def setup_dnsmasq(): if get_dnsmasq_setup_status(): return print("Installing Dnsmasq...") os.system('apt-get -yq install dnsmasq') print("... done!") print("Setting up dnsmasq config...") interface = env.var("ONEIOT_C_NETWORK_INTERFACE") static_ip = env.var("ONEIOT_C_STATIC_IP") static_ip_split = static_ip.split(".") dnsmasq = Parsers.DNSMasqParser("/etc/dnsmasq.conf") dnsmasq.set_options( { 'interface': interface, 'server': '8.8.8.8', 'dhcp-range': f'{static_ip_split[0]}.{static_ip_split[1]}.{static_ip_split[2]}.2,{static_ip_split[0]}.{static_ip_split[1]}.{static_ip_split[2]}.254,255.255.255.0,24h', }, ['bind-interfaces', 'domain-needed', 'bogus-priv']) dnsmasq.save() print(".. done!")
def get_dnsmasq_setup_status(): interface = env.var("ONEIOT_C_NETWORK_INTERFACE") static_ip = env.var("ONEIOT_C_STATIC_IP") static_ip_split = static_ip.split(".") if not path.exists("/etc/dnsmasq.conf"): return False dnsmasq = Parsers.DNSMasqParser("/etc/dnsmasq.conf") result = 'interface' in dnsmasq.option_dict result = result and 'server' in dnsmasq.option_dict result = result and 'dhcp-range' in dnsmasq.option_dict if not result: return result result = dnsmasq.option_dict['interface'] == interface result = result and dnsmasq.option_dict['server'] == '8.8.8.8' result = result and dnsmasq.option_dict[ 'dhcp-range'] == f'{static_ip_split[0]}.{static_ip_split[1]}.{static_ip_split[2]}.2,{static_ip_split[0]}.{static_ip_split[1]}.{static_ip_split[2]}.254,255.255.255.0,24h' result = result and 'bind-interfaces' in dnsmasq.option_list result = result and 'domain-needed' in dnsmasq.option_list result = result and 'bogus-priv' in dnsmasq.option_list return result
def setup_hostapd(): if get_hostapd_setup_status(): print(get_hostapd_setup_status()) return print("Installing Hostapd...") os.system('apt-get -yq install hostapd') print("... done!") print("Setting up hostapd config...") interface = env.var("ONEIOT_C_NETWORK_INTERFACE") ssid = env.var("ONEIOT_C_NETWORK_SSID") psk = prompt.query( 'Network Password (8-63 alphanumeric chars)', validators=[ validators.RegexValidator( regex=r"([a-z]|[0-9]){8,63}", message="Password must be 8 to 63 alphanumeric characters") ]) if not path.exists("/etc/hostapd"): os.mkdir("/etc/hostapd") hostapd = Parsers.HostAPDParser("/etc/hostapd/hostapd.conf", "/etc/default/hostapd") hostapd.set_options({ 'interface': interface, 'driver': 'nl80211', 'ssid': ssid, 'hw_mode': 'g', 'channel': '6', 'ieee80211n': '1', 'wmm_enabled': '1', 'ht_capab': '[HT40][SHORT-GI-20][DSSS_CCK-40]', 'macaddr_acl': '0', 'auth_algs': '1', 'ignore_broadcast_ssid': '0', 'wpa': '2', 'wpa_key_mgmt': 'WPA-PSK', 'wpa_passphrase': psk, 'rsn_pairwise': 'CCMP' }) hostapd.save() hostapd.set_master_options({ 'DAEMON_CONF': '"/etc/hostapd/hostapd.conf"', }) hostapd.save_master() os.system('systemctl unmask hostapd') os.system('update-rc.d hostapd enable') print(".. done!")
def setup_static_ip(): if get_static_ip_set_up_status(): return print("Setting up DHCPCD config...") dhcpcd = Parsers.DHCPDParser("/etc/dhcpcd.conf") interface = env.var("ONEIOT_C_NETWORK_INTERFACE") static_ip = env.var("ONEIOT_C_STATIC_IP") dhcpcd.modifyInterface(interface, [['static', f'ip_address={static_ip}/24'], ['nohook', 'wpa_supplicant']]) dhcpcd.save() print(".. done!")
def get_static_ip_respected_status(): interface = env.var("ONEIOT_C_NETWORK_INTERFACE") ifconfig = netifaces.ifaddresses(interface) if netifaces.AF_INET in ifconfig: if len(ifconfig[netifaces.AF_INET]) > 0: return ifconfig[netifaces.AF_INET][0]['addr'] == env.var( "ONEIOT_C_STATIC_IP") else: return False else: return False
def get_static_ip_set_up_status(): dhcpcd = Parsers.DHCPDParser("/etc/dhcpcd.conf") interface = env.var("ONEIOT_C_NETWORK_INTERFACE") static_ip = env.var("ONEIOT_C_STATIC_IP") if interface in dhcpcd.interfaces: static_present = False nohook_present = False for option in dhcpcd.interfaces[interface]: if option[0] == "static": static_present = option[1] == f"ip_address={static_ip}/24" if option[0] == "nohook": nohook_present = option[1] == f"wpa_supplicant" return static_present and nohook_present else: return False
def main(): HOST, PORT = "localhost", int(env.var("ONEIOT_C_PORT", 1102)) server = ThreadedTCPServer((HOST, PORT), service) try: server.serve_forever() except Exception as e: server.shutdown()
def get_hostapd_setup_status(): interface = env.var("ONEIOT_C_NETWORK_INTERFACE") ssid = env.var("ONEIOT_C_NETWORK_SSID") if not path.exists("/etc/hostapd/hostapd.conf"): return False if not path.exists("/etc/default/hostapd"): return False hostapd = Parsers.HostAPDParser("/etc/hostapd/hostapd.conf", "/etc/default/hostapd") options = hostapd.options print(options) print(ssid) result = options['interface'] == interface result = result and options['driver'] == 'nl80211' result = result and options['ssid'] == ssid result = result and options['hw_mode'] == 'g' result = result and options['channel'] == '6' result = result and options['ieee80211n'] == '1' result = result and options['wmm_enabled'] == '1' result = result and options[ 'ht_capab'] == '[HT40][SHORT-GI-20][DSSS_CCK-40]' result = result and options['macaddr_acl'] == '0' result = result and options['auth_algs'] == '1' result = result and options['ignore_broadcast_ssid'] == '0' result = result and options['wpa'] == '2' result = result and options['wpa_key_mgmt'] == 'WPA-PSK' result = result and options['wpa_passphrase'] == env.network_password() result = result and len(env.network_password()) >= 8 result = result and len(env.network_password()) <= 63 result = result and options['rsn_pairwise'] == 'CCMP' options_master = hostapd.options_master if 'DAEMON_CONF' not in options_master: return False result = result and options_master[ 'DAEMON_CONF'] == '"/etc/hostapd/hostapd.conf"' return result
def get_interface_selected_status(): interfaces = netifaces.interfaces() return env.var("ONEIOT_C_NETWORK_INTERFACE") in interfaces
def addDevice(id, data, eb): stage = id.split('.')[-1] token = id.split('.')[-2] if token not in addDeviceRequests: return requestData = addDeviceRequests[token] if stage == 'unplug_device': requestData['ports'] = [ x.name for x in serial.tools.list_ports.comports() ] eb.send(f'device_manager.add_device.{token}.log', { 'type': 'info', 'message': f'Found COM ports: {requestData["ports"]}' }) eb.send(f'device_manager.add_device.{token}.confirm', {'next_step': steps[2]}) if stage == 'plug_in_device': success = False newPorts = [x.name for x in serial.tools.list_ports.comports()] portsDiff = list(set(newPorts) - set(requestData['ports'])) if len(portsDiff) == 0: eb.send( f'device_manager.add_device.{token}.log', { 'type': 'error', 'message': f'Could not find device. Resetting to step 1' }) eb.send(f'device_manager.add_device.{token}.confirm', {'next_step': steps[1]}) elif len(portsDiff) > 1: eb.send( f'device_manager.add_device.{token}.log', { 'type': 'error', 'message': f'Other devices have been plugged in alongside target device. Resetting to step 1' }) eb.send(f'device_manager.add_device.{token}.confirm', {'next_step': steps[1]}) else: requestData['port'] = portsDiff[0] eb.send( f'device_manager.add_device.{token}.log', { 'type': 'info', 'message': f'Found device on {requestData["port"]}' }) # Flash Device try: # Connect logToEB(eb, f'device_manager.add_device.{token}.log', 'info', f'Connecting to device on {requestData["port"]}...') conn = serial.Serial('/dev/' + requestData['port'], 115200, timeout=1) logToEB(eb, f'device_manager.add_device.{token}.log', 'info', f'Connected') # Setup WebRepl config file logToEB(eb, f'device_manager.add_device.{token}.log', 'info', f'Setting up WebREPL config file') passw = uuid.uuid1().hex requestData['webREPLPasswd'] = passw conn.writelines([ str.encode( 'webreplConf = open("webrepl_cfg.py", "wb")\r\n') ]) conn.writelines( [str.encode(f'webreplConf.write("PASS=\'{passw}\'")\r\n')]) conn.writelines([str.encode('webreplConf.close()\r\n')]) # Setup boot file logToEB(eb, f'device_manager.add_device.{token}.log', 'info', f'Setting up boot.py') ssid = env.var('ONEIOT_C_NETWORK_SSID') passw = env.network_password() conn.writelines( [str.encode('boot = open("boot.py", "wb")\r\n')]) conn.writelines( [str.encode('boot.write("import network\\n")\r\n')]) conn.writelines([ str.encode( 'boot.write("wlan=network.WLAN(network.STA_IF)\\n")\r\n' ) ]) conn.writelines( [str.encode('boot.write("wlan.active(True)\\n")\r\n')]) conn.writelines([ str.encode( f'boot.write("wlan.connect(\'{ssid}\', \'{passw}\')\\n")\r\n' ) ]) #conn.writelines([str.encode('boot.write("wlan.ifconfig((\'' + device.ip + '\',\'255.255.255.0\',\'192.168.4.1\',\'8.8.8.8\'))\\n")\r\n')]) conn.writelines( [str.encode('boot.write("import webrepl\\n")\r\n')]) conn.writelines( [str.encode('boot.write("webrepl.start()\\n")\r\n')]) conn.writelines([str.encode('boot.close()\r\n')]) # Reset logToEB(eb, f'device_manager.add_device.{token}.log', 'info', f'Resetting device on {requestData["port"]}') conn.writelines([str.encode('import machine\r\n')]) conn.writelines([str.encode('machine.reset()\r\n')]) success = True except Exception as err: logToEB(eb, f'device_manager.add_device.{token}.log', 'error', str(err)) finally: # Close Serial Connection logToEB(eb, f'device_manager.add_device.{token}.log', 'info', f'Closing connection on {requestData["port"]}...') conn.close() logToEB(eb, f'device_manager.add_device.{token}.log', 'info', f'Closed') if success: eb.send(f'device_manager.add_device.{token}.confirm', {'next_step': steps[3]}) if stage == "naming": if not path.exists(f'{path.expanduser("~")}/.oneIot/devices'): os.mkdir(f'{path.expanduser("~")}/.oneIot/devices') if 'id' not in data: logToEB(eb, f'device_manager.add_device.{token}.log', 'error', 'Device ID not provided') eb.send(f'device_manager.add_device.{token}.confirm', {'next_step': steps[3]}) elif not re.match("^[a-z_-]*$", data['id']): logToEB( eb, f'device_manager.add_device.{token}.log', 'error', f'Device ID can only contain a-z (lowercase), dashes and underscores.' ) eb.send(f'device_manager.add_device.{token}.confirm', {'next_step': steps[3]}) elif path.exists( f'{path.expanduser("~")}/.oneIot/devices/{data["id"]}.json'): logToEB(eb, f'device_manager.add_device.{token}.log', 'error', f'Device ID "{data["id"]}" already taken') eb.send(f'device_manager.add_device.{token}.confirm', {'next_step': steps[3]}) else: with open( f'{path.expanduser("~")}/.oneIot/devices/{data["id"]}.json', 'w') as deviceFile: json.dump( { 'id': data["id"], 'webprel_password': requestData['webREPLPasswd'] }, deviceFile) eb.send(f'device_manager.add_device.{token}.complete') del addDeviceRequests[token]