blob: b0b258f9935fbc7887de46cda544a610fc4ead65 [file] [log] [blame]
Hyunsun Moon4506e3e2020-10-07 01:27:12 +00001#!/usr/bin/env python3
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -07002
3# Copyright 2020-present Open Networking Foundation
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License
16
Hyunsun Moon4506e3e2020-10-07 01:27:12 +000017import sys
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -070018import os
19import time
20import requests
21import json
22import enum
Hyunsun Moon4506e3e2020-10-07 01:27:12 +000023import logging
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -070024from collections import namedtuple
25from pyadb import ADB
26
27'''
28Check Aether network operational status and report it to
29central monitoring server
30
311) check mobile connctivity after toggling the airplane mode
322) check if ping to 8.8.8.8 works
33'''
34
35CONF = json.loads(
36 open(os.getenv('CONFIG_FILE', "./config.json")).read(),
37 object_hook=lambda d: namedtuple('X', d.keys())(*d.values())
38)
39
Hyunsun Moon4506e3e2020-10-07 01:27:12 +000040logging.basicConfig(
41 filename=CONF.log_file,
42 format='%(asctime)s [%(levelname)s] %(message)s',
43 level=logging.WARN
44)
45
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -070046ADB_GET_COMMANDS = {
47 "apn_mode": "settings get global airplane_mode_on",
48 "lte_state": "dumpsys telephony.registry | grep -m1 mDataConnectionState",
49 "ping_result": "ping -c 3 8.8.8.8&>/dev/null; echo $?"
50}
51ADB_APN_COMMANDS = {
52 "home": "input keyevent 3",
53 "setting": "am start -a android.settings.AIRPLANE_MODE_SETTINGS",
54 "toggle": "input tap " + \
55 CONF.adb.apn_mode_toggle_location.x + " " + \
56 CONF.adb.apn_mode_toggle_location.y
57}
58
59
60class State(enum.Enum):
61 error = "-1"
62 disconnected = "0"
63 connecting = "1"
64 connected = "2"
65
66 @classmethod
67 def has_value(cls, value):
68 return value in cls._value2member_map_
69
70
71edge_status = {
72 'name': CONF.edge_name,
73 'status': {
74 'control_plane': None,
75 'user_plane': 'connected'
76 }
77}
78
79
80def _run_adb_shell(adb, command):
Hyunsun Moon53097ea2020-09-04 17:20:29 -070081 result, error = adb.shell_command(command)
Hyunsun Moon4506e3e2020-10-07 01:27:12 +000082 # error is returned even when succeeded
83 # so ignore error value here
84 if result:
85 logging.debug(result)
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -070086 time.sleep(2)
87 result = result[0] if result is not None else None
88 return True, result
89
90
Hyunsun Moon53097ea2020-09-04 17:20:29 -070091def get_control_plane_state(adb):
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -070092 '''
93 check aether control plane works by toggling airplane mode
94 '''
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -070095 # get the current airplane mode
96 success, result = _run_adb_shell(adb, ADB_GET_COMMANDS['apn_mode'])
97 if not success or result is None:
98 return State.error, result
99 apn_mode_on = True if result == "1" else False
100
101 # toggle the airplane mode
102 for command in ADB_APN_COMMANDS.values():
103 success, result = _run_adb_shell(adb, command)
104 if not success:
105 return State.error, result
106 if not apn_mode_on:
107 success, result = _run_adb_shell(adb, ADB_APN_COMMANDS['toggle'])
108 if not success:
109 return State.error, result
110
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700111 # get connection state
112 state = State.connecting.value
Hyunsun Moona40bda52021-01-21 12:04:43 -0800113 retry_count = 10
114 while retry_count > 0:
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700115 success, result = _run_adb_shell(adb, ADB_GET_COMMANDS['lte_state'])
116 if not success or result is None:
Hyunsun Moona40bda52021-01-21 12:04:43 -0800117 continue
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700118 state = result.split("=")[1]
Hyunsun Moona40bda52021-01-21 12:04:43 -0800119 if state == State.connected.value:
120 break
121 retry_count -= 1
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700122
123 if not State.has_value(state):
124 return State.error, None
125 return State(state), None
126
127
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700128def get_user_plane_state(adb):
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700129 '''
130 checks aether user plane connectivity with ping to 8.8.8.8
131 '''
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700132 success, result = _run_adb_shell(adb, ADB_GET_COMMANDS['ping_result'])
133 if not success or result is None:
134 return State.error, result
135
136 state = State.connected if result == "0" else State.disconnected
137 return state, None
138
139
140def report_aether_network_state():
141 '''
142 report the aether network state to the monitoring server
143 '''
Hyunsun Moon4506e3e2020-10-07 01:27:12 +0000144 logging.info("Sending report %s", edge_status)
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700145 try:
146 result = requests.post(CONF.report_url, json=edge_status)
147 except requests.exceptions.ConnectionError:
Hyunsun Moon4506e3e2020-10-07 01:27:12 +0000148 logging.error("Failed to report for %s", e)
149 pass
150 try:
151 result.raise_for_status()
152 except requests.exceptions.HTTPError as e:
153 logging.error("Failed to report for %s", e)
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700154 pass
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700155
156
Hyunsun Moon4506e3e2020-10-07 01:27:12 +0000157def main():
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700158 adb = ADB()
159 if adb.set_adb_path(CONF.adb.path) is False:
Hyunsun Moon4506e3e2020-10-07 01:27:12 +0000160 logging.error(CONF.adb.path + " not found")
161 sys.exit(1)
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700162
163 dev = adb.get_devices()
164 if len(dev) == 0:
Hyunsun Moon4506e3e2020-10-07 01:27:12 +0000165 logging.error("No device found")
166 sys.exit(1)
167
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700168 adb.set_target_device(dev[0])
Hyunsun Moon4506e3e2020-10-07 01:27:12 +0000169 success, result = _run_adb_shell(adb, "svc data enable")
170 if not success:
171 logging.error("Failed to turn data on")
172 sys.exit(1)
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700173
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700174 while True:
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700175 cp_state, err = get_control_plane_state(adb)
176 up_state, err = get_user_plane_state(adb)
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700177
178 edge_status['status']['control_plane'] = cp_state.name
179 edge_status['status']['user_plane'] = up_state.name
180
181 report_aether_network_state()
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700182 time.sleep(CONF.report_interval)
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700183
184
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700185if __name__ == "__main__":
186 main()