Beispiel #1
0
        mqtt_client.on_connect = on_connect
        mqtt_client.on_message = on_message
        mqtt_client.on_publish = on_publish
        mqtt_client.on_subscribe = on_subscribe

        # Set a Will to be sent by the broker in case the client disconnects unexpectedly.
        # QOS 2: The broker will deliver the message exactly once by using a four step handshake.
        mqtt_client.will_set('/will/oops',
                             payload='{} has vanished!'.format(
                                 settings.MQTT_CLIENT_ID),
                             qos=2)

        connack_code = mqtt_client.connect(settings.MQTT_SERVER,
                                           settings.MQTT_PORT)
        cp.log('MQTT connect reply to {}, {}: {}'.format(
            settings.MQTT_SERVER, settings.MQTT_PORT,
            mqtt.connack_string(connack_code)))
        # Blocking call that processes network traffic, dispatches callbacks and
        # handles reconnecting.
        mqtt_client.loop_forever()

    except Exception as ex:
        cp.log('Exception in start_mqtt()! exception: {}'.format(ex))
        raise


cp.log('Starting...')
mqtt_thread = Thread(target=start_mqtt, args=())
mqtt_thread.start()
publish_thread()
Beispiel #2
0
        if result and result.get('status') in ["error", "done"]:
            break
        time.sleep(2)
        try_count += 1
    if try_count == 15:
        pingstats['error'] = "No Results - Execution Timed Out"
    else:
        # Parse results text
        parsedresults = result.get('result').split('\n')
        i = 0
        index = 1
        for item in parsedresults:
            if item[0:3] == "---": index = i + 1
            i += 1
        pingstats['tx'] = int(parsedresults[index].split(' ')[0])
        pingstats['rx'] = int(parsedresults[index].split(' ')[3])
        pingstats['loss'] = float(
            parsedresults[index].split(' ')[6].split('%')[0])
        pingstats['min'] = float(parsedresults[index +
                                               1].split(' ')[5].split('/')[0])
        pingstats['avg'] = float(parsedresults[index +
                                               1].split(' ')[5].split('/')[1])
        pingstats['max'] = float(parsedresults[index +
                                               1].split(' ')[5].split('/')[2])
    return pingstats


cp = EventingCSClient('ping_sample')
cp.log('Starting...')
cp.log('Output:\n' + json.dumps(ping('8.8.8.8')))
        # Log the Get request
        cp.log(f'Received Get request: {self.path}')

        # Send response status code
        self.send_response(200)

        # Send headers
        self.send_header('Content-type', 'text/html')
        self.end_headers()

        # Send message back to client
        # Write content as utf-8 data
        self.wfile.write(bytes(WEB_MESSAGE, "utf8"))
        return


cp = EventingCSClient('simple_web_server')

WEB_MESSAGE = "Hello World from Cradlepoint router!"

server_address = ('localhost', 9001)

cp.log("Starting Server: {}".format(server_address))
cp.log("Web Message is: {}".format(WEB_MESSAGE))

httpd = HTTPServer(server_address, WebServerRequestHandler)
try:
    httpd.serve_forever()
except KeyboardInterrupt:
    cp.log("Stopping Server, Key Board interrupt")
Beispiel #4
0
class SIMSpeedTest(object):
    MIN_DOWNLOAD_SPD = 0.0  # Mbps
    MIN_UPLOAD_SPD = 0.0  # Mbps
    SCHEDULE = 0  # Run Boot2 every {SCHEDULE} minutes. 0 = Only run on boot.
    NUM_ACTIVE_SIMS = 0  # Number of fastest (download) SIMs to keep active.  0 = all; do not disable SIMs
    ONLY_RUN_ONCE = False  # True means do not run if Boot2 has been run on this device before.

    STATUS_DEVS_PATH = '/status/wan/devices'
    CFG_RULES2_PATH = '/config/wan/rules2'
    CTRL_WAN_DEVS_PATH = '/control/wan/devices'
    API_URL = 'https://www.cradlepointecm.com/api/v2'
    CONNECTION_STATE_TIMEOUT = 7 * 60  # 7 Min
    NETPERF_TIMEOUT = 5 * 60  # 5 Min
    sims = {}

    def __init__(self):
        self.client = EventingCSClient('Boot2')

    def check_if_run_before(self):
        if self.ONLY_RUN_ONCE:
            if self.client.get('/config/wan/rules2/0/_id_'
                               ) == '00000000-1234-1234-1234-1234567890ab':
                self.client.log(
                    'ERROR - Boot2 has been run before! /config/wan/rules2/0/_id = 00000000-1234-1234-1234-1234567890ab'
                )
                raise RunBefore(
                    'ERROR - Boot2 has been run before! /config/wan/rules2/0/_id = 00000000-1234-1234-1234-1234567890ab'
                )
        return False

    def wait_for_ncm_sync(self):
        # WAN connection_state
        if self.client.get('status/wan/connection_state') != 'connected':
            self.client.log('Waiting until WAN is connected...')
        timeout_count = 500
        while self.client.get('/status/wan/connection_state') != 'connected':
            timeout_count -= 1
            if not timeout_count:
                raise Timeout('WAN not connecting')
            time.sleep(2)

        # ECM State
        if self.client.get('status/ecm/state') != 'connected':
            self.client.log('Waiting until NCM is connected...')
            self.client.put('/control/ecm', {'start': True})
        timeout_count = 500
        while self.client.get('/status/ecm/state') != 'connected':
            timeout_count -= 1
            if not timeout_count:
                raise Timeout('NCM not connecting')
            time.sleep(2)

        # ECM Sync
        if self.client.get('status/ecm/sync') != 'ready':
            self.client.log('Waiting until NCM is synced...')
            self.client.put('/control/ecm', {'start': True})
        timeout_count = 500
        while self.client.get('/status/ecm/sync') != 'ready':
            self.client.put('/control/ecm', {'start': True})
            timeout_count -= 1
            if not timeout_count:
                raise Timeout('NCM not connecting')
            time.sleep(2)

        return

    def NCM_suspend(self):
        self.client.log('Stopping NCM')
        timeout_count = 500
        while not 'ready' == self.client.get('/status/ecm/sync'):
            timeout_count -= 1
            if not timeout_count:
                raise Timeout('NCM sync not ready')
            time.sleep(2)
        self.client.put('/control/ecm', {'stop': True})
        timeout_count = 500
        while not 'stopped' == self.client.get('/status/ecm/state'):
            timeout_count -= 1
            if not timeout_count:
                raise Timeout('NCM not stopping')
            time.sleep(2)

    def find_sims(self):
        while True:
            sims = {}
            wan_devs = self.client.get(self.STATUS_DEVS_PATH) or {}
            for uid, status in wan_devs.items():
                if uid.startswith('mdm-'):
                    error_text = status.get('status', {}).get('error_text', '')
                    if error_text:
                        if 'NOSIM' in error_text:
                            continue
                    sims[uid] = status
            num_sims = len(sims)
            if not num_sims:
                self.client.log('No SIMs found at all yet')
                time.sleep(10)
                continue
            if num_sims < 2:
                self.client.log('Only 1 SIM found!')
                raise OneModem('Only 1 SIM found!')
            else:
                break
        self.client.log(f'Found SIMs: {sims.keys()}')
        self.sims = sims
        return True

    def modem_state(self, sim, state):
        # Blocking call that will wait until a given state is shown as the modem's status
        timeout_counter = 0
        sleep_seconds = 0
        conn_path = '%s/%s/status/connection_state' % (self.STATUS_DEVS_PATH,
                                                       sim)
        self.client.log(f'Connecting {self.port_sim(sim)}')
        while True:
            sleep_seconds += 5
            conn_state = self.client.get(conn_path)
            self.client.log(
                f'Waiting for {self.port_sim(sim)} to connect.  Current State={conn_state}'
            )
            if conn_state == state:
                break
            if timeout_counter > self.CONNECTION_STATE_TIMEOUT:
                self.client.log(f'Timeout waiting on {self.port_sim(sim)}')
                raise Timeout(conn_path)
            time.sleep(min(sleep_seconds, 45))
            timeout_counter += sleep_seconds
        self.client.log(f'{self.port_sim(sim)} connected.')
        return True

    def iface(self, sim):
        iface = self.client.get('%s/%s/info/iface' %
                                (self.STATUS_DEVS_PATH, sim))
        return iface

    def port_sim(self, sim):
        return f'{self.sims[sim]["info"]["port"]} {self.sims[sim]["info"]["sim"]}'

    def run_speedtest(self, speedtest):
        self.client.put('/state/system/netperf', {"run_count": 0})
        res = self.client.put("/control/netperf", speedtest)
        self.client.log(f'Starting Speedtest... {res}')

        timeout_counter = 0
        # wait for results
        delay = speedtest['input']['options']['limit']['time'] + 8
        status_path = "/control/netperf/output/status"
        while True:
            time.sleep(delay)
            status = self.client.get(status_path)
            if status == 'complete':
                break
            if timeout_counter > self.NETPERF_TIMEOUT:
                self.client.log(
                    f"Timeout waiting on speedtest for {speedtest['input']['options']['ifc_wan']}"
                )
                raise Timeout(status_path)
            timeout_counter += delay

        if status != 'complete':
            self.client.log(f"ERROR: status=%s expected 'complete' {status}")
            return None

        # now get the result
        results_path = self.client.get("/control/netperf/output/results_path")

        results = None
        while not results:
            results = self.client.get(results_path)
            time.sleep(2)
        self.client.log('Speedtest Complete.')
        return results

    def do_speedtest(self, sim):
        default_speedtest['input']['options']['ifc_wan'] = self.iface(sim)
        default_speedtest['input']['options']['send'] = False
        default_speedtest['input']['options']['recv'] = True
        tcp_down = self.run_speedtest(default_speedtest).get('tcp_down')
        default_speedtest['input']['options']['send'] = True
        default_speedtest['input']['options']['recv'] = False
        tcp_up = self.run_speedtest(default_speedtest).get('tcp_up')

        if not tcp_up:
            self.client.log('do_speedtest tcp_up results missing!')
            default_speedtest['input']['options']['send'] = True
            default_speedtest['input']['options']['recv'] = False
            results = self.run_speedtest(default_speedtest)
            tcp_up = results.get('tcp_up') or None

        if not tcp_down:
            self.client.log('do_speedtest tcp_down results missing!')
            default_speedtest['input']['options']['send'] = False
            default_speedtest['input']['options']['recv'] = True
            results = self.run_speedtest(default_speedtest)
            tcp_down = results.get('tcp_down') or None

        down = float(tcp_down.get('THROUGHPUT', 0.0)) if tcp_down else 0.0
        up = float(tcp_up.get('THROUGHPUT', 0.0)) if tcp_up else 0.0
        return down, up

    def test_sim(self, device):
        try:
            if self.modem_state(device, 'connected'):

                # Get diagnostics and log it
                diagnostics = self.client.get(
                    f'{self.STATUS_DEVS_PATH}/{device}/diagnostics')
                self.sims[device]['diagnostics'] = diagnostics
                self.client.log(
                    f'Modem Diagnostics: {self.port_sim(device)} RSRP:{diagnostics.get("RSRP")}'
                )

                # Do speedtest and log results
                self.sims[device]['download'], self.sims[device][
                    'upload'] = self.do_speedtest(self.sims[device])
                self.client.log(
                    f'Speedtest Results: {self.port_sim(device)} TCP Download: '
                    f'{self.sims[device]["download"]}Mbps TCP Upload: {self.sims[device]["upload"]}Mbps'
                )

                # Verify minimum speeds
                if self.sims[device].get(
                        'download',
                        0.0) > self.MIN_DOWNLOAD_SPD and self.sims[device].get(
                            'upload', 0.0) > self.MIN_UPLOAD_SPD:
                    return True
                else:  # Did not meet minimums
                    self.client.log(
                        f'{self.port_sim(device)} Failed to meet minimums! MIN_DOWNLOAD_SPD: {self.MIN_DOWNLOAD_SPD} MIN_UPLOAD_SPD: {self.MIN_UPLOAD_SPD}'
                    )
                    return False

        except Timeout:
            message = f'Timed out running speedtest on {self.port_sim(device)}'
            self.client.log(message)
            self.client.alert(message)
            self.sims[device]['download'] = self.sims[device]['upload'] = 0.0
            return False

    def create_message(self, uid, *args):
        message = ''
        for arg in args:
            if arg == 'download':
                message = "DL:{:.2f}Mbps".format(
                    self.sims[uid]['download']) if not message else ' '.join([
                        message, "DL:{:.2f}Mbps".format(
                            self.sims[uid]['download'])
                    ])
            elif arg == 'upload':
                message = "UL:{:.2f}Mbps".format(
                    self.sims[uid]['upload']) if not message else ' '.join([
                        message, "UL:{:.2f}Mbps".format(
                            self.sims[uid]['upload'])
                    ])
            elif arg in ['PRD', 'HOMECARRID',
                         'RFBAND']:  # Do not include labels for these fields
                message = "{}".format(
                    self.sims[uid]['diagnostics'][arg]
                ) if not message else ' '.join(
                    [message, "{}".format(self.sims[uid]['diagnostics'][arg])])
            else:  # Include field labels (e.g. "RSRP:-82")
                message = "{}:{}".format(
                    arg, self.sims[uid]['diagnostics']
                    [arg]) if not message else ' '.join([
                        message, "{}:{}".format(
                            arg, self.sims[uid]['diagnostics'][arg])
                    ])
        return message

    def lock_sim(self, sim):
        rules = [{
            "_id_":
            "00000000-1234-1234-1234-123456789000",
            "priority":
            0,
            "trigger_name":
            f"{self.sims[sim]['info']['port']} {self.sims[sim]['info']['sim']}",
            "trigger_string":
            f"type|is|mdm%sim|is|{self.sims[sim]['info']['sim']}%port|is|{self.sims[sim]['info']['port']}"
        }]
        for i, uid in enumerate(self.sims):
            if uid != sim:
                rule = {
                    "_id_": f"0000000{i+1}-1234-1234-1234-123456789000",
                    "priority": -9 + i,
                    "trigger_name":
                    f"{self.sims[sim]['info']['port']} {self.sims[sim]['info']['sim']}",
                    "trigger_string":
                    f"type|is|mdm%sim|is|{self.sims[sim]['info']['sim']}%port|is|{self.sims[sim]['info']['port']}",
                    "disabled": True
                }
                rules.append(rule)
        self.client.put('config/wan/rules2', rules)
        time.sleep(2)

    def create_rules(self, sim_list):
        wan_rules = [{
            "_id_": "00000000-1234-1234-1234-1234567890ab",
            "priority": -10,
            "trigger_name": "Ethernet",
            "trigger_string": "type|is|ethernet"
        }]
        for i in range(0, len(sim_list)):
            rule = {
                "_id_":
                f"0000000{i+1}-1234-1234-1234-123456789000",
                "priority":
                -9 + i,
                "trigger_name":
                f"{self.sims[sim_list[i]]['info']['port']} {self.sims[sim_list[i]]['info']['sim']}",
                "trigger_string":
                f"type|is|mdm%sim|is|{self.sims[sim_list[i]]['info']['sim']}%port|is|{self.sims[sim_list[i]]['info']['port']}"
            }
            if self.NUM_ACTIVE_SIMS and i >= self.NUM_ACTIVE_SIMS:
                rule['disabled'] = True
            wan_rules.append(rule)
        req = self.client.put('config/wan/rules2/', wan_rules)
        time.sleep(2)
        if self.client.get('config/wan/rules2/0/_id_'
                           ) == '00000000-1234-1234-1234-1234567890ab':
            self.client.log(f'Updated WAN rules')
        else:
            self.client.log(f'WAN Rules not updated! : {req}')
        return

    def run(self):  # *** Main Application Starts Here ***
        self.client.log(
            f'Boot2 Starting... MIN_DOWNLOAD_SPD:{self.MIN_DOWNLOAD_SPD} MIN_UPLOAD_SPD:{self.MIN_UPLOAD_SPD} '
            f'SCHEDULE:{self.SCHEDULE} NUM_ACTIVE_SIMS:{self.NUM_ACTIVE_SIMS} ONLY_RUN_ONCE:{self.ONLY_RUN_ONCE}'
        )

        self.check_if_run_before()

        self.wait_for_ncm_sync()

        # Get info from router
        product_name = self.client.get("/status/product_info/product_name")
        system_id = self.client.get("/config/system/system_id")
        router_id = self.client.get('status/ecm/client_id')

        self.find_sims()  # Find active SIM slots

        # Send startup alert
        message = f'Boot2 Starting! {system_id} - {product_name} - Router ID: {router_id}'
        self.client.log(f'Sending alert to NCM: {message}')
        self.client.alert(message)

        # Pause for 3 seconds to allow NCM Alert to be sent before suspending NCM
        time.sleep(3)
        self.NCM_suspend()

        success = False  # Boot2 Success Status - Becomes True when a SIM meets minimum speeds

        # Test the connected SIM first
        primary_device = self.client.get('status/wan/primary_device')
        if 'mdm-' in primary_device:  # make sure its a modem
            if self.test_sim(primary_device):
                success = True

        # test remaining SIMs
        for sim in self.sims:
            if not self.sims[sim].get('download'):
                self.lock_sim(sim)
                if self.test_sim(sim):
                    success = True

        # Prioritizes SIMs based on download speed
        sorted_results = sorted(self.sims,
                                key=lambda x: self.sims[x]['download'],
                                reverse=True)

        # Create WAN rules
        self.create_rules(sorted_results)
        time.sleep(3)

        # Build text for custom1 field
        results_text = datetime.datetime.now().strftime(
            '%m/%d/%y %H:%M:%S')  # Start with a timestamp
        if not success:
            results_text += f' FAILED TO MEET MINIMUMS! MIN_DOWNLOAD_SPD:{self.MIN_DOWNLOAD_SPD} MIN_UPLOAD_SPD:{self.MIN_UPLOAD_SPD}'
        for uid in sorted_results:  # Add the results of each SIM with the fields specified:
            results_text = ' | '.join([
                results_text,
                self.create_message(uid, 'PRD', 'HOMECARRID', 'RFBAND', 'RSRP',
                                    'download', 'upload')
            ])

        # put messages to NCM custom fields
        self.wait_for_ncm_sync()
        if apikeys.get('X-ECM-API-ID') != 'YOUR':
            self.client.log(
                f'X-ECM-API-ID: {apikeys["X-ECM-API-ID"]} X-CP-API-ID: {apikeys["X-CP-API-ID"]}'
            )
            req = requests.put(f'{self.API_URL}/routers/{router_id}/',
                               headers=apikeys,
                               json={'custom1': results_text[:255]})
            self.client.log(f'NCM PUT Custom1 Result: {req.status_code}')
        else:
            self.client.log(
                'No NCM API Keys configured, skipping PUT to custom1')

        # Complete!  Send results.
        message = f"Boot2 Complete! {system_id} Results: {results_text}"
        self.client.log(message)
        self.client.alert(message)
Beispiel #5
0
"""
Probe the GPS hardware and log the results.
"""
from csclient import EventingCSClient

cp = EventingCSClient('gps_probe')

gps_enabled = cp.get('/config/system/gps/enabled')

if not gps_enabled:
    cp.log('GPS Function is NOT Enabled')
else:
    cp.log('GPS Function is Enabled')
    gps_data = cp.get('/status/gps')
    cp.log(gps_data)
Beispiel #6
0
cp = EventingCSClient('cpu_usage')


def get_usage():

    while True:
        memory = cp.get('/status/system/memory')
        load_avg = cp.get('/status/system/load_avg')
        cpu = cp.get('/status/system/cpu')

        log_data = (
            'CPU Usage: ' + str(
                round(
                    float(cpu['nice']) + float(cpu['system']) +
                    float(cpu['user']) * float(100))) + '%, ' +
            ' Mem Available: ' + str(
                ('{:,.0f}'.format(memory['memavailable'] / float(1 << 20)) +
                 " MB,")) + ' Mem Total: ' + str(
                     ('{:,.0f}'.format(memory['memtotal'] / float(1 << 20)) +
                      " MB" + "\n")))

        cp.log(log_data)
        time.sleep(15)


if __name__ == '__main__':

    cp.log('Started App')
    get_usage()
    cp.log('Exited App')
Beispiel #7
0
# hello_world - log "Hello World!"
from csclient import EventingCSClient
cp = EventingCSClient('hello_world')
cp.log('Hello World!')
        if loader not in loaders:
            loaders[loader] = []

        # Add a name and a location about an imported module in the dict.
        # Don't include files that were created for this app or any
        # shared libraries.
        if this_module_name not in module_info.origin and '.so' not in module_info.origin:
            loaders[loader].append((module_info.name, module_info.origin))

    line = '-' * 10
    # Log the python version running in the device
    cp.log('{0} Python Version: {1} {0}'.format(line,
                                                platform.python_version()))

    # Log the python module that were found in the device
    for loader, modules in loaders.items():
        if len(modules) != 0:
            cp.log('{0} Module Count={1}: {2} {0}'.format(
                line, len(modules), loader))
            count = 0
            for mod in modules:
                count += 1
                cp.log('|{0:>3}| {1:20}| {2}'.format(count, mod[0], mod[1]))


if __name__ == "__main__":
    try:
        log_module_list()
    except Exception as e:
        cp.log('Exception occurred! exception: {}'.format(e))
                    ip_data = get_ip_config_info(form)
                    ip_config(ip_data)
                    value = '{} - {}'.format(value, ip_data)

                if value == 'router_data':
                    self.send_response(HTTPStatus.OK)
                    self.send_header('Content-type', 'application/json')
                    self.end_headers()
                    self.wfile.write(
                        bytes(json.dumps(get_router_data()), 'utf-8'))
                    return

            # This is here just to echo back to the client what is receive.
            self.send_response(HTTPStatus.OK)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            self.wfile.write(
                bytes(
                    '<html><body><h1>Server Received: {}</h1></body></html>'.
                    format(value), 'utf-8'))


cp = EventingCSClient('simple_custom_dashboard')
server_address = ('', 9001)
cp.log('Starting Server: {}'.format(server_address))
httpd = HTTPServer(server_address, WebServerRequestHandler)
try:
    httpd.serve_forever()
except KeyboardInterrupt:
    cp.log('Stopping Server, Key Board interrupt')
Beispiel #10
0
cp = EventingCSClient('multicast_to_unicast')
'''
MODIFY THESE VARIABLES TO MATCH YOUR ENVIRONMENT
'''

MCAST_GRP = '224.1.1.1'  # Multicast group to listen on
MCAST_PORT = 5001  # Multicast port to listen on
MCAST_LISTEN_IP = '192.168.0.1'  # Cradlepoint interface IP address to listen on

UCAST_DST_IP = '192.168.0.125'  #Unicast destination to
UCAST_DST_PORT = 5002
'''
DO NOT CHANGE ANYTHING BELOW
'''

cp.log("APP STARTED")

s = socket.socket(type=socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
except AttributeError:
    pass
s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 20)
s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)

s.bind(('', MCAST_PORT))

intf = MCAST_LISTEN_IP
s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(intf))
s.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP,
Beispiel #11
0
    # anonymous user
    authorizer.add_user('survey', 'survey', FTP_DIR, perm='elradfmwM')
    authorizer.add_anonymous(FTP_DIR)

    # Instantiate FTP handler class
    handler = FTPHandler
    handler.authorizer = authorizer

    # Define a customized banner (string returned when client connects)
    handler.banner = "pyftpdlib based ftpd ready."

    # Instantiate FTP server class and listen on 0.0.0.0:2121.
    # Application can only use ports higher that 1024 and the port
    # will need to be allowed in the router firewall
    address = ('', 2121)
    server = FTPServer(address, handler)

    # set a limit for connections
    server.max_cons = 256
    server.max_cons_per_ip = 5

    # start ftp server
    cp.log('Starting FTP server...')
    server.serve_forever()
    # This will run the server in another thread
    # t = Thread(target=server.serve_forever())
    # t.start()

except Exception as e:
    cp.log('Exception occurred! exception: {}'.format(e))
Beispiel #12
0
A reference application to access GNSS on the IBR1700.
See the readme.txt for more details.

"""

import time
import socket

from inetline import ReadLine
from csclient import EventingCSClient

cp = EventingCSClient('ibr1700_gnss')
gnssd_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
    cp.log('Starting...')
    gnss_addr = ("127.0.0.1", 17488)

    cp.log("Attempting sock.connect({})".format(gnss_addr))
    gnssd_sock.connect(gnss_addr)

    # Turns on ALL messages. Only way to turn off is to close the socket.
    cp.log("Attempting sock.send(b'ALL\\r\\n')")
    gnssd_sock.sendall(b'ALL\r\n')

    # Enable IMU messages
    cp.log("Attempting sock.send(b'IMU yes\\r\\n')")
    gnssd_sock.sendall(b'IMU yes\n\r')

    receive_line = ReadLine()
class DataUsageCheck(object):
    """
    Establish global variables.
    
    Set rate shaping values (in Kbps) 
    """

    # Modem Defaults (as of 7.0.40) - Not used when QoS is Disabled
    maxbwup = 25000
    maxbwdown = 25000

    minbwup = 512
    minbwdown = 512
    capreached = 0
    STATUS_DEVS_PATH = '/status/wan/devices'
    STATUS_DATACAP_PATH = '/status/wan/datacap'
    CFG_RULES2_PATH = '/config/wan/rules2'

    def __init__(self):
        self.cp = EventingCSClient(app_name)

    def find_modems(self):
        while True:
            devs = self.cp.get(self.STATUS_DEVS_PATH)
            modems_list = [x for x in devs if x.startswith('mdm-')]
            self.cp.log(f'modems_list: {modems_list}')
            num_modems = len(modems_list)
            if not num_modems:
                self.cp.log('No Modems found at all yet')
                time.sleep(10)
                continue
            else:
                return modems_list

    def find_modem_profiles(self):
        wan_ifcs = self.cp.get(self.CFG_RULES2_PATH)
        modem_profiles_list = [
            x['_id_'] for x in wan_ifcs
            if x['trigger_string'].startswith('type|is|mdm')
        ]
        self.cp.log(f'modem_profiles_list: {modem_profiles_list}')
        return modem_profiles_list

    def reset_throttle(self, modem_profiles_list, monthlyreset):
        for mdm in modem_profiles_list:
            if monthlyreset:
                self.cp.delete(self.CFG_RULES2_PATH + '/' + mdm +
                               '/bandwidth_egress')
                self.cp.delete(self.CFG_RULES2_PATH + '/' + mdm +
                               '/bandwidth_ingress')
            else:
                if 'bandwidth_egress' in self.cp.get(self.CFG_RULES2_PATH +
                                                     '/' + mdm):
                    self.cp.delete(self.CFG_RULES2_PATH + '/' + mdm +
                                   '/bandwidth_egress')
                if 'bandwidth_ingress' in self.cp.get(self.CFG_RULES2_PATH +
                                                      '/' + mdm):
                    self.cp.delete(self.CFG_RULES2_PATH + '/' + mdm +
                                   '/bandwidth_ingress')
        self.cp.put('config/qos/enabled', False)
        if monthlyreset:
            self.cp.log(
                'Monthly data usage reset - disabling reduced LTE data rate')
            message = (
                f'Monthly data usage reset - disabling reduced LTE data rate '
                f'for {self.system_id} - {self.product_name} - Router ID: '
                f'{self.router_id}')
            self.cp.alert(message)
            self.capreached = 0

    def set_throttle(self, modem_profiles_list):
        for mdm in modem_profiles_list:
            self.cp.put(self.CFG_RULES2_PATH + '/' + mdm + '/bandwidth_egress',
                        self.minbwup)
            self.cp.put(
                self.CFG_RULES2_PATH + '/' + mdm + '/bandwidth_ingress',
                self.minbwdown)
        self.cp.put('config/qos/enabled', True)
        self.cp.log(
            'Exceeded monthly data usage threshold - reducing LTE data rate')
        message = (
            f'Exceeded monthly data usage threshold - reducing LTE data rate '
            f'for {self.system_id} - {self.product_name} - Router ID: '
            f'{self.router_id}')
        self.cp.alert(message)
        self.capreached = 1

    def run(self):
        # Get info from router to populate description field in NCM
        # alert message
        self.product_name = self.cp.get('/status/product_info/product_name')
        self.system_id = self.cp.get('/config/system/system_id')
        self.router_id = self.cp.get('status/ecm/client_id')
        # Retrieve list of modems and their profiles
        modems_list = [str(x.split('-')[1]) for x in self.find_modems()]
        modem_profiles_list = self.find_modem_profiles()
        # Reset any throttling to account for router reboots.  If a
        # data cap alert is still active during the monthly cycle, the
        # appropriate rate shaping will be re-applied
        monthlyreset = False
        self.reset_throttle(modem_profiles_list, monthlyreset)
        time.sleep(5)

        while True:
            if self.cp.get(self.STATUS_DATACAP_PATH + '/completed_alerts/'):
                alerts = self.cp.get(self.STATUS_DATACAP_PATH +
                                     '/completed_alerts/')
                limitreached = 0
                for modem in modems_list:
                    if [
                            x['rule_id'] for x in alerts
                            if x['rule_id'] == modem + '-monthly'
                            if 'email_alert' in x['alerts']
                    ]:
                        limitreached += 1
                if limitreached > 0 and self.capreached == 0:
                    self.set_throttle(modem_profiles_list)
                elif limitreached == 0 and self.capreached == 1:
                    monthlyreset = True
                    self.reset_throttle(modem_profiles_list, monthlyreset)
            elif self.capreached == 1:
                monthlyreset = True
                self.reset_throttle(modem_profiles_list, monthlyreset)
            time.sleep(10)
Beispiel #14
0
        system_id = cp.get('/config/system/system_id')
        mqtt_client = mqtt.Client(client_id=system_id)
        mqtt_client.disable_logger()

        # Assign callback functions
        mqtt_client.on_connect = on_connect
        mqtt_client.on_subscribe = on_subscribe
        mqtt_client.on_message = on_message

        # Connect to the MQTT broker using the server and port in the settings file.
        connack_code = mqtt_client.connect(settings.MQTT_SERVER,
                                           settings.MQTT_PORT)
        cp.log('MQTT connect reply to {}, {}: {}'.format(
            settings.MQTT_SERVER, settings.MQTT_PORT,
            mqtt.connack_string(connack_code)))

        # Blocking call that processes network traffic, dispatches callbacks and
        # handles reconnecting.
        mqtt_client.loop_forever()

    except Exception as ex:
        cp.log('Exception in start_mqtt()! exception: {}'.format(ex))
        raise


if __name__ == "__main__":
    try:
        start_mqtt()
    except Exception as ex:
        cp.log('Exception occurred!: {}'.format(ex))
Beispiel #15
0
class DataUsageCheck(object):
    """
    Establish global variables.

    Set rate shaping values (in Kbps) for 70, 80, 90 & 100% rate tiers.
    e.g. minbwup_70 & minbwdown_70 refers to upload & download at 70%
    
    Each of the rate tiers have a default throttling limit set below:
    70% - 6000Kbps Tx/Rx
    80% - 3000Kbps Tx/Rx
    90% - 1500Kbps Tx/Rx
    100% - 600Kbps Tx/Rx
    """

    minbwup_70 = 6000
    minbwdown_70 = 6000
    minbwup_80 = 3000
    minbwdown_80 = 3000
    minbwup_90 = 1500
    minbwdown_90 = 1500
    minbwup_100 = 600
    minbwdown_100 = 600
    STATUS_DEVS_PATH = '/status/wan/devices'
    STATUS_DATACAP_PATH = '/status/wan/datacap'
    CFG_RULES2_PATH = '/config/wan/rules2'

    def __init__(self):
        self.cp = EventingCSClient(app_name)

    def find_modems(self):
        while True:
            devs = self.cp.get(self.STATUS_DEVS_PATH)
            modems_list = [x for x in devs if x.startswith('mdm-')]
            self.cp.log(f'modems_list: {modems_list}')
            num_modems = len(modems_list)
            if not num_modems:
                self.cp.log('No Modems found at all yet')
                time.sleep(10)
                continue
            else:
                return modems_list

    def find_modem_profiles(self):
        wan_ifcs = self.cp.get(self.CFG_RULES2_PATH)
        modem_profiles_list = [
            x['_id_'] for x in wan_ifcs
            if x['trigger_string'].startswith('type|is|mdm')
        ]
        self.cp.log(f'modem_profiles_list: {modem_profiles_list}')
        return modem_profiles_list

    def reset_throttle(self, modem_profiles_list, monthlyreset):
        for mdm in modem_profiles_list:
            if monthlyreset:
                self.cp.delete(self.CFG_RULES2_PATH + '/' + mdm +
                               '/bandwidth_egress')
                self.cp.delete(self.CFG_RULES2_PATH + '/' + mdm +
                               '/bandwidth_ingress')
            else:
                if 'bandwidth_egress' in self.cp.get(self.CFG_RULES2_PATH +
                                                     '/' + mdm):
                    self.cp.delete(self.CFG_RULES2_PATH + '/' + mdm +
                                   '/bandwidth_egress')
                if 'bandwidth_ingress' in self.cp.get(self.CFG_RULES2_PATH +
                                                      '/' + mdm):
                    self.cp.delete(self.CFG_RULES2_PATH + '/' + mdm +
                                   '/bandwidth_ingress')
        self.cp.put('config/qos/enabled', False)
        if monthlyreset:
            self.cp.log(
                'Monthly data usage reset - disabling reduced LTE data rate')
            message = (
                f'Monthly data usage reset - disabling reduced LTE data rate '
                f'for {self.system_id} - {self.product_name} - Router ID: '
                f'{self.router_id}')
            self.cp.alert(message)

    def set_throttle(self, modem_profiles_list, minbwup, minbwdown, tierset):
        for mdm in modem_profiles_list:
            self.cp.put(self.CFG_RULES2_PATH + '/' + mdm + '/bandwidth_egress',
                        minbwup)
            self.cp.put(
                self.CFG_RULES2_PATH + '/' + mdm + '/bandwidth_ingress',
                minbwdown)
        self.cp.put('config/qos/enabled', True)
        self.cp.log('Exceeded monthly data usage threshold - ' + str(tierset) +
                    '% tier - reducing LTE data rate')
        message = (
            f'Exceeded monthly data usage threshold - reducing LTE data rate '
            f'for {self.system_id} - {self.product_name} - Router ID: '
            f'{self.router_id}')
        self.cp.alert(message)

    def run(self):
        # Get info from router to populate description field in NCM
        # alert message
        self.product_name = self.cp.get('/status/product_info/product_name')
        self.system_id = self.cp.get('/config/system/system_id')
        self.router_id = self.cp.get('status/ecm/client_id')
        # Retrieve list of modems and their profiles
        modems_list = [str(x.split('-')[1]) for x in self.find_modems()]
        modem_profiles_list = self.find_modem_profiles()
        # Reset any throttling to account for router reboots.  If a
        # data cap alert is still active during the monthly cycle, the
        # appropriate rate shaping will be re-applied
        monthlyreset = False
        self.reset_throttle(modem_profiles_list, monthlyreset)
        time.sleep(5)

        currtierset = 0

        while True:
            if self.cp.get(self.STATUS_DATACAP_PATH + '/completed_alerts/'):
                alerts = self.cp.get(self.STATUS_DATACAP_PATH +
                                     '/completed_alerts/')
                limitreached = 0
                tierset = 0
                for indalert in alerts:
                    for modem in modems_list:
                        if (indalert['alerts']
                                and indalert['rule_id'] == modem + '-monthly'):
                            if 'email_alert' in indalert['alerts']:
                                limitreached += 1
                                tierset = 100
                                minbwup = self.minbwup_100
                                minbwdown = self.minbwdown_100
                                continue
                            elif 'early_email-90.0' in indalert['alerts']:
                                limitreached += 1
                                tierset = 90
                                minbwup = self.minbwup_90
                                minbwdown = self.minbwdown_90
                                continue
                            elif 'early_email-80.0' in indalert['alerts']:
                                limitreached += 1
                                tierset = 80
                                minbwup = self.minbwup_80
                                minbwdown = self.minbwdown_80
                                continue
                            elif 'early_email-70.0' in indalert['alerts']:
                                limitreached += 1
                                tierset = 70
                                minbwup = self.minbwup_70
                                minbwdown = self.minbwdown_70
                                continue
                if limitreached > 0 and currtierset != tierset:
                    currtierset = tierset
                    self.set_throttle(modem_profiles_list, minbwup, minbwdown,
                                      currtierset)
                elif limitreached == 0 and currtierset > 0:
                    currtierset = 0
                    monthlyreset = True
                    self.reset_throttle(modem_profiles_list, monthlyreset)
            elif currtierset > 0:
                currtierset = 0
                monthlyreset = True
                self.reset_throttle(modem_profiles_list, monthlyreset)
            time.sleep(10)
Beispiel #16
0
        if line:
            output += line + '<br>'
    return output


class ShellHandler(tornado.web.RequestHandler):
    """handle requests for the /shell endpoint."""
    def get(self):
        """return command response."""
        response = ''
        try:
            cmd = self.get_argument('cmd')
            response = shell(cmd) or 'No Response'
        except Exception as e:
            cp.log(e)
        self.write(response)


if __name__ == "__main__":
    cp = EventingCSClient('cp_shell')
    cp.log(f'Starting webserver on port {server_port}...')
    application = tornado.web.Application([
        (r"/shell", ShellHandler),
        (r"/(.*)", tornado.web.StaticFileHandler, {
            "path": static_path,
            "default_filename": "index.html"
        }),
    ])
    application.listen(server_port)
    tornado.ioloop.IOLoop.current().start()
                                password=sas_token)

    mqtt_client.tls_set(ca_certs=path_to_root_cert,
                        certfile=None,
                        keyfile=None,
                        cert_reqs=ssl.CERT_REQUIRED,
                        tls_version=ssl.PROTOCOL_TLSv1,
                        ciphers=None)

    mqtt_client.tls_insecure_set(False)

    mqtt_client.connect(iot_hub_name + '.azure-devices.net', port=8883)

    # Get some router data and publish to the IoT Hub
    device_data = dict()
    cp.log('device_data = {}'.format(device_data))
    device_data['router_id'] = cp.get('/config/system/system_id')
    device_data['product_name'] = cp.get('/status/product_info/product_name')

    # Not all CP devices have a modem_temperature
    if device_data['product_name'].startswith('ibr200') is False:
        device_data['router_temperature'] = cp.get(
            '/status/system/modem_temperature')

    mqtt_client.publish('devices/' + device_id + '/messages/events/',
                        urllib.parse.urlencode(device_data),
                        qos=1)

    mqtt_client.loop_forever()

except Exception as e:
import time
from csclient import EventingCSClient
cp = EventingCSClient('ports-status')

APP_NAME = 'PORTS_STATUS'
DEBUG = False
MODELS_WITHOUT_WAN = ['CBA', 'W18', 'W200', 'W400', 'L950', 'IBR200', '4250']

if DEBUG:
    cp.log("DEBUG ENABLED")

if DEBUG:
    cp.log("Getting Model")
"""Get model number, since some models don't have ethernet WAN"""
model = ''
model = cp.get('/status/product_info/product_name')
if DEBUG:
    cp.log(model)

while True:
    try:
        ports_status = ""
        is_available_modem = 0
        is_available_wan = 0
        is_available_wwan = 0
        is_configured_wwan = 0

        wans = cp.get('/status/wan/devices')
        mdm_present = False
        for wan in wans:
            if 'mdm' in wan:
Beispiel #19
0
"""
This app will create a file and then upload it to an FTP server.
The file will be deleted when the app is stopped.
"""

from csclient import EventingCSClient
from ftplib import FTP

cp = EventingCSClient('ftp_client')
TEMP_FILE = 'my_file.txt'

cp.log('ftp_client send_ftp_file()...')
# Create a temporary file to upload to an FTP server
try:
    f = open(TEMP_FILE, 'w')
    f.write('This is a test!!')
    f.write('This is another test!!')
    f.close()
except OSError as msg:
    cp.log('Failed to open file: {}. error: {}'.format(TEMP_FILE, msg))

try:
    # Connect to an FTP test server
    ftp = FTP('speedtest.tele2.net')

    # Login to the server
    reply = ftp.login('anonymous', 'anonymous')
    cp.log('FTP login reply: {}'.format(reply))

    # Change to the proper directory for upload
    ftp.cwd('/upload/')
Beispiel #20
0
# shell_sample - execute linux shell_sample command and return output

from csclient import EventingCSClient


def shell(cmd):
    """
    executes a linux shell command and returns the output
    :param cmd: string
        command to be executed. e.g. "ls -al"
    :return: string
        output of shell command
    """
    from subprocess import Popen, PIPE
    output = ''
    cmd = cmd.split(' ')
    tail = Popen(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True)
    for line in iter(tail.stdout.readline, ''):
        if tail.returncode:
            break
        if line:
            output += line
    return output


cp = EventingCSClient('shell_sample')
cp.log('Starting...')
cp.log('Output:\n' + shell('ls -al'))