blob: 86c05d57417823a85b0b2ce3dbfb254ac02e65dc [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
111 # additional wait for UE to fully attach
112 time.sleep(3)
113
114 # get connection state
115 state = State.connecting.value
116 while state == State.connecting.value:
117 success, result = _run_adb_shell(adb, ADB_GET_COMMANDS['lte_state'])
118 if not success or result is None:
119 return State.error, result
120 state = result.split("=")[1]
121
122 if not State.has_value(state):
123 return State.error, None
124 return State(state), None
125
126
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700127def get_user_plane_state(adb):
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700128 '''
129 checks aether user plane connectivity with ping to 8.8.8.8
130 '''
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700131 success, result = _run_adb_shell(adb, ADB_GET_COMMANDS['ping_result'])
132 if not success or result is None:
133 return State.error, result
134
135 state = State.connected if result == "0" else State.disconnected
136 return state, None
137
138
139def report_aether_network_state():
140 '''
141 report the aether network state to the monitoring server
142 '''
Hyunsun Moon4506e3e2020-10-07 01:27:12 +0000143 logging.info("Sending report %s", edge_status)
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700144 try:
145 result = requests.post(CONF.report_url, json=edge_status)
146 except requests.exceptions.ConnectionError:
Hyunsun Moon4506e3e2020-10-07 01:27:12 +0000147 logging.error("Failed to report for %s", e)
148 pass
149 try:
150 result.raise_for_status()
151 except requests.exceptions.HTTPError as e:
152 logging.error("Failed to report for %s", e)
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700153 pass
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700154
155
Hyunsun Moon4506e3e2020-10-07 01:27:12 +0000156def main():
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700157 adb = ADB()
158 if adb.set_adb_path(CONF.adb.path) is False:
Hyunsun Moon4506e3e2020-10-07 01:27:12 +0000159 logging.error(CONF.adb.path + " not found")
160 sys.exit(1)
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700161
162 dev = adb.get_devices()
163 if len(dev) == 0:
Hyunsun Moon4506e3e2020-10-07 01:27:12 +0000164 logging.error("No device found")
165 sys.exit(1)
166
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700167 adb.set_target_device(dev[0])
Hyunsun Moon4506e3e2020-10-07 01:27:12 +0000168 success, result = _run_adb_shell(adb, "svc data enable")
169 if not success:
170 logging.error("Failed to turn data on")
171 sys.exit(1)
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700172
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700173 while True:
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700174 cp_state, err = get_control_plane_state(adb)
175 up_state, err = get_user_plane_state(adb)
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700176
177 edge_status['status']['control_plane'] = cp_state.name
178 edge_status['status']['user_plane'] = up_state.name
179
180 report_aether_network_state()
Hyunsun Moon53097ea2020-09-04 17:20:29 -0700181 time.sleep(CONF.report_interval)
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700182
183
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700184if __name__ == "__main__":
185 main()