Advertisement
Guest User

Untitled

a guest
Aug 24th, 2015
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 58.52 KB | None | 0 0
  1. # Standard Modules
  2. from collections import namedtuple, OrderedDict
  3. import socket
  4. import sys
  5. import os
  6. import os.path
  7. import subprocess
  8. import time
  9. import threading
  10.  
  11.  
  12. # XBMC Modules
  13. import xbmcaddon
  14. import xbmcgui
  15. import xbmc
  16.  
  17. __addon__ = xbmcaddon.Addon('script.module.osmcsetting.networking')
  18. DIALOG = xbmcgui.Dialog()
  19.  
  20.  
  21. # Custom modules
  22. sys.path.append(xbmc.translatePath(os.path.join(__addon__.getAddonInfo('path'), 'resources', 'lib')))
  23.  
  24. import osmc_bluetooth
  25. import osmc_network
  26.  
  27. WIFI_THREAD_NAME = 'wifi_population_thread'
  28. BLUETOOTH_THREAD_NAME = 'bluetooth_population_thread'
  29.  
  30.  
  31. def log(message):
  32.     xbmc.log(str(message), level=xbmc.LOGDEBUG)
  33.  
  34.  
  35. def lang(id):
  36.     san = __addon__.getLocalizedString(id).encode('utf-8', 'ignore')
  37.     return san
  38.  
  39.  
  40. gui_ids = { \
  41.  \
  42.     1000: 'Header Group list',
  43.     101: 'Wired Network',
  44.     102: 'Wireless Network',
  45.     103: 'Bluetooth',
  46.     10111: 'Wired - Manual/ DHCP toggle',
  47.     10112: 'Wired - IP Address',
  48.     910112: 'Wired - IP Address VALUE',
  49.     10113: 'Wired - Subnet Mask',
  50.     910113: 'Wired - Subnet Mask VALUE',
  51.     10114: 'Wired - Default Gateway',
  52.     910114: 'Wired - Default Gateway VALUE',
  53.     10115: 'Wired - Primary DNS',
  54.     910115: 'Wired - Primary DNS VALUE',
  55.     10116: 'Wired - Secondary DNS',
  56.     910116: 'Wired - Secondary DNS VALUE',
  57.     10118: 'Wired - Apply',
  58.     10119: 'Wired - Reset',
  59.     10120: 'Wired - Enable Adapter',
  60.     10121: 'Wired - Toggle wait for network service',
  61.     10211: 'Wireless - Automatically configure the network toggle',
  62.     10212: 'Wireless - IP Address',
  63.     910212: 'Wireless - IP Address VALUE',
  64.     10213: 'Wireless - Subnet Mask',
  65.     910213: 'Wireless - Subnet Mask VALUE',
  66.     10214: 'Wireless - Default Gateway',
  67.     910214: 'Wireless - Default Gateway VALUE',
  68.     10215: 'Wireless - Primary DNS',
  69.     910215: 'Wireless - Primary DNS VALUE',
  70.     10216: 'Wireless - Secondary DNS',
  71.     910216: 'Wireless - Secondary DNS VALUE',
  72.     10217: 'Wireless - Enable Adapter',
  73.     10218: 'Wireless - Apply',
  74.     10219: 'Wireless - Reset',
  75.     10221: 'Wireless - Toggle wait for network service',
  76.     10301: 'Bluetooth - Toggle Bluetooth Adapter',
  77.     10303: 'Bluetooth - Toggle Discovery',
  78.     10401:  'Tethering (wifi) - Hotspot SSID label',
  79.     910401: 'Tethering (Wifi) - Hotspot SSID VALUE',
  80.     10402:  'Tethering (Wifi) - Hotspot passphrase label',
  81.     910402: 'Tethering (Wifi) - Hotspot passphrase VALUE',
  82.     10403:  'Tethering (Wifi) - Enable Button',
  83.     10404:  'Tethering (Wifi) - Disable Button',
  84.     10405:  'Tethering (Ethernet) - Enable Button',
  85.     10406:  'Tethering (Ethernet) - Disable Button',
  86.     5000: 'WiFi panel',
  87.     6000: 'Bluetooth paired devices panel',
  88.     7000: 'Bluetooth discoverd devices panel'
  89.  
  90. }
  91.  
  92. ip_controls = [10112, 10113, 10114, 10115, 10116, 910112, 910113, 910114, 910115, 910116, 10212, 10213, 10214, 10215
  93.     , 10216, 910212, 910213, 910214, 910215, 910216, ]
  94.  
  95. SELECTOR_WIRED_NETWORK = 101
  96. SELECTOR_WIRELESS_NETWORK = 102
  97. SELECTOR_BLUETOOTH = 103
  98. SELECTOR_TETHERING = 104
  99.  
  100. MAIN_MENU = [SELECTOR_WIRED_NETWORK, SELECTOR_WIRELESS_NETWORK, SELECTOR_BLUETOOTH, SELECTOR_TETHERING]
  101.  
  102. BLUETOOTH_CONTROLS = [10303, 6000, 7000]
  103.  
  104. BLUETOOTH_DISCOVERY = 10303
  105. BLUETOOTH_ENABLE_TOGGLE = 10301
  106.  
  107. ALL_WIRED_CONTROLS = [10111, 10112, 10113, 10114, 10115, 10116, 10118, 10119, 910112, 910113, 910114,
  108.                       910115, 910116]
  109. WIRED_STATUS_LABEL = 81000
  110. WIRED_IP_VALUES = [910112, 910113, 910114, 910115, 910116]
  111. WIRED_IP_LABELS = [10112, 10113, 10114, 10115, 10116]
  112. WIRED_APPLY_BUTTON = 10118
  113. WIRED_RESET_BUTTON = 10119
  114. WIRED_DHCP_MANUAL_BUTTON = 10111
  115. WIRED_IP_LABELS = [10112, 10113, 10114, 10115, 10116]
  116. WIRED_ADAPTER_TOGGLE = 10120
  117. WIRED_APPLY_BUTTON = 10118
  118. WIRED_RESET_BUTTON = 10119
  119. WIRED_DHCP_MANUAL_BUTTON = 10111
  120. WIRED_WAIT_FOR_NETWORK = 10121
  121.  
  122. ALL_WIRELESS_CONTROLS = [5000, 910212, 910213, 910214, 910215, 910216, 10211, 10212, 10213, 10214, 10215, 10216,
  123.                          10218, 10219]
  124.  
  125. WIRELESS_STATUS_LABEL = 82000
  126. WIRELESS_IP_VALUES = [910212, 910213, 910214, 910215, 910216]
  127. WIRELESS_IP_LABELS = [10212, 10213, 10214, 10215, 10216]
  128. WIRELESS_ADAPTER_TOGGLE = 10217
  129. WIRELESS_APPLY_BUTTON = 10218
  130. WIRELESS_RESET_BUTTON = 10219
  131. WIRELESS_DHCP_MANUAL_BUTTON = 10211
  132. WIRELESS_NETWORKS = 5000
  133. WIRELESS_WAIT_FOR_NETWORK = 10221
  134.  
  135. ALL_TETHERING_CONTROLS = [10401, 910401, 10402, 910402, 10403, 10404, 10405, 10406, 10407]
  136. TETHERING_WIFI_SSID_LABEL = 10401
  137. TETHERING_WIFI_SSID_VALUE = 910401
  138. TETHERING_WIFI_PASSPHRASE_LABEL = 10402
  139. TETHERING_WIFI_PASSPHRASE_VALUE = 910402
  140. TETHERING_WIFI_RADIOBUTTON = 10403
  141. TETHERING_ETHERNET_RADIOBUTTON = 10404
  142. TETHERING_ENABLE = 10405
  143. TETHERING_DISABLE = 10406
  144. TETHERING_WARNING = 10407
  145.  
  146.  
  147.  
  148.  
  149.  
  150. class networking_gui(xbmcgui.WindowXMLDialog):
  151.     current_network_config = {}  # holds the current network config
  152.  
  153.     reboot_required_file = '/tmp/.reboot-needed'
  154.  
  155.     use_preseed = False
  156.  
  157.     internet_protocol = 'IPV4'
  158.  
  159.  
  160.     def setUsePreseed(self, value):
  161.         self.use_preseed = value
  162.  
  163.     def __init__(self, strXMLname, strFallbackPath, strDefaultName, **kwargs):
  164.         self.setting_values = kwargs.get('setting_values', {})
  165.  
  166.         # this stores the wifi password for sending to connman (or equivalent)
  167.         self.wireless_password = None
  168.  
  169.         # current panel we are on
  170.         self.current_panel = -1
  171.  
  172.         # Wired Network List (of one a way of showing connected icon )
  173.         self.WDP = None
  174.  
  175.         # wifi panel (WFP)
  176.         self.WFP = None
  177.  
  178.         # bluetooth paired device panel (BTP)
  179.         self.BTP = None
  180.  
  181.         # bluetooth discovered device panel (BTD)
  182.         self.BTD = None
  183.  
  184.         # list containing list items of all wifi networks
  185.         self.wifis = []
  186.  
  187.         # connected SSID, the ssid we are currently connected to
  188.         self.conn_ssid = None
  189.  
  190.         # list containing list items of all paired bluetooth devices
  191.         self.paired_bluetooths = []
  192.  
  193.         # list containing list items of all discovered bluetooth devices
  194.         self.discovered_bluetooths = []
  195.  
  196.         # Bluetooth GUI update Thread
  197.         self.bluetooth_population_thread = None
  198.  
  199.         self.preseed_data = None
  200.  
  201.         self.wired_status_label = None
  202.  
  203.         self.wireless_status_label = None
  204.  
  205.         self.hotspot_ssid = None
  206.  
  207.         self.hotspot_passphrase = None
  208.  
  209.     def onInit(self):
  210.         # Wired Network Label
  211.         self.wired_status_label = self.getControl(WIRED_STATUS_LABEL);
  212.  
  213.         # wifi panel (WFP)
  214.         self.WFP = self.getControl(5000)
  215.  
  216.         # Wireless Network Label
  217.         self.wireless_status_label = self.getControl(WIRELESS_STATUS_LABEL);
  218.  
  219.         # bluetooth paired device panel (BTP)
  220.         self.BTP = self.getControl(6000)
  221.  
  222.         # bluetooth discovered device panel (BTD)
  223.         self.BTD = self.getControl(7000)
  224.  
  225.         # Hide panel selectors if devices are not present
  226.         if not osmc_network.is_wifi_available():
  227.             self.toggle_controls(False, [SELECTOR_WIRELESS_NETWORK])
  228.             self.toggle_controls(False, [SELECTOR_TETHERING])
  229.  
  230.         if not osmc_bluetooth.is_bluetooth_available():
  231.             self.toggle_controls(False, [SELECTOR_BLUETOOTH])
  232.  
  233.         panel_to_show = SELECTOR_WIRED_NETWORK
  234.         if self.use_preseed and not osmc_network.get_nfs_ip_cmdline_value():
  235.              self.preseed_data = osmc_network.parse_preseed()
  236.              if self.preseed_data:
  237.                  if self.preseed_data['Interface'].startswith('wlan') and osmc_network.is_wifi_available():
  238.                      panel_to_show = SELECTOR_WIRELESS_NETWORK
  239.                  else:
  240.                      panel_to_show = SELECTOR_WIRED_NETWORK
  241.  
  242.         # set all the panels to invisible except the first one
  243.         for ctl in MAIN_MENU:
  244.             self.getControl(ctl * 10).setVisible(True if ctl == panel_to_show else False)
  245.         if panel_to_show == SELECTOR_WIRED_NETWORK:
  246.             self.populate_wired_panel()
  247.         if panel_to_show == SELECTOR_WIRELESS_NETWORK:
  248.             self.populate_wifi_panel(False)
  249.  
  250.         if self.use_preseed and not osmc_network.get_nfs_ip_cmdline_value():
  251.             self.setup_networking_from_preseed()
  252.  
  253.     def setup_networking_from_preseed(self):
  254.         wired = False
  255.         connected = False
  256.  
  257.         if self.preseed_data['Interface'].startswith('wlan') and osmc_network.is_wifi_available():
  258.             if not osmc_network.is_wifi_enabled():
  259.                 self.toggle_wifi()
  260.             ssid = self.preseed_data['SSID']
  261.             encrypted = False
  262.             preseed_password = None
  263.             if 'Password' in self.preseed_data:
  264.                 encrypted = True
  265.                 preseed_password = self.preseed_data['Password']
  266.  
  267.             connected = self.connect_to_wifi(ssid, encrypted, preseed_password, True)
  268.  
  269.         if self.preseed_data is None or self.preseed_data['Interface'].startswith('eth') or not connected:
  270.             wired = True
  271.             if not osmc_network.is_ethernet_enabled():
  272.                 self.toggle_ethernet()
  273.             self.current_network_config = self.get_wired_config()
  274.             connected = True
  275.  
  276.         if connected:
  277.             if self.preseed_data is None or 'dhcp' in self.preseed_data['Method']:
  278.                 self.current_network_config['IPV4']['Method'] = 'dhcp'
  279.             else:
  280.                 self.current_network_config['IPV4']['Method'] = 'manual'
  281.                 self.current_network_config['IPV4']['Address'] = self.preseed_data['Address']
  282.                 self.current_network_config['IPV4']['Netmask'] = self.preseed_data['Netmask']
  283.                 if self.preseed_data['Gateway']:
  284.                     self.current_network_config['IPV4']['Gateway'] = self.preseed_data['Gateway']
  285.                 if self.preseed_data['DNS_1']:
  286.                     self.current_network_config['IPV4']['DNS_1'] = self.preseed_data['DNS_1']
  287.                 if self.preseed_data['DNS_2']:
  288.                     self.current_network_config['IPV4']['DNS_2'] = self.preseed_data['DNS_2']
  289.  
  290.             osmc_network.apply_network_changes(self.current_network_config, 'IPV4')
  291.  
  292.         if wired:
  293.             self.populate_wired_panel()
  294.         else:
  295.             self.populate_wifi_panel(False)
  296.  
  297.     def onClick(self, controlID):
  298.         if controlID in ip_controls:
  299.             self.edit_ip_address(controlID)
  300.         elif controlID in BLUETOOTH_CONTROLS + [BLUETOOTH_ENABLE_TOGGLE]:
  301.             self.handle_bluetooth_selection(controlID)
  302.             self.populate_bluetooth_panel()
  303.  
  304.         elif controlID in ALL_WIRED_CONTROLS + [WIRED_ADAPTER_TOGGLE]:
  305.             self.handle_wired_selection(controlID)
  306.  
  307.         elif controlID in ALL_WIRELESS_CONTROLS + [WIRELESS_ADAPTER_TOGGLE]:
  308.             self.handle_wireless_selection(controlID)
  309.  
  310.         elif controlID == WIRED_WAIT_FOR_NETWORK:
  311.             osmc_network.toggle_wait_for_network(not osmc_network.is_connman_wait_for_network_enabled())
  312.             waitForNetworkRadioButton = self.getControl(WIRED_WAIT_FOR_NETWORK)
  313.             waitForNetworkRadioButton.setSelected(osmc_network.is_connman_wait_for_network_enabled())
  314.  
  315.         elif controlID == WIRELESS_WAIT_FOR_NETWORK:
  316.             osmc_network.toggle_wait_for_network(not osmc_network.is_connman_wait_for_network_enabled())
  317.             waitForNetworkRadioButton = self.getControl(WIRELESS_WAIT_FOR_NETWORK)
  318.             waitForNetworkRadioButton.setSelected(osmc_network.is_connman_wait_for_network_enabled())
  319.  
  320.         elif controlID in ALL_TETHERING_CONTROLS:
  321.             self.handle_tethering_selection(controlID)
  322.  
  323.     def onAction(self, action):
  324.         actionID = action.getId()
  325.         focused_control = self.getFocusId()
  326.  
  327.         log('actionID = ' + str(actionID))
  328.         log('focused_control = %s,   %s' % (type(focused_control), focused_control))
  329.  
  330.         if actionID in (10, 92):
  331.             self.stop_wifi_population_thread()
  332.             self.stop_bluetooth_population_thread()
  333.             xbmc.sleep(200)
  334.             self.close()
  335.  
  336.         if focused_control in MAIN_MENU:
  337.             if focused_control != self.current_panel:
  338.  
  339.                 self.current_panel = focused_control
  340.                 # stop any running threads on change of panel
  341.                 self.stop_wifi_population_thread()
  342.                 self.stop_bluetooth_population_thread()
  343.  
  344.                 if focused_control == SELECTOR_WIRED_NETWORK:
  345.                     self.populate_wired_panel()
  346.  
  347.                 elif focused_control == SELECTOR_WIRELESS_NETWORK:
  348.                     self.populate_wifi_panel()
  349.  
  350.                 elif focused_control == SELECTOR_BLUETOOTH:
  351.                     self.populate_bluetooth_panel()
  352.  
  353.                 elif focused_control == SELECTOR_TETHERING:
  354.                     self.populate_tethering_panel()
  355.  
  356.             # change to the required settings panel
  357.             for ctl in MAIN_MENU:
  358.                 self.getControl(ctl * 10).setVisible(True if ctl == focused_control else False)
  359.  
  360.         if focused_control in WIRED_IP_LABELS:
  361.             self.update_current_ip_settings(WIRED_IP_VALUES)
  362.             self.update_apply_reset_button('WIRED')
  363.  
  364.         if focused_control in WIRELESS_IP_LABELS:
  365.             self.update_current_ip_settings(WIRELESS_IP_VALUES)
  366.             self.update_apply_reset_button('WIRELESS')
  367.  
  368.     def edit_ip_address(self, controlID):
  369.         relevant_label_control = self.getControl(900000 + controlID)
  370.         current_label = relevant_label_control.getLabel()
  371.  
  372.         if current_label == '___ : ___ : ___ : ___':
  373.             current_label = ''
  374.  
  375.         user_input = DIALOG.input(lang(32004), current_label, type=xbmcgui.INPUT_IPADDRESS)
  376.  
  377.         if not user_input or user_input == '0.0.0.0':
  378.  
  379.             relevant_label_control.setLabel(current_label)
  380.  
  381.         else:
  382.             # validate ip_address format
  383.             try:
  384.                 socket.inet_aton(user_input)
  385.  
  386.             except:
  387.                 'The address provided is not a valid IP address.', 'OSMC Network Setup'
  388.                 ok = DIALOG.ok(lang(32004), lang(32005))
  389.  
  390.                 self.edit_ip_address(controlID)
  391.  
  392.                 return
  393.  
  394.             # ip_string = ' : '.join(str(user_input).split('.'))
  395.             relevant_label_control.setLabel(user_input)
  396.  
  397.             return
  398.  
  399.     def stop_wifi_population_thread(self):
  400.         # call the wifi checking bot to exit, if it exists
  401.         try:
  402.             self.wifi_populate_bot.stop_thread()
  403.         except:
  404.             pass
  405.  
  406.     def stop_bluetooth_population_thread(self):
  407.         try:
  408.             self.bluetooth_population_thread.stop_thread()
  409.         except:
  410.             pass
  411.  
  412.     def show_busy_dialogue(self):
  413.         xbmc.executebuiltin("ActivateWindow(busydialog)")
  414.  
  415.     def clear_busy_dialogue(self):
  416.         xbmc.executebuiltin("Dialog.Close(busydialog)")
  417.  
  418.     def toggle_controls(self, enabled, control_ids):
  419.         for control_id in control_ids:
  420.             control = self.getControl(control_id)
  421.             control.setEnabled(enabled)
  422.             control.setVisible(True)
  423.  
  424.     def hide_controls(self, control_ids):
  425.         for control_id in control_ids:
  426.             control = self.getControl(control_id)
  427.             control.setVisible(False)
  428.  
  429.     def get_wired_config(self):
  430.         return osmc_network.get_ethernet_settings()
  431.  
  432.     def populate_wired_panel(self):
  433.         if os.path.isfile(self.reboot_required_file):
  434.             # 'NFS Network Settings'
  435.             # 'The displayed network configuration may be out dated - A reboot is recommended before proceeding'
  436.             DIALOG.ok(lang(32036), lang(32038))
  437.         # Clear wired network Panel
  438.         self.hide_controls(ALL_WIRED_CONTROLS)
  439.         if osmc_network.is_ethernet_enabled():
  440.             self.current_network_config = self.get_wired_config()
  441.             if self.current_network_config:
  442.                 interface = self.current_network_config['Interface']
  443.                 if self.current_network_config['State'] == 'configuration':
  444.                     status = lang(32044) + ': ' + interface + ' ('+ lang(32076) + ')'
  445.                 else:
  446.                     if osmc_network.has_network_connection(True):
  447.                         # 'Status'                               'Connected'
  448.                         status = lang(32044) + ': ' + interface + ' (' + lang(32046) + ')'
  449.                     else:
  450.                         # 'Status'                               'No internet'
  451.                         status = lang(32044) + ': ' + interface + ' (' + lang(32047) + ')'
  452.                 self.wired_status_label.setLabel(status)
  453.                 if self.current_network_config['State'] == 'configuration':
  454.                     self.current_network_config[self.internet_protocol]['Method'] = 'manual'
  455.                 if self.current_network_config['State'] in ['online', 'ready', 'configuration']:
  456.                     self.toggle_controls(True, ALL_WIRED_CONTROLS)
  457.                     self.update_manual_DHCP_button(WIRED_DHCP_MANUAL_BUTTON, WIRED_IP_VALUES, WIRED_IP_LABELS)
  458.                     self.populate_ip_controls(self.current_network_config, WIRED_IP_VALUES)
  459.  
  460.                     # enable reset and apply button
  461.                     self.update_apply_reset_button('WIRED')
  462.  
  463.             else:  # no wired connection
  464.                 self.hide_controls(WIRED_IP_VALUES + WIRELESS_IP_VALUES)
  465.                 # 'Status'     'no wired connection'
  466.                 status = lang(32044) + ': ' + lang(32049)
  467.                 self.wired_status_label.setLabel(status)
  468.                 self.clear_ip_controls(WIRED_IP_VALUES)
  469.         else:  # Disabled
  470.             self.clear_ip_controls(WIRED_IP_VALUES)
  471.             self.hide_controls(ALL_WIRED_CONTROLS)
  472.             # 'Status'     'disabled'
  473.             status = lang(32044) + ': ' + lang(32048)
  474.             self.wired_status_label.setLabel(status)
  475.             self.update_apply_reset_button('WIRED')
  476.  
  477.         adapterRadioButton = self.getControl(WIRED_ADAPTER_TOGGLE)
  478.         adapterRadioButton.setSelected(osmc_network.is_ethernet_enabled())
  479.         adapterRadioButton.setEnabled(True)
  480.  
  481.         waitForNetworkRadioButton = self.getControl(WIRED_WAIT_FOR_NETWORK)
  482.         waitForNetworkRadioButton.setSelected(osmc_network.is_connman_wait_for_network_enabled())
  483.         waitForNetworkRadioButton.setEnabled(True)
  484.  
  485.     def update_manual_DHCP_button(self, button_id, ip_values, ip_labels):
  486.         manualDHCPButton = self.getControl(button_id)
  487.         if 'dhcp' in self.current_network_config[self.internet_protocol]['Method']:
  488.             # 'Configure Network Manually'
  489.             manualDHCPButton.setLabel(lang(32006))
  490.             # if configuration is by DHCP disable controls
  491.             self.toggle_controls(False, ip_values)
  492.             self.toggle_controls(False, ip_labels)
  493.         else:
  494.             # 'Configure Network Using DHCP'
  495.             manualDHCPButton.setLabel(lang(32033))
  496.             self.toggle_controls(True, ip_values)
  497.             self.toggle_controls(True, ip_labels)
  498.  
  499.     def populate_ip_controls(self, settings_dict, controls):
  500.         ip_address = self.getControl(controls[0])
  501.         ip_address.setLabel(settings_dict[self.internet_protocol]['Address'])
  502.         subnet = self.getControl(controls[1])
  503.         subnet.setLabel(settings_dict[self.internet_protocol]['Netmask'])
  504.         defaultGateway = self.getControl(controls[2])
  505.         if settings_dict[self.internet_protocol].has_key('Gateway'):
  506.             defaultGateway.setLabel(settings_dict[self.internet_protocol]['Gateway'])
  507.         else:
  508.             defaultGateway.setLabel('')
  509.             defaultGateway.setEnabled(False)
  510.         primaryDNS = self.getControl(controls[3])
  511.         if settings_dict['Nameservers']['DNS_1']:
  512.             primaryDNS.setLabel(settings_dict['Nameservers']['DNS_1'])
  513.         else:
  514.             primaryDNS.setLabel('')
  515.         secondaryDNS = self.getControl(controls[4])
  516.         if settings_dict['Nameservers']['DNS_2']:
  517.             secondaryDNS.setLabel(settings_dict['Nameservers']['DNS_2'])
  518.         else:
  519.             secondaryDNS.setLabel('')
  520.  
  521.     def clear_ip_controls(self, controls):
  522.         ip_address = self.getControl(controls[0])
  523.         ip_address.setLabel('')
  524.         subnet = self.getControl(controls[1])
  525.         subnet.setLabel('')
  526.         defaultGateway = self.getControl(controls[2])
  527.         defaultGateway.setLabel('')
  528.         primaryDNS = self.getControl(controls[3])
  529.         primaryDNS.setLabel('')
  530.         secondaryDNS = self.getControl(controls[4])
  531.         secondaryDNS.setLabel('')
  532.         self.toggle_controls(False, controls)
  533.  
  534.     def update_current_ip_settings(self, controls):
  535.         ip_address = self.getControl(controls[0])
  536.         self.current_network_config[self.internet_protocol]['Address'] = ip_address.getLabel()
  537.         subnet = self.getControl(controls[1])
  538.         self.current_network_config[self.internet_protocol]['Netmask'] = subnet.getLabel()
  539.         defaultGateway = self.getControl(controls[2])
  540.         self.current_network_config[self.internet_protocol]['Gateway'] = defaultGateway.getLabel()
  541.         primaryDNS = self.getControl(controls[3])
  542.         self.current_network_config['Nameservers']['DNS_1'] = primaryDNS.getLabel()
  543.         secondaryDNS = self.getControl(controls[4])
  544.         if secondaryDNS.getLabel():
  545.             self.current_network_config['Nameservers']['DNS_2'] = secondaryDNS.getLabel()
  546.  
  547.     def handle_wired_selection(self, control_id):
  548.         if control_id == WIRED_DHCP_MANUAL_BUTTON:
  549.             if self.current_network_config[self.internet_protocol]['Method'] == 'dhcp':
  550.                 self.current_network_config[self.internet_protocol]['Method'] = 'manual'
  551.             elif self.current_network_config[self.internet_protocol]['Method'] == 'nfs_dhcp':
  552.                 self.current_network_config[self.internet_protocol]['Method'] = 'nfs_manual'
  553.             elif self.current_network_config[self.internet_protocol]['Method'] == 'manual':
  554.                 self.current_network_config[self.internet_protocol]['Method'] = 'dhcp'
  555.             elif self.current_network_config[self.internet_protocol]['Method'] == 'nfs_manual':
  556.                 self.current_network_config[self.internet_protocol]['Method'] = 'nfs_dhcp'
  557.             self.update_manual_DHCP_button(WIRED_DHCP_MANUAL_BUTTON, WIRED_IP_VALUES, WIRED_IP_LABELS)
  558.             if 'dhcp' in self.current_network_config[self.internet_protocol]['Method']:
  559.                 self.hide_controls(WIRED_IP_VALUES)
  560.  
  561.         if control_id == WIRED_RESET_BUTTON:
  562.             self.current_network_config = self.get_wired_config()
  563.             self.populate_ip_controls(self.current_network_config, WIRED_IP_VALUES)
  564.             self.update_manual_DHCP_button(WIRED_DHCP_MANUAL_BUTTON, WIRED_IP_VALUES, WIRED_IP_LABELS)
  565.             self.setFocusId(WIRED_DHCP_MANUAL_BUTTON)
  566.  
  567.         if control_id == WIRED_APPLY_BUTTON:
  568.             if self.current_network_config:
  569.                 osmc_network.apply_network_changes(self.current_network_config, self.internet_protocol)
  570.                 if self.current_network_config[self.internet_protocol]['Method'] in ['nfs_dhcp', 'nfs_manual']:
  571.                     with open(self.reboot_required_file, 'w') as f:
  572.                         f.write('d')
  573.                     # 'NFS Network Settings'
  574.                     # 'Your Settings will not take effect until you reboot. Reboot Now?''
  575.                     if DIALOG.yesno(lang(32036), lang(32037)):
  576.                         xbmc.executebuiltin('Reboot')
  577.                 else:
  578.                     self.populate_wired_panel()
  579.                 self.setFocusId(WIRED_DHCP_MANUAL_BUTTON)
  580.  
  581.         if control_id == WIRED_ADAPTER_TOGGLE:
  582.             self.toggle_ethernet()
  583.             self.populate_wired_panel()
  584.  
  585.         self.update_apply_reset_button('WIRED')
  586.  
  587.     def toggle_ethernet(self):
  588.         self.show_busy_dialogue()
  589.         self.hide_controls(ALL_WIRED_CONTROLS)
  590.         # 'Status'              'Configuring...'
  591.         self.wired_status_label.setLabel(lang(32044) + ' : ' + lang(32016))
  592.         osmc_network.toggle_ethernet_state(not osmc_network.is_ethernet_enabled())
  593.         # 5 second wait to allow connman to make the changes before refreshing
  594.         time.sleep(2)
  595.         self.clear_busy_dialogue()
  596.  
  597.     def update_apply_reset_button(self, type):
  598.         if type == 'WIRED':
  599.             if cmp(self.get_wired_config(), self.current_network_config) == 0 or not self.get_wired_config():
  600.                 self.toggle_controls(False, [WIRED_RESET_BUTTON, WIRED_APPLY_BUTTON])
  601.             else:
  602.                 self.toggle_controls(True, [WIRED_RESET_BUTTON, WIRED_APPLY_BUTTON])
  603.         if type == 'WIRELESS':
  604.             wireless_config = self.get_wireless_config(self.conn_ssid)
  605.             if cmp(wireless_config, self.current_network_config) == 0:
  606.                 self.toggle_controls(False, [WIRELESS_RESET_BUTTON, WIRELESS_APPLY_BUTTON])
  607.             else:
  608.                 self.toggle_controls(True, [WIRELESS_RESET_BUTTON, WIRELESS_APPLY_BUTTON])
  609.  
  610.     def get_wireless_config(self, ssid):
  611.         if ssid is not None:
  612.             wifi = None
  613.             for adapterAddress, wifis in osmc_network.get_wifi_networks().iteritems():
  614.                 if ssid in wifis:
  615.                     wifi = wifis[ssid]
  616.             if wifi:
  617.                 config = wifi
  618.                 if self.wireless_password:
  619.                     config['Password'] = self.wireless_password
  620.                 return config
  621.         return {}
  622.  
  623.     def populate_wifi_panel(self, scan=False):
  624.         if osmc_network.is_wifi_available():
  625.             if osmc_network.is_wifi_enabled():
  626.                 # Start the wifi population thread
  627.                 threadRunning = False
  628.                 for t in threading.enumerate():
  629.                     if t.getName() == WIFI_THREAD_NAME:
  630.                         threadRunning = True
  631.                 if not threadRunning:
  632.                     self.wifi_populate_bot = wifi_populate_bot(scan, self.getControl(5000), self.conn_ssid)
  633.                     self.wifi_populate_bot.setDaemon(True)
  634.                     self.wifi_populate_bot.start()
  635.  
  636.                 self.current_network_config = osmc_network.get_connected_wifi()
  637.                 self.conn_ssid = None
  638.                 if 'SSID' in self.current_network_config:
  639.                     self.conn_ssid = self.current_network_config['SSID']
  640.                 if self.conn_ssid:
  641.                     if 'Address' in self.current_network_config[self.internet_protocol]:
  642.                         self.update_manual_DHCP_button(WIRELESS_DHCP_MANUAL_BUTTON, WIRELESS_IP_VALUES, WIRELESS_IP_LABELS)
  643.                         self.populate_ip_controls(self.current_network_config, WIRELESS_IP_VALUES)
  644.                     self.toggle_controls(True, [WIRELESS_ADAPTER_TOGGLE,  WIRELESS_NETWORKS,
  645.                                                 WIRELESS_DHCP_MANUAL_BUTTON])
  646.                     if osmc_network.has_network_connection(True):
  647.                         # 'Status'            'Connected'
  648.                         status = lang(32044) + ': ' + lang(32046)
  649.                     else:
  650.                         # 'Status'            'No internet'
  651.                         status = lang(32044) + ':  ' + lang(32047)
  652.                     self.wireless_status_label.setLabel(status)
  653.                 else:  # not connected to a network
  654.                     self.hide_controls(WIRELESS_IP_VALUES + WIRELESS_IP_LABELS + [WIRELESS_DHCP_MANUAL_BUTTON,
  655.                                                                                   WIRELESS_APPLY_BUTTON,
  656.                                                                                   WIRELESS_RESET_BUTTON])
  657.                     self.toggle_controls(True, [WIRELESS_ADAPTER_TOGGLE, WIRELESS_NETWORKS])
  658.                     self.clear_ip_controls(WIRELESS_IP_VALUES)
  659.                     # 'Status'           'No wireless Connection'
  660.                     status = lang(32044) + ': ' + lang(32050)
  661.                     self.wireless_status_label.setLabel(status)
  662.  
  663.             else:  # Wifi disabled
  664.                 self.hide_controls(ALL_WIRELESS_CONTROLS)
  665.                 # 'Status'            'disabled'
  666.                 status = lang(32044) + ': ' + lang(32048)
  667.                 self.wireless_status_label.setLabel(status)
  668.  
  669.             adapterRadioButton = self.getControl(WIRELESS_ADAPTER_TOGGLE)
  670.             adapterRadioButton.setSelected(osmc_network.is_wifi_enabled())
  671.             adapterRadioButton.setEnabled(True)
  672.  
  673.         else:  # Wifi not available
  674.             self.toggle_controls(False, ALL_WIRELESS_CONTROLS)
  675.  
  676.         waitForNetworkRadioButton = self.getControl(WIRELESS_WAIT_FOR_NETWORK)
  677.         waitForNetworkRadioButton.setSelected(osmc_network.is_connman_wait_for_network_enabled())
  678.         waitForNetworkRadioButton.setEnabled(True)
  679.  
  680.     def handle_wireless_selection(self, control_id):
  681.         if control_id == 5000:  # wireless network
  682.             self.handle_selected_wireless_network()
  683.  
  684.         elif control_id == WIRELESS_DHCP_MANUAL_BUTTON:
  685.             if self.current_network_config[self.internet_protocol]['Method'] == 'dhcp':
  686.                 self.current_network_config[self.internet_protocol]['Method'] = 'manual'
  687.             elif self.current_network_config[self.internet_protocol]['Method'] == 'manual':
  688.                 self.current_network_config[self.internet_protocol]['Method'] = 'dhcp'
  689.                 self.hide_controls(WIRELESS_IP_VALUES)
  690.             self.update_manual_DHCP_button(WIRELESS_DHCP_MANUAL_BUTTON, WIRELESS_IP_VALUES, WIRELESS_IP_LABELS)
  691.             if 'dhcp' in self.current_network_config[self.internet_protocol]['Method']:
  692.                 self.hide_controls(WIRELESS_IP_VALUES)
  693.  
  694.         elif control_id == WIRELESS_RESET_BUTTON:
  695.             self.current_network_config = self.get_wireless_config(self.conn_ssid)
  696.             self.update_manual_DHCP_button(WIRELESS_DHCP_MANUAL_BUTTON, WIRELESS_IP_VALUES, WIRELESS_IP_LABELS)
  697.             self.setFocusId(WIRELESS_DHCP_MANUAL_BUTTON)
  698.  
  699.         elif control_id == WIRELESS_APPLY_BUTTON:
  700.             if self.current_network_config:
  701.                 osmc_network.apply_network_changes(self.current_network_config)
  702.                 self.populate_wifi_panel()
  703.                 self.setFocusId(WIRELESS_DHCP_MANUAL_BUTTON)
  704.  
  705.         elif control_id == WIRELESS_ADAPTER_TOGGLE:
  706.             self.toggle_wifi()
  707.             self.populate_wifi_panel()
  708.  
  709.         self.update_apply_reset_button('WIRELESS')
  710.  
  711.     def toggle_wifi(self):
  712.         self.show_busy_dialogue()
  713.         self.WFP.reset()
  714.         self.hide_controls(ALL_WIRELESS_CONTROLS)
  715.         self.toggle_controls(True, [WIRELESS_NETWORKS])
  716.         wifi_state = not osmc_network.is_wifi_enabled()
  717.         osmc_network.toggle_wifi_state(wifi_state)
  718.         # 5 second wait to allow connman to make the changes before refreshing
  719.         time.sleep(5)
  720.         if not wifi_state:
  721.             self.stop_wifi_population_thread()
  722.             self.current_network_config = {}
  723.         self.clear_busy_dialogue()
  724.  
  725.     def handle_selected_wireless_network(self):
  726.         item = self.WFP.getSelectedItem()
  727.         path = item.getProperty('Path')
  728.         encrypted = item.getProperty('Encrypted') == 'True'
  729.         connected = item.getProperty('Connected')
  730.         ssid = item.getProperty('SSID')
  731.         if connected == 'False':
  732.             if not self.conn_ssid:  # if we are not connected to a network connect
  733.                 if self.connect_to_wifi(ssid, encrypted):
  734.                     if '_hidden_' not in path:
  735.                         strength = self.current_network_config['Strength']
  736.                         icon = wifi_populate_bot.get_wifi_icon(encrypted, strength, True)
  737.                         item.setIconImage(icon)
  738.                         item.setProperty('Connected', 'True')
  739.  
  740.             else:  # Display a toast asking the user to disconnect first
  741.                 # 'Please disconnect from the current network before connecting'
  742.                 message = lang(32053)
  743.                 # 'Wireless'
  744.                 xbmc.executebuiltin("XBMC.Notification(%s,%s,%s)" % (lang(32041), message, "2500"))
  745.  
  746.         else:
  747.             if ssid == self.conn_ssid:
  748.                 #                             'Disconnect from'
  749.                 selection = DIALOG.select(lang(32042) + ' ' + self.conn_ssid + '?',
  750.                                           [lang(32051),lang(32058), lang(32059)])
  751.                 if selection == -1 or selection == 0:
  752.                     return
  753.                 self.show_busy_dialogue()
  754.                 self.conn_ssid = None
  755.                 self.wireless_password = None
  756.                 self.current_network_config = {}
  757.                 self.hide_controls(WIRELESS_IP_VALUES + WIRELESS_IP_LABELS)
  758.                 osmc_network.wifi_disconnect(path)
  759.                 if selection == 2: # we also want to remove/forget this network
  760.                     osmc_network.wifi_remove(path)
  761.                 self.WFP.removeItem(self.WFP.getSelectedPosition())
  762.                 self.toggle_controls(False, [SELECTOR_TETHERING])
  763.                 self.populate_wifi_panel()
  764.                 self.clear_busy_dialogue()
  765.  
  766.     def connect_to_wifi(self, ssid, encrypted, password=None, scan=False):
  767.         if scan:
  768.             self.show_busy_dialogue()
  769.             osmc_network.scan_wifi()
  770.             self.clear_busy_dialogue()
  771.  
  772.         wifi = None
  773.         for adapterAddress, wifis in osmc_network.get_wifi_networks().iteritems():
  774.             if ssid in wifis:
  775.                 wifi = wifis[ssid]
  776.  
  777.         if wifi:
  778.             # 'Configuring'
  779.             self.wireless_status_label.setLabel(lang(32016))
  780.             path = wifi['path']
  781.             connection_status = False
  782.             hiddenssid = None
  783.             connect = False
  784.             if '_hidden_' in path :
  785.                 # 'Enter SSID to connect to this hidden network'
  786.                 hiddenssid = DIALOG.input(lang(32073))
  787.             else:
  788.                 # 'Wireless'   'Connect to'
  789.                 if DIALOG.yesno(lang(32041), lang(32052) + ' ' + ssid + '?'):
  790.                     connect = True
  791.             if connect or hiddenssid:
  792.                 self.show_busy_dialogue()
  793.                 # try without a password see if connman has the password
  794.                 script_base_path = os.path.join(__addon__.getAddonInfo('path'), 'resources', 'lib') + '/'
  795.                 connection_status = osmc_network.wifi_connect(path, None, hiddenssid, script_base_path)
  796.                 self.clear_busy_dialogue()
  797.                 if not connection_status and encrypted:
  798.                     if password is None:
  799.                         password = DIALOG.input(lang(32013), type=xbmcgui.INPUT_ALPHANUM,
  800.                                             option=xbmcgui.ALPHANUM_HIDE_INPUT)
  801.                     if password:
  802.                         self.wireless_password = password
  803.                         self.show_busy_dialogue()
  804.                         connection_status = osmc_network.wifi_connect(path, password, hiddenssid, script_base_path)
  805.                         self.clear_busy_dialogue()
  806.                 if not connection_status:
  807.                     # 'Connection to '                  'failed'
  808.                     message = lang(32043) + ' ' + ssid + ' ' + lang(32025)
  809.                     #                                                   'Wireless'
  810.                     xbmc.executebuiltin("XBMC.Notification(%s,%s,%s)" % (lang(32041), message, "2500"))
  811.                     self.current_network_config = {}
  812.                     self.clear_ip_controls(WIRELESS_IP_VALUES)
  813.                     self.toggle_controls(False, [WIRELESS_DHCP_MANUAL_BUTTON])
  814.                     #         'Status'           'Not connected'
  815.                     status = lang(32044) + ': ' + lang(32050)
  816.                     self.wireless_status_label.setLabel(status)
  817.                     self.clear_busy_dialogue()
  818.                     return False
  819.                 else:
  820.                     self.show_busy_dialogue()
  821.                     self.current_network_config = osmc_network.get_connected_wifi()
  822.                     self.update_manual_DHCP_button(WIRELESS_DHCP_MANUAL_BUTTON, WIRELESS_IP_VALUES, WIRELESS_IP_LABELS)
  823.                     self.populate_ip_controls(self.current_network_config, WIRELESS_IP_VALUES)
  824.                     self.toggle_controls(True, [WIRELESS_ADAPTER_TOGGLE, WIRELESS_NETWORKS,
  825.                                                 WIRELESS_DHCP_MANUAL_BUTTON])
  826.                     self.conn_ssid = self.current_network_config['SSID']
  827.                     interface = self.current_network_config['Interface']
  828.                     if osmc_network.has_network_connection(True):
  829.                         # 'Status'                               'Connected'
  830.                         status = lang(32044) + ': ' + interface + ' (' + lang(32046) + ')'
  831.                     else:
  832.                         # 'Status'                               'No internet'
  833.                         status = lang(32044) + ': ' + interface + ' (' + lang(32047) + ')'
  834.                     self.wireless_status_label.setLabel(status)
  835.                     self.toggle_controls(True, [SELECTOR_TETHERING])
  836.                     self.clear_busy_dialogue()
  837.                     return True
  838.         else:
  839.             return False
  840.  
  841.     def sort_strength(self, itm):
  842.         try:
  843.             metric = int(itm.getProperty('strength'))
  844.             if itm.getProperty('Connected') == 'True':
  845.                 # make sure the connected network is always at the top
  846.                 metric += 100
  847.         except:
  848.             metric = 0
  849.         return metric
  850.  
  851.     def populate_bluetooth_panel(self):
  852.         bluetoothRadioButton = self.getControl(BLUETOOTH_ENABLE_TOGGLE)
  853.         bluetooth_enabled = osmc_bluetooth.is_bluetooth_enabled()
  854.         bluetoothRadioButton.setSelected(bluetooth_enabled)
  855.  
  856.         # disable all if bluetooth is not enabled
  857.         if not bluetooth_enabled:
  858.             # disable all controls
  859.             self.toggle_controls(False, BLUETOOTH_CONTROLS)
  860.             return
  861.  
  862.         self.toggle_controls(True, BLUETOOTH_CONTROLS)
  863.         discoveryRadioButton = self.getControl(BLUETOOTH_DISCOVERY)
  864.         discoveryRadioButton.setSelected(osmc_bluetooth.is_discovering())
  865.         # Start Bluetooth Population Thread
  866.         threadRunning = False
  867.         for t in threading.enumerate():
  868.             if t.getName() == BLUETOOTH_THREAD_NAME:
  869.                 threadRunning = True
  870.         if not threadRunning:
  871.             self.bluetooth_population_thread = bluetooth_population_thread(self.BTD, self.BTP)
  872.             self.bluetooth_population_thread.setDaemon(True)
  873.             self.bluetooth_population_thread.start()
  874.  
  875.     def handle_bluetooth_selection(self, control_id):
  876.         if control_id == BLUETOOTH_ENABLE_TOGGLE:  # Enable Bluetooth
  877.             self.show_busy_dialogue()
  878.             if osmc_bluetooth.is_bluetooth_enabled():
  879.                 osmc_bluetooth.toggle_bluetooth_state(False)
  880.                 self.stop_bluetooth_population_thread()
  881.             else:
  882.                 osmc_bluetooth.toggle_bluetooth_state(True)
  883.             self.clear_busy_dialogue()
  884.  
  885.         if control_id == BLUETOOTH_DISCOVERY:  # Discovery
  886.             self.show_busy_dialogue()
  887.             if not osmc_bluetooth.is_discovering():
  888.                 osmc_bluetooth.start_discovery()
  889.             else:
  890.                 osmc_bluetooth.stop_discovery()
  891.             xbmc.sleep(1500)
  892.             self.clear_busy_dialogue()
  893.  
  894.  
  895.         if control_id == 6000:  # paired devices
  896.             item = self.BTP.getSelectedItem()
  897.             if item:
  898.                 address = item.getProperty('address')
  899.                 alias = item.getProperty('alias')
  900.                 connected = item.getProperty('connected') == 'True'
  901.                 #                                'Cancel'     'Re-connect'  'Remove Device'
  902.                 selection = DIALOG.select(alias, [lang(32051), lang(32075), lang(32021)])
  903.                 if selection == -1 or selection == 0:
  904.                     return
  905.  
  906.                 if selection == 1: # Reconnect
  907.                     if not connected:
  908.                         self.show_busy_dialogue()
  909.                         if self.connect_bluetooth(address, alias):
  910.                             self.bluetooth_population_thread.update_bluetooth_lists()
  911.                         self.clear_busy_dialogue()
  912.  
  913.                 if selection == 2:
  914.                     osmc_bluetooth.remove_device(address)
  915.                     self.setFocusId(BLUETOOTH_ENABLE_TOGGLE)
  916.                     self.bluetooth_population_thread.update_bluetooth_lists()
  917.  
  918.         if control_id == 7000:  # Discovered devices
  919.             item = self.BTD.getSelectedItem()
  920.             if item:
  921.                 address = item.getProperty('address')
  922.                 alias = item.getProperty('alias')
  923.                 #              'Connect With Device'                        'No'        'Pair and Connect' 'pair'
  924.                 selection = DIALOG.select(lang(32022) + ' ' + alias + '?', [lang(32055),lang(32056), lang(32057)])
  925.                 if selection == -1 or selection == 0:
  926.                     return
  927.                 self.show_busy_dialogue()
  928.                 self.setFocusId(BLUETOOTH_DISCOVERY)
  929.                 if selection == 1:
  930.                     script_base_path = os.path.join(__addon__.getAddonInfo('path'), 'resources', 'lib') + '/'
  931.                     result = osmc_bluetooth.pair_device(address, script_base_path)
  932.  
  933.                     if not result:
  934.                         #         'Connection to '                       'failed'
  935.                         message = lang(32024) + ' ' + alias + ' ' + lang(32025)
  936.                         #                                                     'Bluetooth'
  937.                         xbmc.executebuiltin("XBMC.Notification(%s,%s,%s)" % (lang(32020), message, "2500"))
  938.                         self.clear_busy_dialogue()
  939.                         return
  940.                 if self.connect_bluetooth(address, alias):
  941.                     osmc_bluetooth.set_device_trusted(address, True)
  942.                     self.bluetooth_population_thread.update_bluetooth_lists()
  943.                 self.clear_busy_dialogue()
  944.  
  945.     def connect_bluetooth(self, address, alias):
  946.         connected = osmc_bluetooth.connect_device(address)
  947.         if not connected:
  948.              #         'Connection to'                       'failed'
  949.             message = lang(32024) + ' ' + alias + ' ' + lang(32025)
  950.             #                                                     'Bluetooth'
  951.             xbmc.executebuiltin("XBMC.Notification(%s,%s,%s)" % (lang(32020), message, "2500"))
  952.         return connected
  953.  
  954.     def populate_tethering_panel(self):
  955.         wifi_tethering = osmc_network.is_tethering_wifi()
  956.         ethernet_tethering = osmc_network.is_tethering_ethernet()
  957.         self.toggle_controls(True, ALL_TETHERING_CONTROLS)
  958.         if wifi_tethering:
  959.             self.handle_tethering_selection(TETHERING_WIFI_RADIOBUTTON)
  960.         if ethernet_tethering:
  961.             self.handle_tethering_selection(TETHERING_ETHERNET_RADIOBUTTON)
  962.         if not wifi_tethering and not ethernet_tethering:
  963.             self.handle_tethering_selection(TETHERING_WIFI_RADIOBUTTON)
  964.  
  965.         # disable controls if tethering is active
  966.         if wifi_tethering or ethernet_tethering:
  967.             self.toggle_controls(False, [TETHERING_WIFI_SSID_LABEL,TETHERING_WIFI_SSID_VALUE, TETHERING_WIFI_PASSPHRASE_LABEL,
  968.                                          TETHERING_WIFI_PASSPHRASE_VALUE, TETHERING_ENABLE, TETHERING_WIFI_RADIOBUTTON,
  969.                                          TETHERING_ETHERNET_RADIOBUTTON])
  970.         else:
  971.             self.toggle_controls(False, [TETHERING_DISABLE])
  972.  
  973.         wifiSSIDLabel = self.getControl(TETHERING_WIFI_SSID_VALUE)
  974.         self.hotspot_ssid  = osmc_network.get_tethering_SSID();
  975.         if not self.hotspot_ssid:
  976.             self.hotspot_ssid = 'osmc_wifi';
  977.         wifiSSIDLabel.setLabel(self.hotspot_ssid)
  978.         self.hotspot_passphrase = osmc_network.get_tethering_passphrase();
  979.         if not self.hotspot_passphrase:
  980.             self.hotspot_passphrase = 'h0tsp0t0smc'
  981.         control_label = ' '.join([self.hotspot_passphrase[i: i + 33] for i in
  982.                                   xrange(0, len(self.hotspot_passphrase), 33)])
  983.         wifiPassphaseLabel = self.getControl(TETHERING_WIFI_PASSPHRASE_VALUE)
  984.         wifiPassphaseLabel.setLabel(control_label)
  985.  
  986.     def handle_tethering_selection(self, control_id):
  987.         if control_id in [TETHERING_WIFI_RADIOBUTTON, TETHERING_ETHERNET_RADIOBUTTON]:
  988.             wifi_radiobutton = self.getControl(TETHERING_WIFI_RADIOBUTTON)
  989.             ethernet_radiobutton = self.getControl(TETHERING_ETHERNET_RADIOBUTTON)
  990.             wifi_radiobutton.setSelected(False)
  991.             ethernet_radiobutton.setSelected(False)
  992.             if control_id == TETHERING_WIFI_RADIOBUTTON:
  993.                 self.hide_controls([TETHERING_WARNING])
  994.                 wifi_radiobutton.setSelected(True)
  995.                 ethernet_radiobutton.setSelected(False)
  996.                 self.toggle_controls(True, [TETHERING_WIFI_SSID_LABEL,TETHERING_WIFI_SSID_VALUE,
  997.                                             TETHERING_WIFI_PASSPHRASE_LABEL, TETHERING_WIFI_PASSPHRASE_VALUE])
  998.             else:
  999.                 self.toggle_controls(True, [TETHERING_WARNING])
  1000.                 wifi_radiobutton.setSelected(False)
  1001.                 ethernet_radiobutton.setSelected(True)
  1002.                 self.toggle_controls(False, [TETHERING_WIFI_SSID_LABEL,TETHERING_WIFI_SSID_VALUE,
  1003.                                             TETHERING_WIFI_PASSPHRASE_LABEL, TETHERING_WIFI_PASSPHRASE_VALUE])
  1004.  
  1005.         if control_id == TETHERING_WIFI_SSID_LABEL:
  1006.             wifiSSIDLabel = self.getControl(TETHERING_WIFI_SSID_VALUE)
  1007.             enteredSSID = DIALOG.input(lang(32068), self.hotspot_ssid)
  1008.             if enteredSSID:
  1009.                 self.hotspot_ssid = enteredSSID
  1010.                 wifiSSIDLabel.setLabel(enteredSSID)
  1011.  
  1012.         if control_id == TETHERING_WIFI_PASSPHRASE_LABEL:
  1013.             wifiPassphraseLabel = self.getControl(TETHERING_WIFI_PASSPHRASE_VALUE)
  1014.             currentPassphrase =self.hotspot_passphrase
  1015.             enteredPassphrase = DIALOG.input(lang(32069), currentPassphrase)
  1016.             if enteredPassphrase:
  1017.                 self.hotspot_passphrase = enteredPassphrase
  1018.                 control_label = ' '.join([self.hotspot_passphrase[i: i + 33] for i in
  1019.                                   xrange(0, len(self.hotspot_passphrase), 33)])
  1020.                 wifiPassphraseLabel.setLabel(control_label)
  1021.  
  1022.         if control_id == TETHERING_ENABLE:
  1023.             wifi_radiobutton = self.getControl(TETHERING_WIFI_RADIOBUTTON)
  1024.             technology = None
  1025.             ssid = None
  1026.             passphrase = None
  1027.             if wifi_radiobutton.isSelected():
  1028.                 technology = 'wifi'
  1029.                 ssid = self.hotspot_ssid
  1030.                 if len(ssid) == 0:
  1031.                     # 'Portable Hotspot'
  1032.                     # 'SSID must be set to enable WiFi Tethering'
  1033.                     DIALOG.ok(lang(32063), lang(32070))
  1034.                     return
  1035.                 passphrase = self.hotspot_passphrase
  1036.                 if len(passphrase) > 63:
  1037.                     # 'Portable Hotspot'
  1038.                     # 'Passphrase must be 63 characters or less"'
  1039.                     DIALOG.ok(lang(32063), lang(32074))
  1040.                     return
  1041.                 if len(passphrase) < 8:
  1042.                     # 'Portable Hotspot'
  1043.                     # 'Passphrase must at least 8 characters long'
  1044.                     DIALOG.ok(lang(32063), lang(32071))
  1045.                     return
  1046.             else:
  1047.                 technology = 'ethernet'
  1048.  
  1049.             log('Enabling '+ technology +' Hotspot')
  1050.             if technology is 'wifi':
  1051.                 log('Hotspot ssid = ' + ssid)
  1052.  
  1053.             if osmc_network.tethering_enable(technology, ssid, passphrase):
  1054.                 self.setFocusId(TETHERING_DISABLE)
  1055.                 self.toggle_controls(False, [TETHERING_WIFI_SSID_LABEL,TETHERING_WIFI_SSID_VALUE, TETHERING_WIFI_PASSPHRASE_LABEL,
  1056.                                          TETHERING_WIFI_PASSPHRASE_VALUE, TETHERING_ENABLE, TETHERING_WIFI_RADIOBUTTON,
  1057.                                          TETHERING_ETHERNET_RADIOBUTTON, TETHERING_ENABLE])
  1058.                 self.toggle_controls(True, [TETHERING_DISABLE])
  1059.             else:
  1060.                 # 'Portable Hotspot'
  1061.                 # 'Error enabling hotspot - see log for details'
  1062.                 DIALOG.ok(lang(32063), lang(32072))
  1063.  
  1064.         if control_id == TETHERING_DISABLE:
  1065.             log('Disabling Hotspot')
  1066.             osmc_network.tethering_disable()
  1067.             self.setFocusId(SELECTOR_TETHERING)
  1068.             self.toggle_controls(True, [TETHERING_WIFI_SSID_LABEL,TETHERING_WIFI_SSID_VALUE, TETHERING_WIFI_PASSPHRASE_LABEL,
  1069.                                      TETHERING_WIFI_PASSPHRASE_VALUE, TETHERING_ENABLE, TETHERING_WIFI_RADIOBUTTON,
  1070.                                      TETHERING_ETHERNET_RADIOBUTTON, TETHERING_ENABLE])
  1071.             self.toggle_controls(False, [TETHERING_DISABLE])
  1072.  
  1073.  
  1074. class bluetooth_population_thread(threading.Thread):
  1075.     def __init__(self, discovered_list_control, trusted_list_control):
  1076.         super(bluetooth_population_thread, self).__init__(name=BLUETOOTH_THREAD_NAME)
  1077.         self.exit = False
  1078.         self.discovered_list_control = discovered_list_control
  1079.         self.trusted_list_control = trusted_list_control
  1080.         self.trusted_dict = {}
  1081.         self.discovered_dict = {}
  1082.  
  1083.     def run(self):
  1084.         runs = 0
  1085.         while not self.exit:
  1086.             # update gui every 2 seconds
  1087.             if runs % 200 == 0 and not self.exit:
  1088.                 self.update_bluetooth_lists()
  1089.             # every 4 seconds output debug info
  1090.             if runs % 400 == 0 and not self.exit:
  1091.                 log('-- DISCOVERED ---')
  1092.                 log(self.discovered_dict)
  1093.                 log('-- TRUSTED --')
  1094.                 log(self.trusted_dict)
  1095.  
  1096.             xbmc.sleep(10)
  1097.             runs += 1
  1098.  
  1099.     def update_bluetooth_lists(self):
  1100.         self.trusted_dict = self.populate_bluetooth_dict(True)
  1101.         self.discovered_dict = self.populate_bluetooth_dict(False)
  1102.         self.update_list_control(dict(self.discovered_dict), self.discovered_list_control)
  1103.         self.update_list_control(dict(self.trusted_dict), self.trusted_list_control)
  1104.  
  1105.     def stop_thread(self):
  1106.         self.exit = True
  1107.  
  1108.     def update_list_control(self, devices_dict, list_control):
  1109.         items_to_be_removed = []
  1110.         for itemIndex in range(0, list_control.size()):
  1111.             listItem = list_control.getListItem(itemIndex)
  1112.             address = listItem.getProperty('address')
  1113.             if address in devices_dict.keys():
  1114.                 connected = listItem.getProperty('connected') == 'True'
  1115.                 # connected status differs
  1116.                 if not connected == devices_dict[address]['connected']:
  1117.                     log('Connected status differs')
  1118.                     items_to_be_removed.append(itemIndex)
  1119.                 else:
  1120.                     devices_dict.pop(address)
  1121.             else:
  1122.                 items_to_be_removed.append(itemIndex)
  1123.  
  1124.         for itemIndex in items_to_be_removed:
  1125.             try:
  1126.                 list_control.removeItem(itemIndex)
  1127.             except:
  1128.                 pass
  1129.  
  1130.         if len(devices_dict.keys()) > 0:
  1131.             for address, info in devices_dict.iteritems():
  1132.                 list_control.addItem(self.create_bluetooth_item(address, info))
  1133.  
  1134.     def create_bluetooth_item(self, address, info):
  1135.         label = address
  1136.         if info['alias']:
  1137.             label = info['alias']
  1138.         item = xbmcgui.ListItem(label)
  1139.         icon_image = 'disconnected.png'
  1140.         if info['connected']:
  1141.             icon_image = 'connected.png'
  1142.         item.setIconImage(icon_image)
  1143.         item.setProperty('address', address)
  1144.         item.setProperty('alias', info['alias'])
  1145.         item.setProperty('connected', str(info['connected']))
  1146.         return item
  1147.  
  1148.     def populate_bluetooth_dict(self, paired):
  1149.         devices = {}
  1150.         if paired:
  1151.             devices = osmc_bluetooth.list_trusted_devices()
  1152.         else:
  1153.             devices = osmc_bluetooth.list_discovered_devices()
  1154.         bluetooth_dict = {}
  1155.         for address in devices.keys():
  1156.             alias = str(osmc_bluetooth.get_device_property(address, 'Alias'))
  1157.             paired = osmc_bluetooth.get_device_property(address, 'Paired')
  1158.             connected = osmc_bluetooth.get_device_property(address, 'Connected')
  1159.             trusted = osmc_bluetooth.get_device_property(address, 'Trusted')
  1160.             bluetooth_dict[address] = {'alias': alias, 'paired': paired,
  1161.                                        'connected': connected, 'trusted': trusted}
  1162.         return bluetooth_dict
  1163.  
  1164.     def sort_alias(self, itm):
  1165.         try:
  1166.             metric = int(itm.getProperty('alias'))
  1167.         except:
  1168.             metric = 0
  1169.  
  1170.         return metric
  1171.  
  1172.  
  1173. class wifi_scanner_bot(threading.Thread):
  1174.     def __init__(self):
  1175.         super(wifi_scanner_bot, self).__init__()
  1176.  
  1177.     def run(self):
  1178.         osmc_network.scan_wifi()
  1179.  
  1180.  
  1181. class wifi_populate_bot(threading.Thread):
  1182.     def __init__(self, scan, wifi_list_control, conn_ssid):
  1183.  
  1184.         super(wifi_populate_bot, self).__init__(name=WIFI_THREAD_NAME)
  1185.  
  1186.         self.WFP = wifi_list_control
  1187.         self.scan = scan
  1188.         self.exit = False
  1189.         self.conn_ssid = conn_ssid
  1190.         self.wifis = []
  1191.         self.current_network_config = None
  1192.  
  1193.         if self.scan:
  1194.             self.wifi_scanner_bot = wifi_scanner_bot()
  1195.             self.wifi_scanner_bot.setDaemon(True)
  1196.             self.wifi_scanner_bot.start()
  1197.  
  1198.     def run(self):
  1199.         running_dict = {}
  1200.         runs = 0
  1201.         while not self.exit:
  1202.             # only run the network check every 2 seconds, but allow the exit command to be checked every 10ms
  1203.             if runs % 200 == 0 and not self.exit:
  1204.                 log('Updating Wifi networks')
  1205.                 wifis = osmc_network.get_wifi_networks()
  1206.  
  1207.                 running_dict.update(wifis)
  1208.  
  1209.                 self.update_list_control(running_dict, len(wifis.keys()) > 1)
  1210.  
  1211.                 # find any connected setting and load its values into the controls
  1212.                 for adapterAddress, wifis in running_dict.iteritems():
  1213.                     for ssid, info in wifis.iteritems():
  1214.                         try:
  1215.                             if info['Connected'] == 'True':
  1216.                                 self.current_network_config = self.get_wireless_config(ssid)
  1217.                                 self.populate_ip_controls(info, WIRELESS_IP_VALUES)
  1218.                         except:
  1219.                             pass
  1220.              # every minute re-scan wifi unless the thread has been asked to exit
  1221.             if not self.exit and runs % 600 == 0:
  1222.                 self.wifi_scanner_bot = wifi_scanner_bot()
  1223.                 self.wifi_scanner_bot.setDaemon(True)
  1224.                 self.wifi_scanner_bot.start()
  1225.             xbmc.sleep(10)
  1226.             runs += 1
  1227.  
  1228.     def stop_thread(self):
  1229.         self.exit = True
  1230.  
  1231.     def update_list_control(self, running_dict, multiAdpter):
  1232.         items_to_be_removed = []
  1233.         for itemIndex in range(0, self.WFP.size()):
  1234.             listItem = self.WFP.getListItem(itemIndex)
  1235.             listItemAdapterAddress = listItem.getProperty('AdapterAddress')
  1236.             listItemSSID = listItem.getProperty('SSID')
  1237.             listItemConnected = True if listItem.getProperty('Connected') in 'True' else False
  1238.             if listItemAdapterAddress in running_dict.keys():
  1239.                     if listItemSSID in running_dict[listItemAdapterAddress].keys():
  1240.                         wifi = running_dict[listItemAdapterAddress][listItemSSID]
  1241.                         networkConnected = True if wifi['State']in ('ready', 'online') else False
  1242.                         expectedLabel = self.getListItemLabel(wifi, multiAdpter);
  1243.                         if listItem.getLabel() == expectedLabel and listItemConnected == networkConnected:
  1244.                             running_dict[listItemAdapterAddress].pop(listItemSSID)
  1245.                         else:
  1246.                             items_to_be_removed.append(itemIndex)
  1247.                     else:
  1248.                         items_to_be_removed.append(itemIndex)
  1249.             else:
  1250.                 items_to_be_removed.append(itemIndex)
  1251.  
  1252.         for itemIndex in reversed(items_to_be_removed):
  1253.             self.WFP.removeItem(itemIndex)
  1254.  
  1255.         if len(running_dict.keys()) > 0:
  1256.             for adapterAddress, wifis in running_dict.iteritems():
  1257.                 for ssid, info in wifis.iteritems():
  1258.                     self.WFP.addItem(self.convert_wifi_to_listitem(info, multiAdpter))
  1259.                     connected = True if info['State'] in ('ready', 'online') else False
  1260.                     if connected and ssid == self.conn_ssid:
  1261.                         self.WFP.selectItem(self.WFP.size() - 1)
  1262.  
  1263.     def getListItemLabel(self, wifi, multiAdapter):
  1264.         ssid = wifi['SSID']
  1265.         interface = wifi['Interface']
  1266.         if multiAdapter:
  1267.             return ssid + ' (' + interface + ')'
  1268.         else:
  1269.             return ssid
  1270.  
  1271.     def convert_wifi_to_listitem(self, wifi, multiAdapter):
  1272.  
  1273.         # {'path': str(path),
  1274.         # 'SSID': str(dbus_properties['Name']),
  1275.         # 'Strength': int(dbus_properties['Strength']),
  1276.         # 'State' : str(dbus_properties['State'])}
  1277.  
  1278.         ssid = wifi['SSID']
  1279.         strength = wifi['Strength']
  1280.         state = wifi['State']
  1281.         path = wifi['path']
  1282.         encrypted = True if wifi['Security'] != 'none' else False
  1283.         connected = True if wifi['State'] in ('ready', 'online') else False
  1284.         address = wifi['AdapterAddress']
  1285.  
  1286.         # icon_tuple = (connected, encrypted, strength)
  1287.         icon_image = self.get_wifi_icon(encrypted, strength, connected)
  1288.  
  1289.         item = xbmcgui.ListItem(self.getListItemLabel(wifi, multiAdapter))
  1290.         item.setIconImage(icon_image)
  1291.         item.setProperty('Strength', str(strength))
  1292.         item.setProperty('Encrypted', str(encrypted))
  1293.         item.setProperty('Path', path)
  1294.         item.setProperty('Connected', str(connected))
  1295.         item.setProperty('SSID', ssid)
  1296.         item.setProperty('AdapterAddress', address)
  1297.  
  1298.         if connected:
  1299.             self.conn_ssid = ssid
  1300.  
  1301.         return item
  1302.  
  1303.     @staticmethod
  1304.     def get_wifi_icon(encrypted, strength, connected):
  1305.         filename = ''
  1306.         if connected:
  1307.             filename += 'c'
  1308.         else:
  1309.             filename += 'nc'
  1310.         if encrypted:
  1311.             filename += 'e'
  1312.         else:
  1313.             filename += 'ne'
  1314.         if strength >= 0 and strength <= 40:
  1315.             filename += '020'
  1316.         if strength >= 41 and strength <= 60:
  1317.             filename += '6080'
  1318.         if strength >= 61 and strength <= 100:
  1319.             filename += '80100'
  1320.  
  1321.         filename += ".png"
  1322.         return filename
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement