ath9k-hmac/hmac_python_wrapper/hmac_python_wrapper.py
2016-09-26 18:11:22 +02:00

263 lines
8.1 KiB
Python

import sys
import datetime
import time
import inspect
import subprocess
import zmq
"""
A hybrid TDMA CSMA MAC based on Atheros and ath9k wifi driver
"""
class HybridTDMACSMAMac():
def __init__(self, no_slots_in_superframe, slot_duration_ns):
#super(HybridTDMACSMAMac,self).__init__()
self.name = "hybridTDMACSMA"
self.desc = "works w/ ath9k"
self.mNo_slots_in_superframe = no_slots_in_superframe
self.mSlot_duration_ns = slot_duration_ns
self.acs = []
for ii in range(no_slots_in_superframe):
self.acs.append(None)
def getNumSlots(self):
return self.mNo_slots_in_superframe
def addAccessPolicy(self, slot_nr, ac):
self.acs[slot_nr] = ac
def getAccessPolicy(self, slot_nr):
return self.acs[slot_nr]
def getSlotDuration(self):
return self.mSlot_duration_ns
def printConfiguration(self):
s = '['
for ii in range(self.getNumSlots()):
s = s + str(ii) + ': ' + self.getAccessPolicy(ii).printConfiguration() + "\n"
s = s + ']'
return s
def install_mac_processor(self, interface, hybridMac):
print 'Function: installMacProcessor'
#self.log.info('margs = %s' % str(myargs))
# hybridMac = pickle.loads(mac_profile)
conf_str = None
for ii in range(hybridMac.getNumSlots()): # for each slot
ac = hybridMac.getAccessPolicy(ii)
entries = ac.getEntries()
for ll in range(len(entries)):
entry = entries[ll]
# slot_id, mac_addr, tid_mask
if conf_str is None:
conf_str = str(ii) + "," + str(entry[0]) + "," + str(entry[1])
else:
conf_str = conf_str + "#" + str(ii) + "," + str(entry[0]) + "," + str(entry[1])
# set-up executable here. note: it is platform-dependent
#exec_file = str(os.path.join(self.get_platform_path_hybrid_MAC())) + '/hybrid_tdma_csma_mac'
exec_file = 'hmac_userspace_daemon/hmac_userspace_daemon'
processArgs = str(exec_file) + " -d 0 " + " -i" +str(interface) + " -f" + str(hybridMac.getSlotDuration()) + " -n" + str(hybridMac.getNumSlots()) + " -c" + conf_str
print 'Calling hybrid mac executable w/ = ' + str(processArgs)
try:
# run as background process
subprocess.Popen(processArgs.split(), shell=False)
return True
except Exception as e:
fname = inspect.currentframe().f_code.co_name
print "An error occurred in " +str(fname) + " : " +str(e)
def update_mac_processor(self, interface, hybridMac):
print 'Function: updateMacProcessor'
#hybridMac = pickle.loads(mac_profile)
# generate configuration string
conf_str = None
for ii in range(hybridMac.getNumSlots()): # for each slot
ac = hybridMac.getAccessPolicy(ii)
entries = ac.getEntries()
for ll in range(len(entries)):
entry = entries[ll]
# slot_id, mac_addr, tid_mask
if conf_str is None:
conf_str = str(ii) + "," + str(entry[0]) + "," + str(entry[1])
else:
conf_str = conf_str + "#" + str(ii) + "," + str(entry[0]) + "," + str(entry[1])
# update MAC processor configuration
try:
# todo cache sockets!!!
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect("tcp://localhost:" + str("1217"))
socket.send(conf_str)
message = socket.recv()
print "Received reply from HMAC: " + str(message)
return True
except zmq.ZMQError as e:
fname = inspect.currentframe().f_code.co_name
print "An error occurred in " +str(fname) + " : " +str(e)
def uninstall_mac_processor(self, interface, hybridMac):
print 'Function: uninstallMacProcessor'
#hybridMac = pickle.loads(mac_profile)
# set allow all
# generate configuration string
conf_str = None
for ii in range(hybridMac.getNumSlots()): # for each slot
# slot_id, mac_addr, tid_mask
if conf_str is None:
conf_str = str(ii) + "," + 'FF:FF:FF:FF:FF:FF' + "," + str(255)
else:
conf_str = conf_str + "#" + str(ii) + "," + 'FF:FF:FF:FF:FF:FF' + "," + str(255)
# command string
terminate_str = 'TERMINATE'
# update MAC processor configuration
try:
# todo cache sockets!!!
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect("tcp://localhost:" + str("1217"))
#socket.connect("ipc:///tmp/localmacprocessor")
# (1) set new config
socket.send(conf_str)
message = socket.recv()
print "Received reply from HMAC: " + str(message)
# give one second to settle down
time.sleep(1)
# (2) terminate MAC
socket.send(terminate_str)
message = socket.recv()
print "Received reply from HMAC: " +str(message)
return True
except zmq.ZMQError as e:
fname = inspect.currentframe().f_code.co_name
print "An error occurred in " +str(fname) + " : " +str(e)
"""
AccessPolicy for each slot
"""
class AccessPolicy(object):
def __init__(self):
self.entries = []
def disableAll(self):
self.entries = []
def allowAll(self):
self.entries = []
self.entries.append(('FF:FF:FF:FF:FF:FF', 255))
def addDestMacAndTosValues(self, dstHwAddr, *tosArgs):
"""add destination mac address and list of ToS fields
:param dstHwAddr: destination mac address
:param tosArgs: list of ToS values to be allowed here
"""
tid_map = 0
for ii in range(len(tosArgs)):
# convert ToS into tid
tos = tosArgs[ii]
skb_prio = tos & 30 >> 1
tid =skb_prio & 7
tid_map = tid_map | 2**tid
self.entries.append((dstHwAddr, tid_map))
def getEntries(self):
return self.entries
def printConfiguration(self):
s = ''
for ii in range(len(self.entries)):
s = str(self.entries[ii][0]) + "/" + str(self.entries[ii][1]) + "," + s
return s
if __name__ == "__main__":
# hybrid MAC parameter
dstHWAddr = "34:13:e8:24:77:be" #node on which scheme should be applied, e.g. nuc15 interface sta1
total_slots = 10
slot_duration = 20000
iface = 'wlan0'
# create new MAC for local node
mac = HybridTDMACSMAMac(no_slots_in_superframe=total_slots, slot_duration_ns=slot_duration)
be_slots = [1,2,3,4]
# assign access policies to each slot in superframe
for slot_nr in range(total_slots):
if slot_nr in be_slots:
acBE = AccessPolicy()
acBE.addDestMacAndTosValues(dstHWAddr, 0)
mac.addAccessPolicy(slot_nr, acBE)
else:
acGuard = AccessPolicy()
acGuard.disableAll() # guard slot
mac.addAccessPolicy(slot_nr, acGuard)
# install MAC Processor
if mac.install_mac_processor(iface, mac):
print str(mac.printConfiguration())
time.sleep(10)
print "\nUpdating Hybrid MAC:"
mac = HybridTDMACSMAMac(no_slots_in_superframe=total_slots, slot_duration_ns=slot_duration)
be_slots = [5,6,7,8]
# assign access policies to each slot in superframe
for slot_nr in range(total_slots):
if slot_nr in be_slots:
acBE = AccessPolicy()
acBE.addDestMacAndTosValues(dstHWAddr, 0)
mac.addAccessPolicy(slot_nr, acBE)
else:
acGuard = AccessPolicy()
acGuard.disableAll() # guard slot
mac.addAccessPolicy(slot_nr, acGuard)
if mac.update_mac_processor(iface, mac):
print str(mac.printConfiguration())
time.sleep(15)
print "\nStopping Hybrid MAC:"
if mac.uninstall_mac_processor(iface, mac):
print str(mac.printConfiguration())