Beispiel #1
0
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)
Beispiel #2
0
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'])
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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')
Beispiel #8
0
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
Beispiel #9
0
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)