Reconfigure monitoring agent

- Run signal quality and dongle stats fetch after control plane test.
- Run dry run as user plane test if available, dns 3x otherwise.
- Change ping latency iterations from 10 to 5.
- Change NO_RESULT_THRESHOLD from 720 to 360 for more accurate in-band results.
- Run curl and pycurl with silent option to avoid flooding the journalctl log.

Change-Id: I2bbea189ded0da021aa17a4a5a7392aa725ce416
diff --git a/VERSION b/VERSION
index 8bd6ba8..c006218 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.7.5
+0.7.6
diff --git a/edge-monitoring-server/edge_monitoring_server.py b/edge-monitoring-server/edge_monitoring_server.py
index fa50bcc..6e71973 100755
--- a/edge-monitoring-server/edge_monitoring_server.py
+++ b/edge-monitoring-server/edge_monitoring_server.py
@@ -23,7 +23,7 @@
 AETHER_ENV = os.environ.get("AETHER_ENV", "production")
 
 # Move to "no result" status if we don't hear from agent for this many seconds
-NO_RESULT_THRESHOLD = 720
+NO_RESULT_THRESHOLD = 360
 
 dictConfig({
     'version': 1,
diff --git a/edge-monitoring/agent_modem/edge_monitoring_agent_modem.py b/edge-monitoring/agent_modem/edge_monitoring_agent_modem.py
index 0315655..c9d362b 100755
--- a/edge-monitoring/agent_modem/edge_monitoring_agent_modem.py
+++ b/edge-monitoring/agent_modem/edge_monitoring_agent_modem.py
@@ -170,14 +170,22 @@
 
 
 def get_user_plane_state(modem):
-    try:
-        subprocess.check_output(
-            "ping -c 3 " + CONF.ips.dns + ">/dev/null 2>&1",
-            shell=True)
-        return State.connected
-    except subprocess.CalledProcessError as e:
-        logging.warning("User plane test failed")
-        return State.disconnected
+    if "dry_run" in CONF.ips._fields and CONF.ips.dry_run: # run dry_run latency test as user plane test
+        dry_run_latency, dry_run_passed = run_ping_test(CONF.ips.dry_run, 3)
+        if dry_run_passed:
+            return State.connected, dry_run_latency
+        else:
+            logging.warning("User plane test failed")
+            return State.disconnected, dry_run_latency
+    else: # run default user plane test
+        try:
+            subprocess.check_output(
+                "ping -c 3 " + CONF.ips.dns + ">/dev/null 2>&1",
+                shell=True)
+            return State.connected, None
+        except subprocess.CalledProcessError as e:
+            logging.warning("User plane test failed")
+            return State.disconnected, None
 
 
 def run_ping_test(ip, count):
@@ -230,18 +238,23 @@
     return result, True
 
 
-def get_ping_test(modem):
+def get_ping_test(modem, dry_run_latency=None):
     '''
     Prepares the ping test.
     Runs ping tests from 'ips' entry in config.json in order.
-    Note: 'dry_run' IP entry runs 3 ping iterations. Other IPs run 10 iterations.
+    Note: 'dry_run' is not run here; it is run during the user plane test.
     '''
     speedtest_ping = {}
     status = True
     ping_test_passed = True
 
+    if dry_run_latency:
+        speedtest_ping["dry_run"] = dry_run_latency
+
     for i in range(0, len(CONF.ips)):
-        count = 10 if CONF.ips._fields[i] != "dry_run" else 3
+        if CONF.ips._fields[i] == "dry_run":
+            continue
+        count = 5
         speedtest_ping[CONF.ips._fields[i]], status = run_ping_test(CONF.ips[i], count)
         if not status:
             ping_test_passed = False
@@ -324,6 +337,10 @@
 
 def get_dongle_stats(modem):
     result = {'SuccessfulFetch' : False}
+    if "report_in_band" in CONF._fields:
+        result['inBandReporting'] = CONF.report_in_band
+    else:
+        result['inBandReporting'] = False
     XMLkeys = ["MAC",
                "PLMNStatus",
                "UICCStatus",
@@ -342,7 +359,7 @@
                "IPv4Addr"]
     dongleStatsXML = None
     try:
-        dongleStatsXML = ET.fromstring(subprocess.check_output("curl -u admin:admin 'http://192.168.0.1:8080/cgi-bin/ltestatus.cgi?Command=Status'", shell=True).decode("UTF-8"))
+        dongleStatsXML = ET.fromstring(subprocess.check_output("curl -u admin:admin -s 'http://192.168.0.1:8080/cgi-bin/ltestatus.cgi?Command=Status'", shell=True).decode("UTF-8"))
     except Exception as e:
         logging.error("Failed to fetch dongle stats from URL: " + str(e))
         return result
@@ -423,6 +440,7 @@
            c.setopt(pycurl.INTERFACE, CONF.modem.iface)
         elif "report_iface" in CONF._fields and CONF.report_iface:
            c.setopt(pycurl.INTERFACE, CONF.report_iface)
+        c.setopt(pycurl.WRITEFUNCTION, lambda x: None) # don't output to console
         c.perform()
         c.close()
     except Exception as e:
@@ -490,11 +508,9 @@
         sys.exit(1)
 
     while True:
-        dongle_stats = get_dongle_stats(modem)
-
-        signal_quality = get_signal_quality(modem)
-
         cp_state = get_control_plane_state(modem)
+        signal_quality = get_signal_quality(modem)
+        dongle_stats = get_dongle_stats(modem)
         if cp_state is State.error:
             logging.error("Modem is in error state.")
             reset_usb()
@@ -504,13 +520,13 @@
             report_status(signal_quality, dongle_stats)
             continue
 
-        up_state = get_user_plane_state(modem)
+        up_state, dry_run_latency = get_user_plane_state(modem)
         if up_state is State.disconnected:
             # Basic user plane test failed, don't need to run the rest of tests
             report_status(signal_quality, dongle_stats, cp_state)
             continue
 
-        speedtest_ping, speedtest_status = get_ping_test(modem)
+        speedtest_ping, speedtest_status = get_ping_test(modem, dry_run_latency)
         if speedtest_status:
             speedtest_iperf = get_iperf_test(modem)
         else: