Example #1
0
def get_diagnostics_data():
    """Gets diagnostics data on the SupaBRCK
    
    Includes:
    
    - temperature information
    - connected clients information
    
    :return: dict
    """
    status = {}
    client_data = run_command(['connected_clients'], output=True) or '{}'
    try:
        _data = json.loads(client_data)
        status['clients'] = _data.get('clients', [])
    except ValueError as exc:
        LOG.error('Failed to load connected_clients: %r', exc)
    modem_temp = run_command(['querymodem', 'temp'], output=True)
    try:
        status['modem'] = dict(temperature=[float(modem_temp)])
    except (ValueError, TypeError) as e:
        LOG.error('Failed to get modem temperature: %r', e)
        status['modem'] = dict(temperature=[STATE_UNKNOWN])
    bat_temp = get_battery_temperature()
    # cpu temperatures
    sensors_temp = psutil.sensors_temperatures() or {}
    cpu_temps = [t.current for t in sensors_temp.get('coretemp', [])]
    status['cpu'] = dict(temperature=cpu_temps)
    status['battery'] = dict(temperature=[bat_temp])
    return status
Example #2
0
def get_software():
    """Gets the versions of the installed software on the system.
    
    This includes packages, firmware and operating system versions.

        See the REST API documentation for payload schema.

    :return: dict
    """
    os_version = run_command(['uname', '-s', '-r', '-v', '-o'],
                             output=True) or STATE_UNKNOWN
    firmware_version = get_firmware_version()
    packages_text = run_command(['opkg', 'list-installed'], output=True) or ''
    package_data = dict(
        [p.split(' - ') for p in packages_text.splitlines() if p])
    # we're only interested in a subset of packages
    package_list = []
    for package_name in BRCK_PACKAGES:
        version = package_data.get(package_name)
        installed = version is not None
        package_list.append(
            dict(name=package_name, version=version, installed=installed))
    return dict(os=os_version,
                firmware=firmware_version,
                packages=package_list)
Example #3
0
def restart_modem():
    """Restarts the current modem
    """
    LOG.warn("Restarting modem")
    s0 = run_command(['querymodem', 'run', 'AT+CFUN=4'])
    s1 = run_command(['querymodem', 'run', 'AT+CFUN=6'])
    LOG.warn("Restart modem status|%r|%r", s0, s1)
Example #4
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'])
Example #5
0
def get_battery_status(no_cache=False):
    """Gets the battery status of the BRCK device.

        Sample Response:
        {
            'state': 'CHARGING',
            'battery_level': 98
        }

    :return: dict
    """
    if no_cache:
        run_command(['check_battery'])
    state = read_file('/tmp/battery/status') or STATE_UNKNOWN
    battery_level = read_file('/tmp/battery/capacity') or 0
    extended = read_file('/tmp/battery/status_ex') or '{}'
    try:
        battery_level = int(battery_level)
        extended = json.loads(extended)
    except ValueError:
        battery_level = 0
        LOG.error('Failed to ready battery capacity | Returned: %s',
                  battery_level)
    state = dict(state=state.upper(), battery_level=battery_level)
    state.update(extended)
    if 'charging current' in state:
        state['charging_current'] = state['charging current']
        state.pop('charging current')
    if 'iadp' in state:
        state.pop('iadp')
    return state
Example #6
0
def get_uci_state(option, command='show', as_dict=True):
    """Gets the uci state stored at `option`

    :param str option: the name of the uci option
    :param str command: the command to run on state (`show` or `get`)
    :param bool expand_options: whether the response should be expanded
    :return: dict|string
    """
    cmd_list = ['uci', '-P']
    cmd_list.append('/var/state')

    cmd_list.append(command)
    cmd_list.append(option)

    response = run_command(cmd_list, output=True) or ''
    if response is False:
        LOG.warn("No UCI state found at: %s", option)
        return {} if as_dict else False
    out = response
    if as_dict:
        out = dict()
        if not (response is False) and len(response):
            out.update(
                [l.replace("'", "").split('=') for l in response.splitlines()])
    return out
Example #7
0
def get_connection_status():
    """Gets the connection status via 3g-wan interface

    :return bool:
    """
    command = ['ping', '-c', '2', '-I', '3g-wan', '-W', '1', '8.8.8.8']
    return run_command(command)
Example #8
0
def get_modem_network_info(*args):
    """Gets network information.
    """
    net_info = {}
    try:
        info_str = run_command(['querymodem', 'run', 'AT+XCELLINFO?'], output=True)
        if not info_str:
            info_str = run_command(['querymodem', 'run', 'AT+XCELLINFO?'], output=True)
        LOG.debug("XCELL_INFO INFO: %r", info_str)
        cell_data = info_str.split(',')
        _mode, cell_type, _mcc, mnc, lac, cell_id = cell_data[:6]
        net_info = dict(
            mnc=mnc,
            lac=int('0x{}'.format(lac), 16),
            cell_id=int('0x{}'.format(cell_id), 16),
            net_type=MOBILE_TECH_MAP.get(cell_type, 'Unknown')
        )
    except Exception as e:
        LOG.error("Failed to load modem network information: %r", e)
    return net_info
Example #9
0
def get_network_status():
    """Gets the network state of the BRCK

    This is a summarized view of the connection state of the BRCK

    Sample Response:
            {
            "connected": true,
            "connection": {
            "connection_type": "WAN",
            "up_speed": 1000000,
            "down_speed": 1000000,
            "signal_strengh": 77
            },
            "connected_clients": 0
            }

    :return: dict
    """
    num_clients = 0
    connected = False
    net_type = STATE_NO_CONNECTION
    chilli_list = run_command(['connected_clients', 'list'], output=True)
    if chilli_list:
        num_clients = (chilli_list.splitlines().__len__() - 1)
    net_order = get_uci_state('brck.network.order',
                              command='get',
                              as_dict=False)
    active_net = None
    if net_order:
        nets = [n.strip() for n in net_order.split(' ')]
        net_state = get_uci_state('network')
        for net in nets:
            conn_state = net_state.get('network.{}.connected'.format(net),
                                       '') == '1'
            if conn_state:
                active_net = net
                net_type = net.upper()
                if net in ['wan', 'wan2']:
                    net_type = net_state.get('network.{}.proto'.format(net),
                                             STATE_UNKNOWN).upper()
                elif net == 'wwan':
                    net_type = 'Wireless'
                break

    up, down = get_interface_speed(active_net)
    state = dict(connected=connected,
                 connected_clients=num_clients,
                 connection=dict(
                     connection_type=net_type,
                     up_speed=up,
                     down_speed=down,
                     signal_strength=get_signal_strength(net_type)))
    return state
Example #10
0
def configure_ip(net_id, dhcp_enabled, net_info):
    """Configures ethernet IP configuration.

    Reloads the network.
    """
    interface = CONNECTION_MAP.get(net_id)
    if dhcp_enabled:
        LOG.warn('Configuring interface [%s] proto to DHCP', interface)
        uci_set('network.{}.proto'.format(interface), 'dhcp')
        for static_key in ['ipaddr', 'netmask', 'gateway', 'dns']:
            uci_option = 'network.{}.{}'.format(interface, static_key)
            LOG.warn('Deleting UCI option:[%s]', uci_option)
            uci_delete(uci_option)
    else:
        net_info['proto'] = 'static'
        for k, v in net_info.iteritems():
            if v:
                uci_option = 'network.{}.{}'.format(interface, k)
                LOG.warn('Configuring network: [%s = %s]', uci_option, v)
                uci_set(uci_option, v)
    uci_commit('network.{}'.format(interface))
    run_command(['iptables', '--flush'])
    run_command(['/etc/init.d/network', 'reload'])
    run_command(['iptables', '--flush'])
    LOG.warn(
        'Sleeping for five (5) seconds to see if interface connection comes up.'
    )
    time.sleep(NETWORK_CONFIG_WAIT_TIME)
    return (200, 'OK')
Example #11
0
def get_signal_strength(net_type):
    """Get wireless signal strength (Mobile)

    :return: int (percentage 0-100)
    """
    if net_type == 'wan':
        signal_strength = 0
        model_id = run_command(['querymodem', 'model_id'], output=True)
        resp = run_command(['querymodem', 'signal'], output=True)
        try:
            rssi = int(resp or '')
            if model_id == 'MU736' or not model_id:
                if (rssi >= 0 and rssi <= 31):
                    signal_strength = (rssi * 827 + 127) >> 8
            else:
                signal_strength = 0 if (rssi == 255) else rssi
        except ValueError:
            LOG.error(
                "Failed to load signal strength: QueryModem Response: %s",
                resp)
    else:
        signal_strength = 100
    return signal_strength
Example #12
0
def get_modems():
    """Gets active modem set
    :return: (bool, bool)
    """
    m1 = False
    m2 = False
    _path = '/sys/class/tty'
    _paths_str = run_command(['ls', '-l', _path], output=True)
    _paths = _paths_str.splitlines()
    matches1 = [p for p in _paths if MODEM1_PATTERN.match(p)]
    matches2 = [p for p in _paths if MODEM2_PATTERN.match(p)]
    if len(matches1) == 4:
        m1 = True
    if len(matches2) == 4:
        m2 = True
    return (m1, m2)
Example #13
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
Example #14
0
def start_service(name):
    run_command(['/etc/init.d/{}'.format(name), 'start'])
Example #15
0
def disable_pin(pin):
    """Disable PIN
    """
    s0 = run_command(['querymodem', 'run', "AT+CLCK=SC,0,{}".format(pin)])
    LOG.warn("Disable PIN status|%r", s0)
Example #16
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)
Example #17
0
def disable_service(name):
    run_command(['/etc/init.d/{}'.format(name), 'disable'])