def configure_wifi(wifi_id, payload): """Configure wireless network. See the API documentation for expected configuration payload schema. :param string wifi_id: wifi id :param dict payload: configuration payload :return: tuple """ available = bool(uci_get(RADIO_UCI[wifi_id])) if not available: raise APIError(message='Device not found', status_code=422) config = payload.get('configuration', {}) v = Validator(config) v.ensure_exists('mode', 'ssid') v.ensure_inclusion('mode', [MODE_AP, MODE_STA]) v.ensure_inclusion('encryption', ['none', 'psk', 'psk2', 'wep', 'wpa'], required=False) if config.get('encryption') != 'none': v.ensure_exists('key') v.ensure_passes_test('channel', validate_channel, required=False) v.ensure_inclusion('hidden', ['0', '1'], required=False) v.ensure_inclusion('hwmode', ['11a', '11b', '11g'], required=False) if v.is_valid: apply_wifi_configuration(config) return (200, 'OK') else: return (422, v.errors)
def apply_wifi_configuration(config): """Applies wireless configuration to UCI. Also reloads wireless. :param dict config: :return: None """ if uci_get('mwan3.wwan.enabled') != '1': LOG.warn('Enabling wwan interface') uci_set('mwan3.wwan.enabled', '1') uci_commit('mwan3') base_bridge_path = 'wireless.wifibridge.{}' base_radio_path = 'wireless.radio1.{}' mode = config['mode'] if mode == MODE_STA: config['hidden'] = '1' for k,v in config.iteritems(): if v: uci_path = ( base_radio_path.format(k) if k in RADIO_CONFIGS else base_bridge_path.format(k) ) LOG.warn('configuring wireless [%s] | [%s]', uci_path, v) uci_set(uci_path, v) uci_commit('wireless') LOG.warn('Reloading Network') run_command(['wifi', 'reload'])
def connect_sim(sim_id, pin='', puk='', apn='', username='', password=''): """Attempts to establish a connect to the with this SIM """ previous_sim = uci_get('brck.active_sim') errors = {} sim_id = int(sim_id[-1]) m1, m2 = get_modems() modem = 0 if m1: modem = 1 elif m2: modem = 2 if modem: LOG.warn('Saving SIM STATE') set_sim_state(sim_id, pin=pin, puk=puk, apn=apn, username=username, password=password, active=True) eventlet.call_after_global(1, connect_sim_actual, sim_id, modem, previous_sim) else: errors['network'] = 'no modem found' return errors
def get_ethernet_networks(net_id=None): """Gets the connection status for the provided network or all networks. The output response schema is described in the API documentation under ethernet connections. :return: dict """ networks = [net_id] if (net_id is not None) else NETWORKS networks_info = [] for net in networks: interface = CONNECTION_MAP.get(net, None) if interface is None: raise APIError(status_code=404, errors=[dict(network="not found")]) uci_path = 'network.{}'.format(interface) uci_state = get_uci_state(uci_path) connected = uci_state.get( 'network.{}.connected'.format(interface)) == '1' available = uci_state.get('network.{}.up'.format(interface)) == '1' dhcp_enabled = uci_state.get( 'network.{}.proto'.format(interface)) == 'dhcp' network_device = uci_state.get('network.{}.ifname'.format(interface)) net_data = dict(id=net, name=CONNECTION_NAMES[net], available=available, connected=connected) net_info = {} all_addr_info = psutil.net_if_addrs() interface_info = all_addr_info.get(network_device, None) if interface_info: ipv4 = filter(lambda s: s.family == socket.AF_INET, interface_info) if len(ipv4) == 1: net_info.update( dict(ipaddr=ipv4[0].address, netmask=ipv4[0].netmask)) # get uci dns/routing configuration net_info['dns'] = uci_get('network.{}.dns'.format(interface)) or '' net_info['gateway'] = uci_get( 'network.{}.gateway'.format(interface)) or '' ip_info = dict(dhcp_enabled=dhcp_enabled, network=net_info) net_data['info'] = ip_info networks_info.append(net_data) return networks_info
def get_power_config(**kwargs): """Gets the current power configuraition of the device """ configured = False mode = uci_get('brck.power.mode') if mode != False: configured = True else: mode = None config = dict(configured=configured, mode=mode) soc_settings = get_soc_settings(**kwargs) config.update(soc_settings) return config
def get_device_mode(): """Returns the device mode May be one of - MATATU - ALWAYS_ON - RETAIL - SOLAR_POWERED - UNKNOWN :return: str """ mode = STATE_UNKNOWN resp = uci_get('brck.soc.mode') if resp and len(mode): return mode return mode
def set_sim_state(sim_id, pin=None, puk=None, apn=None, username=None, password=None, active=False): assert sim_id in [1, 2, 3] _params = dict(pin=pin, puk=puk, apn=apn, username=username, password=password, active=int(active)) change_count = 0 state_path = 'brck.sim%d' % sim_id if not uci_get(state_path): LOG.debug("Initializing SIM section in uci: %s", state_path) uci_set(state_path, 'sims') uci_commit(state_path) for name, value in _params.iteritems(): if value: _path = 'brck.sim%d.%s' % (sim_id, name) LOG.debug("Setting UCI value: %s | %r", _path, value) uci_set(_path, str(value)) change_count += 1 # configure active_sim if active: uci_set('brck.active_sim', str(sim_id)) if apn: uci_set('network.wan.apn', apn) change_count += 1 if username: uci_set('network.wan.username', username) change_count += 1 if password: uci_set('network.wan.password', password) change_count += 1 change_count += 1 if change_count > 0: uci_commit('brck') uci_commit('network.wan')
def get_wan_connections(sim_id=None): """Returns list of SIM connections Sample Reponse: [ { "id": "SIM1", "name": "SIM 1", "connection_type": "SIM", "connection_available": true, "connected": true, "info": { "pin_locked": true, "puk_locked": false, "apn_configured": true, "network_info": { "operator": "Operator Name", "imei": 350089999084990, "cell_id": 300300, "lac": 300, "mnc": 304, "mcc": 639, "network_type": "2G" } } } ] :return: list(dict) """ conns = [] conn_paths = SIM_STATUS_FILES if sim_id is not None: sim_id_num = int(sim_id[-1]) if sim_id_num in [1, 2, 3]: conn_paths = [SIM_STATUS_FILES[sim_id_num - 1]] net_connected = get_connection_status() active_sim = uci_get('brck.active_sim') sim_statuses = [read_file(p) for p in conn_paths] # when only one SIM is available - assume that's the active SIM active_sims = len([s for s in sim_statuses if s == '1']) for (i, sim_status) in enumerate(sim_statuses): key = i + 1 c_id = 'SIM%d' %(key) name = 'SIM %d' % (key) available = False connected = False if sim_status != False and sim_status == '1': available = True info = {} if available: sim_state = get_sim_state(key) info['apn_configured'] = sim_state.get('apn', '') != '' is_active_sim = (active_sims == 1 and net_connected) or (str(key) == active_sim) if is_active_sim and (not net_connected): sim_status = run_command(['querymodem', 'check_pin'], output=True) or '' if REG_PIN_LOCK.match(sim_status): info['pin_locked'] = True else: info['pin_locked'] = False if REG_PUK_LOCK.match(sim_status): info['puk_locked'] = True else: info['puk_locked'] = False elif is_active_sim: info['pin_locked'] = False info['puk_locked'] = False if net_connected: ex_net_info = {} connected = True signal_strength = get_signal_strength('wan') operator = run_command(['querymodem', 'carrier'], output=True) imei = run_command(['querymodem', 'imei'], output=True) imsi = run_command(['querymodem', 'imsi'], output=True) if REG_ERROR.match(operator) or operator == "0": operator = 'Unknown' connected = False else: ex_net_info['imei'] = imei ex_net_info['imsi'] = imsi ex_net_info['mcc'] = imsi[:3] ex_net_info.update(get_modem_network_info(imsi, imei)) ex_net_info.update(dict( operator=operator, signal_strength=signal_strength )) info['network_info'] = ex_net_info c_data = dict( id=c_id, name=name, available=available, connected=connected, info=info ) conns.append(c_data) return conns
def connect_sim_actual(sim_id, modem_id, previous_sim): """Connects to the selected SIM in interactive fashion. This method pushes all events to a websocket topic for consumption. :param int sim_id: SIM ID (1 or 2 or 3) :param int modem_Id: Modem ID (1 or 2) """ from local_api import socketio as io, NS_SIM_CONNECTIVITY as ns try: if is_service_running(THREEG_MONITOR_SERVICE): LOG.warn("Stopping 3g-monitor") disable_service(THREEG_MONITOR_SERVICE) stop_service(THREEG_MONITOR_SERVICE) emit_event(io, DISABLE_3G_MONITOR, ns) else: LOG.warn("3g-monitor is already stopped") flags = SIM_FLAGS.get('%d-%d' % (modem_id, sim_id)) if flags: LOG.warn("Bringing down WAN") run_command(['ifdown', 'wan']) emit_event(io, STOP_WAN, ns) emit_event(io, SELECT_SIM, ns) for (key, flag) in enumerate(flags): port_path = SIM_CONFIG_PATHS[key] run_call(port_path, flag) for modem_flag_path in MODEM_FLAG_PATHS: run_call(modem_flag_path, '0') eventlet.sleep(1) run_call(modem_flag_path, '1') eventlet.sleep(5) emit_event(io, CHECK_SIM, ns) check_imei_status = run_command(['querymodem', 'imei'], output=True) LOG.warn("SIM|IMEI STATUS|%s", check_imei_status) requires_input = False if not REG_ERROR.match(check_imei_status): emit_event(io, SIM_DETECTED, ns) emit_event(io, CHECK_PIN, ns) pin_status = run_command(['querymodem', 'check_pin'], output=True) if not pin_status: eventlet.sleep(2) pin_status = run_command(['querymodem', 'check_pin'], output=True) LOG.warn("SIM|PIN STATUS|%s", pin_status) puk_path = 'brck.sim{}.puk'.format(sim_id) pin_path = 'brck.sim{}.pin'.format(sim_id) ready = False if REG_PUK.match(pin_status): puk = uci_get(puk_path) pin = uci_get(pin_path) if puk: emit_event(io, SET_PUK, ns) pin = pin or DEFAULT_PIN set_puk_status = run_command([ 'querymodem', 'run', 'AT+CPIN={},{}'.format( puk, pin) ], output=True) LOG.warn("SIM|SET PUK STATUS|%s", set_puk_status) if REG_OK.match(set_puk_status): emit_event(io, DISABLE_PIN, ns) disable_pin(pin) eventlet.sleep(3) emit_event(io, PUK_OK, ns) emit_event(io, CHECK_READY, ns) eventlet.sleep(5) check_sim_ready_status = run_command( ['querymodem', 'check_pin'], output=True) if REG_READY.match(check_sim_ready_status): emit_event(io, SIM_READY, ns) ready = True else: emit_event(io, DELETE_PUK, ns) uci_delete(puk_path) uci_commit('brck') emit_event(io, SIM_NOT_READY, ns) else: emit_event(io, PUK_REJECTED, ns) emit_event(io, DELETE_PUK, ns) uci_delete(puk_path) uci_commit('brck') emit_event(io, REQUIRES_PUK, ns) requires_input = True else: emit_event(io, REQUIRES_PUK, ns) requires_input = True elif REG_PIN.match(pin_status): pin = uci_get(pin_path) if pin: emit_event(io, SET_PIN, ns) set_pin_status = run_command( ['querymodem', 'run', 'AT+CPIN={}'.format(pin)], output=True) LOG.warn("SIM|SET PIN STATUS|%s", set_pin_status) eventlet.sleep(5) sim_status = run_command(['querymodem', 'check_pin'], output=True) if REG_OK.match(set_pin_status) or REG_READY.match( sim_status): emit_event(io, PIN_OK, ns) emit_event(io, DISABLE_PIN, ns) disable_pin(pin) emit_event(io, CHECK_READY, ns) eventlet.sleep(5) check_sim_ready_status = run_command( ['querymodem', 'check_pin'], output=True) if REG_READY.match(check_sim_ready_status): emit_event(io, SIM_READY, ns) ready = True else: emit_event(io, DELETE_PIN, ns) uci_delete(pin_path) uci_commit('brck') emit_event(io, SIM_NOT_READY, ns) else: emit_event(io, PIN_REJECTED, ns) emit_event(io, DELETE_PIN, ns) uci_delete(pin_path) uci_commit('brck') emit_event(io, REQUIRES_PIN, ns) requires_input = True else: emit_event(io, REQUIRES_PIN, ns) requires_input = True elif REG_READY.match(pin_status): emit_event(io, PIN_NOT_REQUIRED, ns) ready = True else: emit_event(io, SIM_NOT_READY, ns) restore_sim(previous_sim) emit_event(io, ACTIVE_SIM_RESET, ns) if ready: if uci_get('network.wan.apn'): emit_event(io, WAIT_CARRIER, ns) eventlet.sleep(10) emit_event(io, CHECK_CARRIER, ns) carrier_resp = run_command(['querymodem', 'carrier'], output=True) LOG.warn("SIM|CHECK CARRIER STATUS|%s", carrier_resp) if REG_ERROR.match( carrier_resp) or carrier_resp == "0": emit_event(io, NO_CARRIER, ns) # emit_event(io, RESTART_MODEM, ns) # restart_modem() # eventlet.sleep(10) else: emit_event(io, CARRIER_DETECTED, ns) emit_event(io, START_WAN, ns) LOG.warn("Bringing up WAN") run_command(['ifup', 'wan']) emit_event(io, WAIT_CONNECTION, ns) _connected = False for _ in xrange(6): _connected = get_connection_status() if _connected: emit_event(io, CONNECTED, ns) break else: eventlet.sleep(10) if not _connected: emit_event(io, NO_CONNECTION, ns) else: emit_event(io, REQUIRES_APN, ns) requires_input = True else: emit_event(io, SIM_NOT_READY, ns) else: LOG.error('No such modem configuration exists: SIM: %d MODEM: %d', sim_id, modem_id) emit_event(io, NO_MODEM, ns) if not requires_input: LOG.warn("Bringing up WAN") run_command(['ifup', 'wan']) emit_event(io, ENABLE_3G_MONITOR, ns) LOG.warn('Enabling 3G Monitor') enable_service(THREEG_MONITOR_SERVICE) start_service(THREEG_MONITOR_SERVICE) except Exception as e: restore_sim(previous_sim) LOG.error("Failed to connect with SIM CARD|%d|%r", sim_id, e) emit_event(io, ACTIVE_SIM_RESET, ns) restore_sim(previous_sim) emit_event(io, NO_CONNECTION, ns) run_command(['ifup', 'wan']) emit_event(io, ENABLE_3G_MONITOR, ns) LOG.warn('Enabling 3G Monitor') enable_service(THREEG_MONITOR_SERVICE) start_service(THREEG_MONITOR_SERVICE)