-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathconnMgr.py
175 lines (152 loc) · 6.73 KB
/
connMgr.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# Connection Manager
# This module is informed by the several state machines in case of good connection.
# It calculates an overall ConnectionLevel.
# This ConnectionLevel is provided to the state machines, so that each state machine
# has the possiblity to decide whether it needs to do something or just stays silent.
#
# The basic rule is, that a good connection on higher layer (e.g. TCP) implicitely
# confirms the good connection on lower layer (e.g. Modem presence). This means,
# the lower-layer state machine can stay silent as long as the upper layers are working
# fine.
from configmodule import getConfigValue, getConfigValueBool
import sys # For exit_on_session_end hack
CONNLEVEL_100_APPL_RUNNING = 100
CONNLEVEL_80_TCP_RUNNING = 80
CONNLEVEL_50_SDP_DONE = 50
CONNLEVEL_20_TWO_MODEMS_FOUND = 20
CONNLEVEL_15_SLAC_ONGOING = 15
CONNLEVEL_10_ONE_MODEM_FOUND = 10
CONNLEVEL_5_ETH_LINK_PRESENT = 5
CONNMGR_CYCLES_PER_SECOND = 33 # 33 cycles for one second, is 30ms call cycle
CONNMGR_TIMER_MAX = (5*33) # 5 seconds until an OkReport is forgotten.
CONNMGR_TIMER_MAX_10s = (10*33) # 10 seconds until an OkReport is forgotten.
CONNMGR_TIMER_MAX_15s = (15*33) # 15 seconds until an OkReport is forgotten.
CONNMGR_TIMER_MAX_20s = (20*33) # 20 seconds until an OkReport is forgotten.
class connMgr():
def getConnectionLevel(self):
return self.ConnectionLevel
def printDebugInfos(self):
s = "[CONNMGR] " + str(self.timerEthLink) + " " \
+ str(self.timerModemLocal) + " " \
+ str(self.timerModemRemote) + " " \
+ str(self.timerSlac) + " " \
+ str(self.timerSDP) + " " \
+ str(self.timerTCP) + " " \
+ str(self.timerAppl) + " " \
+ " --> " + str(self.ConnectionLevel)
self.addToTrace(s)
def __init__(self, callbackAddToTrace, callbackShowStatus):
self.timerEthLink = 0
self.timerModemLocal = 0
self.timerModemRemote = 0
self.timerSlac = 0
self.timerSDP = 0
self.timerTCP = 0
self.timerAppl = 0
self.ConnectionLevel = 0
self.ConnectionLevelOld = 0
self.cycles = 0
self.addToTrace = callbackAddToTrace
def mainfunction(self):
# shortcut: we do not check the ethernet link, instead, we assume it is just always present.
self.timerEthLink = 10
# count all the timers down
if (self.timerEthLink>0):
self.timerEthLink-=1
if (self.timerModemLocal>0):
self.timerModemLocal-=1
if (self.timerModemRemote>0):
self.timerModemRemote-=1
if (self.timerSlac>0):
self.timerSlac-=1
if (self.timerSDP>0):
self.timerSDP-=1
if (self.timerTCP>0):
self.timerTCP-=1
if (self.timerAppl>0):
self.timerAppl-=1
# Based on the timers, calculate the connectionLevel.
if (self.timerAppl>0):
self.ConnectionLevel=CONNLEVEL_100_APPL_RUNNING
else:
if (self.timerTCP>0):
self.ConnectionLevel=CONNLEVEL_80_TCP_RUNNING
else:
if (self.timerSDP>0):
self.ConnectionLevel=CONNLEVEL_50_SDP_DONE
else:
if (self.timerModemRemote>0):
self.ConnectionLevel=CONNLEVEL_20_TWO_MODEMS_FOUND
else:
if (self.timerSlac>0):
self.ConnectionLevel=CONNLEVEL_15_SLAC_ONGOING
else:
if (self.timerModemLocal>0):
self.ConnectionLevel=CONNLEVEL_10_ONE_MODEM_FOUND
else:
if (self.timerEthLink>0):
self.ConnectionLevel=CONNLEVEL_5_ETH_LINK_PRESENT
else:
self.ConnectionLevel=0
if (self.ConnectionLevelOld!=self.ConnectionLevel):
self.addToTrace("[CONNMGR] ConnectionLevel changed from " + str(self.ConnectionLevelOld) + " to " + str(self.ConnectionLevel))
if ((self.ConnectionLevelOld==100) and (self.ConnectionLevel<100)):
# We had a charging session, and now it is gone.
# Depending on configuration option, we may end the script here.
if getConfigValueBool("exit_on_session_end"):
# TODO: This is a hack. Do this in fsmPev instead?
self.addToTrace("[CONNMGR] Terminating the application.")
sys.exit(0)
self.ConnectionLevelOld = self.ConnectionLevel
if ((self.cycles % 33)==0):
# once per second
self.printDebugInfos()
self.cycles+=1
def ModemFinderOk(self, numberOfFoundModems):
if (numberOfFoundModems>=1):
self.timerModemLocal = CONNMGR_TIMER_MAX
if (numberOfFoundModems>=2):
self.timerModemRemote = CONNMGR_TIMER_MAX_10s # 10s for the slac sequence, to avoid too fast timeout
def SlacOk(self):
# The SetKey was sent to the local modem. This leads to restart of the
# local modem, and potenially also for the remote modem. If both modems are up,
# they need additional time to pair. We need to be patient during this process. */
self.timerSlac = CONNMGR_TIMER_MAX_20s
def SdpOk(self):
self.timerSDP = CONNMGR_TIMER_MAX
def TcpOk(self):
self.timerTCP = CONNMGR_TIMER_MAX_10s
def ApplOk(self, time_in_seconds=10):
# The application confirmed to have communication. It can decide, based on its state,
# how long the confirmation shall hold. Default is ten seconds.
self.timerAppl = time_in_seconds * CONNMGR_CYCLES_PER_SECOND
def testCallbackAddToTrace(s):
print("callbackAddToTrace: " + s)
def testCallbackShowStatus(s):
print("callbackShowStatus: " + s)
if __name__ == "__main__":
print("Testing ConnectionManager...")
cm = connMgr(testCallbackAddToTrace, testCallbackShowStatus)
print("connection level " + str(cm.getConnectionLevel()))
cm.mainfunction()
print("connection level " + str(cm.getConnectionLevel()))
cm.SlacOk()
cm.mainfunction()
print("connection level " + str(cm.getConnectionLevel()))
for i in range(1000):
cm.mainfunction()
cm.ModemFinderOk(1)
for i in range(1000):
cm.mainfunction()
cm.ModemFinderOk(2)
for i in range(1000):
cm.mainfunction()
cm.SdpOk()
for i in range(1000):
cm.mainfunction()
cm.TcpOk()
for i in range(1000):
cm.mainfunction()
cm.ApplOk()
for i in range(1000):
cm.mainfunction()