forked from wishful-project/examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwishful_handover_controller
executable file
·264 lines (202 loc) · 7.04 KB
/
wishful_handover_controller
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
wifi_handover_controller.py: A simple client load-balancing (handover) demo. Here 1-2 client STAs are
periodically handovered from one AP to another.
Req.:
- 2 APs,
- 1 GW node,
- 1-2 client STAs
Usage:
wifi_handover_controller.py [options] [-q | -v]
Options:
--logfile name Name of the logfile
--config configFile Config file path
Example:
./wifi_handover_controller -v
Other options:
-h, --help show this help message and exit
-q, --quiet print less text
-v, --verbose print more text
--version show version and exit
"""
import sys
import gevent
import logging
import wishful_controller
import wishful_upis as upis
import time
__author__ = "Piotr Gawlowicz, Anatolij Zubow"
__copyright__ = "Copyright (c) 2015, Technische Universitat Berlin"
__version__ = "0.1.0"
__email__ = "{gawlowicz, zubow}@tkn.tu-berlin.de"
log = logging.getLogger('wishful_agent.main')
controller = wishful_controller.Controller(dl="tcp://127.0.0.1:8990", ul="tcp://127.0.0.1:8989")
nodes = []
#
# Topology: 2x AP, 1x GW and 1-2 STAs
#
# AP0
node0_name = "nuc4"
node0_ip = "192.168.103.136"
node0_ch = 44
# AP1
node1_name = "nuc2"
node1_ip = "192.168.103.125"
node1_ch = 48
# Gateway node
gateway_name = "nuc1"
gateway_ip = "192.168.103.115"
# iface to use
wlan_iface = 'ap1'
wlan_inject_iface = 'inject1'
# BSSID of our Network
network_bssid = "D0:0E:A4:09:11:A3"
gateway = None
@controller.new_node_callback()
def new_node_cb(node):
nodes.append(node.id)
log.debug('NodeEnter: NodeID: ' % node)
if node.ip == gateway_ip:
gateway = node
@controller.node_exit_callback()
def exit_node_cb(node, reason):
if node.id in nodes:
nodes.remove(node.id)
log.debug("NodeExit : NodeID : %s Reason : %s" % (node.id, reason))
def runDualPeriodicSwitching(switchingInterval):
"""
Periodic handover of two client STAs
"""
sta1_mac_addr = "ec:1f:72:82:09:56"
sta1_ip = "192.168.5.222"
ho1_type = 0 #HandoverTypes.Soft_CSA
sta2_mac_addr = 'd0:22:be:b7:76:8c'
sta2_ip = "192.168.5.200"
ho2_type = 1 #HandoverTypes.Hard_BL
numSTAs = 2
while True:
# for each STA
for sta_ii in range(numSTAs):
if sta_ii == 0:
sta_mac_addr = sta1_mac_addr
sta_ip = sta1_ip
ho_type = ho1_type
else:
sta_mac_addr = sta2_mac_addr
sta_ip = sta2_ip
ho_type = ho2_type
log.info("Performing Handover OP ...")
performHO(sta_mac_addr, sta_ip, ho_type)
# reschedule handover
log.info("Handover successful")
time.sleep(switchingInterval) # wait
def runSinglePeriodicSwitching(ho_scheme, switching_interval = 30):
"""
Periodic handover of singe client STA
"""
sta_mac_addr = 'd0:22:be:b7:76:8c'
sta_ip = "192.168.5.200"
while True:
performHO(sta_mac_addr, sta_ip, ho_scheme)
time.sleep(switching_interval)
def performHO(sta_mac_addr, sta_ip, ho_scheme):
"""
perform handover
"""
try:
log.debug('********* testPerformHardHO **********')
# find out which AP is currently controlling this client STA
serving_AP = controller.wireless_topology.is_associated_with(nodes, wlan_iface, sta_mac_addr)
if str(serving_AP) == str(nodes[0]):
target_AP = nodes[1]
target_channel = node1_ch
serving_channel = node0_ch
serving_AP_ip = node0_ip
target_AP_ip = node1_ip
serving_AP_name = node0_name
target_AP_name = node1_name
elif str(serving_AP) == str(nodes[1]):
target_AP = nodes[0]
target_channel = node0_ch
serving_channel = node1_ch
serving_AP_ip = node1_ip
target_AP_ip = node0_ip
serving_AP_name = node1_name
target_AP_name = node0_name
else:
log.debug('STA is served by an unknown AP; backoff')
return
log.debug('Serving AP of %s is %s' % (str(sta_mac_addr), str(serving_AP_name)))
log.debug('Move STA %s from %s to %s' % (str(sta_mac_addr), str(serving_AP_name), str(target_AP_name)))
retVal = controller.handover.perform_handover(wlan_iface, serving_AP, target_AP, sta_mac_addr,
wlan_inject_iface = wlan_inject_iface, sta_ip = sta_ip,
servingAP_ip = serving_AP_ip, servingChannel = serving_channel,
network_bssid = network_bssid, targetAP_ip = target_AP_ip,
targetChannel = target_channel, gateway = gateway,
ho_type = ho_scheme)
log.debug('HO result %s' % (str(retVal)))
except Exception as e:
log.fatal("... An error occurred : %s" % e)
raise e
# possible scenarios
class HOScenarios:
SINGLE_HARD, SINGLE_SOFT, DOUBLE_HARD_SOFT = list(range(2))
def main(args):
log.debug(args)
controller.add_module(moduleName="handover", pyModuleName="wishful_module_handover",
className="HandoverModule", importAs="handover")
controller.start()
log.debug("waiting for nodes ...")
# wait until all nodes become available
while True:
gevent.sleep(1)
if len(nodes) == 3:
# we need two APs and a GW node
break
log.debug(" ... done: %s" % str(nodes))
mode = HOScenarios.SINGLE_SOFT
# in seconds
switchingInterval = 30
if mode == HOScenarios.DOUBLE_HARD_SOFT:
# two nodes are periodically switched
runDualPeriodicSwitching(switchingInterval)
elif mode == HOScenarios.SINGLE_SOFT:
# single node HO via soft
runSinglePeriodicSwitching(0, switchingInterval)
elif mode == HOScenarios.SINGLE_HARD:
# single node HO via hard
runSinglePeriodicSwitching(1, switchingInterval)
else:
log.fatal('Unknown scenario; stopping')
raise Exception("Unknown scenario")
log.info('Global controller stopped')
if __name__ == "__main__":
try:
from docopt import docopt
except:
print("""
Please install docopt using:
pip install docopt==0.6.1
For more refer to:
https://github.com/docopt/docopt
""")
raise
args = docopt(__doc__, version=__version__)
log_level = logging.INFO # default
if args['--verbose']:
log_level = logging.DEBUG
elif args['--quiet']:
log_level = logging.ERROR
logfile = None
if args['--logfile']:
logfile = args['--logfile']
logging.basicConfig(filename=logfile, level=log_level,
format='%(asctime)s - %(name)s.%(funcName)s() - %(levelname)s - %(message)s')
try:
main(args)
except KeyboardInterrupt:
log.debug("Controller exits")
finally:
log.debug("Exit")
controller.stop()