├── Components ├── __init__.py ├── powerModel.py ├── latencyModel.py ├── SDS_Host.py ├── config.py ├── contentLibrary.py ├── SDS_Station.py ├── SDS_Car_Switch.py ├── SDS_Switch.py ├── SDS_Car.py ├── SDS_eNodeB.py ├── SDS_C_Car.py ├── SDS_Controller.py ├── SDS_RSU.py └── SDS_VANET_Controller.py ├── .gitignore ├── D-SDCompute └── dsdcompute-experimental.py ├── SDStorage └── sdstorage-experimental.py ├── README.md └── SDCD └── sdcd-experimental.py /Components/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.csv 3 | .idea/* -------------------------------------------------------------------------------- /Components/powerModel.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/pyhton 2 | class powerModel(): 3 | pass 4 | -------------------------------------------------------------------------------- /D-SDCompute/dsdcompute-experimental.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append('../') 4 | from mininet.log import setLogLevel 5 | 6 | def topology(): 7 | print "Decentralized Software Defined Computing at the edge of the Network" 8 | print "--------------------------------------------------------------------" 9 | 10 | if __name__ == '__main__': 11 | setLogLevel('debug') 12 | topology() 13 | -------------------------------------------------------------------------------- /Components/latencyModel.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/pyhton 2 | 3 | class latencyModel(): 4 | """This should facilitate the latency cost of SD Network Operations""" 5 | @staticmethod 6 | def fileTransferLatency(size): 7 | # TODO: replace with a scientific real equation 8 | return (size/1000)*0.0000018 9 | @staticmethod 10 | def nextHopLatency(): 11 | # latency per Hub jump 12 | return 0.03 13 | @staticmethod 14 | def searchPenality(): 15 | """search peneality in the same MEC node""" 16 | return 0.0001 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Components/SDS_Host.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os 4 | from mininet.node import Host 5 | #from FunctionTable import * 6 | from Components.contentLibrary import contentLibrary 7 | from .config import Type 8 | 9 | class Cloud_Host(Host): 10 | 11 | "Host Storage where other hosts can store the data inside it " 12 | 13 | def __init__(self, name, custom_type=Type.SD_CLOUD_HOST, NO_of_Dir=10, NO_of_files=20, file_size=5, Used_space=0, **pars): 14 | Host.__init__(self, name, **pars) 15 | self.NO_of_files = NO_of_files 16 | self.NO_of_Dir = NO_of_Dir 17 | self.file_size = file_size 18 | self.Used_space = Used_space 19 | self.custom_type = custom_type 20 | """AR Content""" 21 | self.cLibrary = contentLibrary() 22 | 23 | print ("Cloud host has been initialized") 24 | -------------------------------------------------------------------------------- /Components/config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/pyhton 2 | 3 | """ CUSTOM TYPES """ 4 | # Constants describing custom types 5 | class Type(): 6 | """Constants describing custom types""" 7 | SD_CAR = "sd_car" 8 | SD_C_CAR = "sd_c_car" 9 | SD_CAR_SWITCH = "sd_car_switch" 10 | SD_SWITCH = "sd_switch" 11 | SD_E_NODEB = "sd_eNodeB" 12 | SD_CLOUD_HOST = "sd_cloudHost" 13 | SD_RSU = "sd_rsu" 14 | SD_STATION = "sd_station" 15 | SD_VANET_CONTROLLER = "vanet_controller" 16 | SD_STORAGE_CONTROLLER = "storage_controller" 17 | 18 | #MININET-WIFI Constants 19 | HOST = "host" 20 | STATION = "station" 21 | SWITCH = "switch" 22 | ACCESSPOINT = "ap" 23 | VEHICLE = "vehicle" 24 | 25 | 26 | class Modes(): 27 | """MODES of EXPERIMENTS """ 28 | MEC = 1 29 | CONTENT_DELIVERY = 2 30 | 31 | class Operations(): 32 | """ OPERATION TYPES""" 33 | MEC = 1 34 | CONTENT_DELIVERY = 2 35 | -------------------------------------------------------------------------------- /Components/contentLibrary.py: -------------------------------------------------------------------------------- 1 | def contentLibrary(): 2 | cLib = []; 3 | #[content_identifier,content_name,content_size] 4 | content = [1, "CityAR.fbx", 5000] 5 | cLib.append(content) 6 | content = [2, "CarAR.obj", 9000] 7 | cLib.append(content) 8 | content = [3, "StreetAR.fbx", 3000] 9 | cLib.append(content) 10 | content = [4, "HeritageAR.jpg", 850] 11 | cLib.append(content) 12 | content = [5, "MallAR.fbx", 5000] 13 | cLib.append(content) 14 | content = [6, "statueAR.obj", 9000] 15 | cLib.append(content) 16 | content = [7, "StAR.fbx", 3000] 17 | cLib.append(content) 18 | content = [8, "HallAR.jpg", 850] 19 | cLib.append(content) 20 | content = [9, "shopAR.fbx", 3500] 21 | cLib.append(content) 22 | content = [10, "DinasorAR.obj", 8650] 23 | cLib.append(content) 24 | 25 | return cLib 26 | -------------------------------------------------------------------------------- /Components/SDS_Station.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/pyhton 2 | 3 | from mininet.wifi.node import Station 4 | from .config import Modes, Type 5 | 6 | 7 | class SDStorage_Station(Station): 8 | "Storage Station is a host that operates with a wireless interface card" 9 | 10 | def __init__(self, name, custom_type=Type.SD_STATION, NO_of_Dir=0, NO_of_files=0, file_size=0, Used_space=0, **pars): 11 | Station.__init__(self, name, **pars) 12 | self.NO_of_files = NO_of_files 13 | self.NO_of_Dir = NO_of_Dir 14 | self.file_size = file_size 15 | self.Used_space = Used_space 16 | self.custom_type = custom_type 17 | 18 | # print ("Custom station has been initialized") 19 | 20 | def requestContents(self, content_identifier, mode, net): 21 | if (mode == Modes.MEC): 22 | """MEC SEARCH""" 23 | """getting accessPoint the station is associated to""" 24 | ap = self.params['associatedTo'][0] 25 | 26 | # request AR content from associated accessPoint first 27 | index = 0 28 | for accessPoint in net.aps: 29 | if (accessPoint.params['mac'] == ap.params['mac']): 30 | result = net.aps[index].handleContentRequest( 31 | content_identifier, net) 32 | # print ("result in station: %s"%result) 33 | break 34 | else: 35 | index += 1 36 | 37 | # print ("AP[%s] returned %s for the requested AR content"%(index,result)) 38 | return result 39 | 40 | else: 41 | """SD Search""" 42 | -------------------------------------------------------------------------------- /Components/SDS_Car_Switch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import sys 4 | from mininet.node import OVSKernelSwitch 5 | from operator import itemgetter 6 | from .config import Type,Operations,Modes 7 | 8 | 9 | # guppy: actual memory consumption 10 | 11 | 12 | class SD_Car_Switch(OVSKernelSwitch): 13 | "Switch to connect different types of storage hosts like StorageHost" 14 | 15 | def __init__(self, name, custom_type=Type.SD_CAR_SWITCH, **pars): 16 | OVSKernelSwitch.__init__(self, name, **pars) 17 | print ("custom swtich has been initialized") 18 | self.Function_table = [] 19 | self.counter = 0 20 | self.custom_type = custom_type 21 | self.MEC = [] 22 | """AR Content""" 23 | self.AR_Library = [] 24 | 25 | def update_AR(self, msg): 26 | self.MEC = [] 27 | for attrib in range(len(msg) - 1): 28 | self.MEC.append(msg[attrib]) 29 | self.AR_Library.append(msg[len(msg) - 1]) 30 | 31 | def Handle_controller_packets(self, operation, message): 32 | packetstatus = operation 33 | SDSObject = message 34 | if (packetstatus == Operations.CONTENT_DELIVERY): 35 | self.update_AR(SDSObject) 36 | 37 | def sendMsg_toCon(self, status, Used_space, HostID, net): 38 | " Send a message to the controller to notify it with any change" 39 | if status == "Add": 40 | network = net.controllers[0].Handle_switch_packets( 41 | "Add", None, None, net) 42 | return network 43 | elif status == "Update": 44 | net.controllers[0].Handle_switch_packets( 45 | "Update", Used_space, HostID, net) 46 | 47 | def print_switch_info(self, mode, net): 48 | if (mode == Modes.CONTENT_DELIVERY): 49 | print ( 50 | "[MAC Address]\t{AR Library} \n ***************************") 51 | for sw in net.switches: 52 | if (sw.custom_type != "sd_car_switch"): 53 | continue 54 | print ("%s \t " % sw.MEC[0]) 55 | count = 0 56 | for AR in sw.AR_Library: 57 | for i in range(len(AR)): 58 | print ("content: %s" % (AR[i])) 59 | count += 1 60 | print ("------") 61 | -------------------------------------------------------------------------------- /Components/SDS_Switch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from operator import itemgetter 4 | 5 | from mininet.node import OVSKernelSwitch 6 | from .config import Operations, Type 7 | 8 | 9 | # guppy: actual memory consumption 10 | 11 | class SDStor_Switch(OVSKernelSwitch): 12 | "Switch to connect different types of storage hosts like StorageHost" 13 | 14 | def __init__(self, name, custom_type=Type.SD_SWITCH, **pars): 15 | OVSKernelSwitch.__init__(self, name, **pars) 16 | print ("custom swtich has been initialized") 17 | self.Function_table = [] 18 | self.counter = 0 19 | self.custom_type = custom_type 20 | self.MEC = [] 21 | """Content""" 22 | self.cLibrary = [] 23 | 24 | def insert_entry(self, SDSObject): 25 | self.Function_table.append([]) 26 | for index in range(len(SDSObject)): 27 | self.Function_table[self.counter].append(SDSObject[index]) 28 | 29 | L = sorted(self.Function_table, key=itemgetter(4), reverse=True) 30 | self.Function_table = L 31 | self.counter += 1 32 | 33 | def update_AR(self, msg): 34 | self.MEC = [] 35 | for attrib in range(len(msg) - 1): 36 | self.MEC.append(msg[attrib]) 37 | # print ("attrib %s -> %s"%(attrib,self.MEC[attrib])) 38 | self.cLibrary.append(msg[len(msg) - 1]) 39 | 40 | def update_entry(self, SDSObject): 41 | HostIP = SDSObject[0] 42 | index = 0 43 | # print len(self.Function_table) 44 | while (index < len(self.Function_table)): 45 | 46 | if (HostIP == self.Function_table[index][0]): 47 | self.Function_table[index][1] = SDSObject[1] 48 | self.Function_table[index][2] = SDSObject[2] 49 | self.Function_table[index][3] = SDSObject[3] 50 | self.Function_table[index][4] = SDSObject[4] 51 | 52 | # L=sorted(self.Function_table,key=itemgetter(4),reverse=True) 53 | # self.Function_table=L 54 | 55 | # print self.Function_table 56 | break 57 | index += 1 58 | 59 | def remove_entry(self, SDSObject): 60 | HostIP = SDSObject[0] 61 | index = 0 62 | while index < len(self.Function_table): 63 | if (HostIP == self.Function_table[index][0]): 64 | self.Function_table.pop(index) 65 | break 66 | sorted(self.Function_table, key=itemgetter(4)) 67 | 68 | def Handle_controller_packets(self, operation, message): 69 | " Get a message from the controller and handle it." 70 | packetstatus = operation 71 | SDSObject = message 72 | 73 | if packetstatus == "Add": 74 | self.insert_entry(SDSObject) 75 | elif packetstatus == "Update": 76 | self.update_entry(SDSObject) 77 | elif (packetstatus == Operations.CONTENT_DELIVERY): 78 | self.update_AR(SDSObject) 79 | else: 80 | self.remove_entry(SDSObject) 81 | 82 | def sendMsg_toCon(self, status, Used_space, HostID, net): 83 | " Send a message to the controller to notify it with any change" 84 | if status == "Add": 85 | network = net.controllers[0].Handle_switch_packets( 86 | "Add", None, None, net) 87 | return network 88 | elif status == "Update": 89 | net.controllers[0].Handle_switch_packets( 90 | "Update", Used_space, HostID, net) 91 | 92 | def sendMesg_toHost(message): 93 | pass 94 | # send a message to the host 95 | 96 | def store_data(data): 97 | pass 98 | # Store the data on the underling storage hosts. 99 | -------------------------------------------------------------------------------- /SDStorage/sdstorage-experimental.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | Veicular Ad Hoc Networks - VANETs 5 | 6 | """ 7 | import os 8 | import sys 9 | 10 | from mininet.wifi.net import Mininet_wifi 11 | from mininet.wifi.link import wmediumd 12 | sys.path.append('../') 13 | from mininet.link import TCLink 14 | from mininet.cli import CLI 15 | from mininet.log import setLogLevel 16 | import random 17 | import time 18 | from Components.SDS_RSU import SD_RSU 19 | from Components.SDS_VANET_Controller import SDVanet_Controller 20 | from Components.SDS_Switch import SDStor_Switch 21 | from Components.SDS_Car import SD_Car 22 | from Components.SDS_Station import SDStorage_Station 23 | from Components.config import Modes 24 | import pdb 25 | 26 | RSU = SD_RSU 27 | VANET_Controller = SDVanet_Controller 28 | SD_Switch = SDStor_Switch 29 | SD_station = SDStorage_Station 30 | 31 | def topology(): 32 | 33 | "Create a network." 34 | net = Mininet_wifi(controller=VANET_Controller, link=wmediumd, 35 | switch=SD_Switch, station=SD_station, enable_interference=True) 36 | 37 | print ("*** Creating nodes") 38 | car = [] 39 | stas = [] 40 | mec = [] 41 | channel = ['1','6','11'] 42 | NUM_OF_MECS = 4 43 | for x in range(0, 5): 44 | car.append(x) 45 | stas.append(x) 46 | for x in range(0, 5): 47 | min = random.randint(1,10) 48 | max= random.randint(11,30) 49 | car[x] = net.addCar('car%s' % (x+1), wlans=1, ip='10.0.0.%s/8' % (x + 1), min_speed=min, max_speed=max,cls=SD_Car) 50 | 51 | c = 0 52 | for m in range(0, NUM_OF_MECS): 53 | mec.append(m) 54 | for m in range(0,NUM_OF_MECS): 55 | #print "Counter of mecs is %s "%m 56 | if((m+1) % 3 == 0): 57 | c=0 58 | mec[m] = net.addAccessPoint('MEC%s' % (m+1), ssid= 'RSU%s' % (m+1), mode= 'g', channel= channel[c], range=100 ,cls=RSU) 59 | c += 1 60 | 61 | c1 = net.addController( 'c1', controller=VANET_Controller ) 62 | 63 | 64 | def SDStorage(datasize): 65 | start2 = time.time() 66 | datasize = int(datasize) 67 | print ("car %s want to store %s bytes" % (0, datasize)) 68 | car[0].store(datasize,Modes.MEC, net) 69 | end2 = time.time() 70 | with open('Storage.txt', 'a') as f: 71 | f.write('%.12f \n' % (end2-start2)) 72 | print ("took : ", end2 - start2) 73 | 74 | print ("*** Configuring wifi nodes") 75 | net.configureWifiNodes() 76 | 77 | #net.meshRouting('custom') 78 | 79 | print ("*** Associating and Creating links") 80 | for m in range(0, NUM_OF_MECS): 81 | if(m < (NUM_OF_MECS-1)): 82 | net.addLink(mec[m],mec[m+1]) 83 | else: 84 | net.addLink(mec[0],mec[m]) 85 | 86 | 87 | """uncomment to plot graph""" 88 | net.plotGraph(max_x=700, max_y=700) 89 | 90 | """Number of Roads""" 91 | net.roads(10) 92 | 93 | """Start Mobility""" 94 | net.startMobility(time=0) 95 | 96 | print ("*** Starting network") 97 | net.build() 98 | c1.start() 99 | 100 | c1.initializeNetworkResources(net) 101 | print ("Draw 10 roads and place the 4 MEC nodes along them?") 102 | print ("\n\n\n***************************START*******************************") 103 | datasize = raw_input("What is the amount of storage you want (in bytes)") 104 | SDStorage(datasize) 105 | print ("\n\n\n***************************END*******************************") 106 | print ("(MEC) info Table after the test") 107 | net.aps[0].listMecContents(Modes.MEC, net) 108 | print ("*** Running CLI") 109 | CLI( net ) 110 | 111 | print ("*** Stopping network") 112 | net.stop() 113 | 114 | if __name__ == '__main__': 115 | setLogLevel( 'info' ) 116 | topology() 117 | -------------------------------------------------------------------------------- /Components/SDS_Car.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/pyhton 2 | 3 | import os 4 | from mininet.wifi.node import Car 5 | import time 6 | from .config import Modes,Type 7 | 8 | 9 | class SD_Car(Car): 10 | "Storage Station is a host that operates with a wireless interface card" 11 | 12 | def __init__(self, name, custom_type=Type.SD_CAR, NO_of_Dir=0, NO_of_files=0, file_size=0, Used_space=0, **pars): 13 | Car.__init__(self, name, **pars) 14 | self.NO_of_files = NO_of_files 15 | self.NO_of_Dir = NO_of_Dir 16 | self.file_size = file_size 17 | self.Used_space = Used_space 18 | self.custom_type = custom_type 19 | 20 | def RequestContent(self, net, op=1): 21 | print ("\tcontent \t|\t Time \t\t| Status") 22 | print ("-----------\t|\t ----------\t| ----------") 23 | for i in range(1, 11): 24 | start3 = time.time() 25 | result = self.escalateRequest(i, Modes.MEC, net, op) 26 | if (result): 27 | result = "Found" 28 | else: 29 | result = "Not Found" 30 | 31 | if(op != 1): 32 | # TODO: this was added to emulate the latency for transfering the content to the other car 33 | time.sleep(0.03) 34 | end3 = time.time() 35 | with open('v2v.csv', 'a') as f: 36 | f.write('%s,%.12f \n' % (i, end3 - start3)) 37 | else: 38 | end3 = time.time() 39 | with open('v2i.csv', 'a') as f: 40 | f.write('%s,%.12f \n' % (i, end3 - start3)) 41 | 42 | print (" %s \t \t \t %.12f \t%s" % (i, end3 - start3, result)) 43 | 44 | def getAssociatedAP(self): 45 | result = self.cmd('iw dev %s-wlan0 link'%self.name) 46 | if(result != 'Not Connected'): 47 | mac_address = result.split()[2] 48 | return mac_address 49 | else: 50 | raise ValueError("Vehicle is not connected") 51 | 52 | 53 | def getExternalIP(self): 54 | result = self.cmd('ifconfig %s | grep "inet addr"'%self.params['wlan'][0]) 55 | ip_address = result.split()[1].split(':')[1] 56 | return ip_address 57 | 58 | def decodeRXResults(self): 59 | receiverLog = '%s-receiver.log'%self.name 60 | self.cmdPrint("ITGDec %s"%receiverLog) 61 | 62 | 63 | def escalateRequest(self, content_identifier, mode, net, op): 64 | if (mode == Modes.MEC): 65 | """getting accessPoint the station is associated to""" 66 | ap = self.params['associatedTo'][0] 67 | index = 0 68 | for accessPoint in net.aps: 69 | if(op == 1): 70 | if (accessPoint.params['mac'] == ap.params['mac']): 71 | result = net.aps[index].handleContentRequest( 72 | content_identifier, net) 73 | break 74 | else: 75 | index += 1 76 | else: # v2v (bgscan enabled) 77 | if (self.getAssociatedAP() in accessPoint.params['mac']): 78 | result = net.aps[index].handleContentRequest( 79 | content_identifier, net) 80 | break 81 | else: 82 | index += 1 83 | 84 | return result 85 | 86 | else: 87 | """SD Search""" 88 | def store(self, datasize, mode, net): 89 | if (mode == Modes.MEC): 90 | """MEC OPERATIONS""" 91 | # get the accessPoint the station is attached to 92 | for wlan in range(0, len(self.params['wlan'])): 93 | ap = self.params['associatedTo'][0] 94 | print ("Associated RSU is: %s with mac: %s" % (ap, ap.params['mac'])) 95 | break 96 | index = 0 97 | # search if the accesspoint 98 | for accessPoint in net.aps: 99 | if (accessPoint.custom_type == Type.SD_SWITCH): 100 | continue 101 | if (accessPoint.params['mac'] == accessPoint.params['mac']): 102 | net.aps[index].store_data(datasize, net) 103 | print ("an accessPoint found index %s" % index) 104 | break 105 | else: 106 | index += 1 107 | # print "Total number of searched aps are: %s"%(index+1) 108 | # TODO: add v2v storage mode 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SDS-Mininet-WiFi 2 | Software Defined Systems support Extension for Mininet-WiFi Emulator 3 | 4 | ### What is this repository for? ### 5 | 6 | * Quick summary 7 | * Systems Support 8 | 9 | This repo holds the outcome of the collaborative work on supporting software defined systems as an extension to the well-known Network SDN Emulator Mininet-wifi. 10 | 11 | The list of supported systems are as follows: 12 | 13 | 1. VANET-based Software Defined Content Delivery Systems for cooperative mobile Edge Computing 14 | 2. [Software Defined Storage for Cooperative Mobile Edge Computing Systems.](https://www.researchgate.net/publication/317421285_Software_Defined_Storage_for_cooperative_Mobile_Edge_Computing_systems) 15 | 16 | Cite @ [SDStorage, J.Albadarneh et.al](http://ieeexplore.ieee.org/document/7939160/) 17 | 18 | 19 | 20 | ### How do I get set up? ### 21 | 22 | * Summary of set up 23 | 24 | There is no special configurations required to run the system, all you've to do is to clone the repo and cd into the system directory (ex. SDCD) and run the experiment. 25 | * Configuration 26 | 27 | - you've to follow the configuration required by Mininet-WiFi 28 | * Dependencies 29 | 30 | As stated in the description, the proposed systems support works as an extension to mininet wifi. so you should have mininet-wifi installed inside your machine. 31 | you'll need: 32 | - Mininet-wifi (latest version) can be cloned at: [Mininet-WiFi](https://github.com/intrig-unicamp/mininet-wifi) 33 | - SUMO Urban simulator version >= 0.28.0 34 | - Distributed Internet Traffic Generator (D-ITG) (latest version) can be found at: [D-ITG](http://traffic.comics.unina.it/software/ITG/download.php) 35 | - octave (latest version), can be found at: [Octave](http://www.octave.org/) 36 | - Both Storage and Content Delivery Experimetns requires `Python2.7` 37 | - ~~any future dependencies will be added here~~ 38 | * How to run tests 39 | 40 | In order to run the experiments, follow these instructions: 41 | 42 | 1) for V-SDCD, navigate to the system directory (SDCD): 43 | `cd SDCD` then run the experiment via `sudo python2.7 sdcd_experimental.py`. 44 | - The terminal will guide you to choose your experiment. 45 | - The Map files are hosted inside Mininet-WiFi. Once you have it installed, Mininet environment variables will be able to locate the files and grab them. 46 | They can be found [here](https://github.com/intrig-unicamp/mininet-wifi/blob/master/mininet/sumo/data/new-york.rou.xml) 47 | 48 | 2) for SDStorage experiment, navigate to system directory (SDStorage): 49 | `cd SDStorage` then run the experiment via `sudo python2.7 sdstorage_experimental.py` 50 | - Right after initializing the environemnt, a plot will be shown asking for drawing some roads for the cars. (10 roads - 4 mec nodes - 5 cars). Draw roads as connected points, and then place the mec nodes among those roads. After placing the last MEC node, the cars will be placed on the roads with random positions and speeds. 51 | > please note that, for you to be able to run the experiments properly, you need to wait for car1 to be connected to one of the mec node. -a nice tip here is to place the MEC nodes near to each other-. 52 | 53 | - Once `car1` is in range of any MEC node, enter the amount of storage units the car is willing to store. Note that Each MEC node is set to have a predefined capacity of 125000 storage units. As specified in the study, auto-scaling storage capacity for MEC nodes will be triggered on-demand. 54 | 55 | * If you encountered problems with your wifi-drivers which might stops the nodes from getting connected to the experiment basestations, you need to stop your network manager and use __wpa_supplicant__ to retain your interenet connection which is needed to load the simulation environment map. 56 | 57 | ### Having some troubles!! ### 58 | Don't hesitiate and go ahead submit your PRs 59 | 60 | ### Who do I talk to? ### 61 | 62 | * Repo owner or admin (Jafar Albadarneh) 63 | 64 | Collaborators 65 | --- 66 | - __Jafar albadarneh__, _Email_: jafar92.jaa@gmail.com, Jordan University of Science and Technology 67 | - __Yaser Jararweh__, _Email_:yaser.amd@gmail.com, Carnegie Mellon University 68 | - __Mahmoud Alayyoub__, _Email_:maalshbool@just.edu.jo, Jordan University of Science and Technology 69 | - __Mohammad Alsmadi__, _Email_:maalsmadi9@just.edu.jo, Jordan University of Science and Technology 70 | - __Ramon Fontes__, _Email_:ramonrf@dca.fee.unicamp.br, University of Campinas, Campinas, Brazil 71 | - __Christian Rothenberg__, _Email_:chesteve@dca.fee.unicamp.br ,University of Campinas, Campinas, Brazil 72 | -------------------------------------------------------------------------------- /Components/SDS_eNodeB.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from mininet.wifi.node import UserAP 3 | from operator import itemgetter 4 | import time 5 | from .config import Modes,Operations,Type 6 | 7 | 8 | class SD_eNodeB (UserAP): 9 | "custom AccessPoint to support SDSecure Storage" 10 | 11 | def __init__(self, name, custom_type=Type.SD_E_NODEB, NO_of_Dir=100, NO_of_files=50, file_size=25, NO_of_RACKS=1, Used_space=0, **pars): 12 | UserAP.__init__(self, name, **pars) 13 | """MEC Attributes""" 14 | self.NO_of_Dir = NO_of_Dir 15 | self.NO_of_files = NO_of_files 16 | self.file_size = file_size 17 | self.Used_space = Used_space 18 | self.NO_of_RACKS = NO_of_RACKS 19 | self.custom_type = custom_type 20 | self.MEC = [] 21 | """""" 22 | 23 | """ Content""" 24 | self.cLibrary = [] 25 | 26 | """""" 27 | self.Function_table = [] 28 | self.counter = 0 29 | 30 | def handleControllerUpdateRequest(self, operation, SDSObject): 31 | if(operation == Operations.MEC): 32 | self.initializeMecContents(SDSObject) 33 | 34 | def initializeMecContents(self, msg): 35 | self.MEC = [] 36 | for attrib in range(len(msg) - 1): 37 | self.MEC.append(msg[attrib]) 38 | self.cLibrary.append(msg[len(msg) - 1]) 39 | 40 | def listMecContents(self, mode, net): 41 | if(mode == Modes.CONTENT_DELIVERY): 42 | print ( 43 | "[MAC Address]\t{AR Library} \n ***************************") 44 | for ap in net.aps: 45 | if (ap.custom_type == Type.SD_SWITCH): 46 | continue 47 | print ("%s \t " % ap.MEC[0]) 48 | count = 0 49 | for c in ap.cLibrary: 50 | for i in range(len(c)): 51 | print ("content: %s" % (c[i])) 52 | count += 1 53 | print ("------") 54 | 55 | def sendMsgToController(self, operation, data, sta_IP, mac_id, net): 56 | if(operation == Operations.CONTENT_DELIVERY): 57 | res = net.controllers[0].Handle_AP_message( 58 | Operations.CONTENT_DELIVERY, data, None, mac_id, net) 59 | return res 60 | 61 | def handleContentRequest(self, contentIdentifier, net): 62 | found = False 63 | for AR_content in self.cLibrary: 64 | for c in AR_content: 65 | #print ("AR identifier inside AP is %s holding %s and passed identifier is %s "%(c[0],c[1],content_identifier)) 66 | if(c[0] == contentIdentifier): 67 | # print "AR content found locally" 68 | # Consider file size when applying latency 69 | sleep_time = (c[0 + 2] / 1000) * 0.0000018 70 | time.sleep(sleep_time) 71 | found = True 72 | else: 73 | # search peneality in the same MEC node 74 | time.sleep(0.0001) 75 | if(found): 76 | break 77 | if(not found): 78 | # ask the controller to search another MEC node 79 | A_MEC_mac_address = self.MEC[0] 80 | res = self.sendMsgToController( 81 | Operations.CONTENT_DELIVERY, contentIdentifier, None, A_MEC_mac_address, net) 82 | #print ("result in accessPoint(CO MEC): %s"%res) 83 | return res 84 | #print ("result in accesspoint(Local MEC): %s"%found) 85 | return found 86 | 87 | def sendTrafficToCar(self,car,numberOfKiloBytes = 1024): 88 | carIP = car.getExternalIP() 89 | interface = car.params['wlan'][0] 90 | """ activate ITG-Recieve Listener inside car """ 91 | car.cmdPrint("ITGRecv &") 92 | 93 | """ send traffic from accessPoint """ 94 | protocol = 'UDP' 95 | generationDuration = 150 # -t 96 | numOfkilobytes = numberOfKiloBytes # -r 97 | numberofPackets = None # -z 98 | # when -z,-t,-k selected, the most constructive will be applied 99 | packetSize = 10 # -c 100 | senderLogFile = '%s-sender.log'%self.name 101 | receiverLogFile = '%s-receiver.log'%car.name 102 | 103 | self.cmdPrint("sudo ITGSend " 104 | "-T %s " # protocol 105 | "-a %s " # destination IP 106 | "-k %s " # number of kilobytes 107 | "-t %s " # generation duration 108 | "-l %s " # sender log 109 | "-x %s" # receiver log 110 | %(protocol,carIP,numOfkilobytes,generationDuration,senderLogFile,receiverLogFile)) 111 | -------------------------------------------------------------------------------- /Components/SDS_C_Car.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/pyhton 2 | 3 | import os 4 | from mininet.wifi.node import Car 5 | import time 6 | from .config import Modes,Type 7 | from .latencyModel import latencyModel 8 | 9 | 10 | class SD_C_Car(Car): 11 | "Storage Station is a host that operates with a wireless interface card" 12 | 13 | def __init__(self, name, custom_type=Type.SD_C_CAR, NO_of_Dir=0, NO_of_files=0, file_size=0, Used_space=0, **pars): 14 | Car.__init__(self, name, **pars) 15 | self.NO_of_files = NO_of_files 16 | self.NO_of_Dir = NO_of_Dir 17 | self.file_size = file_size 18 | self.Used_space = Used_space 19 | self.custom_type = custom_type 20 | 21 | # TODO: Caching contents should be dynamic 22 | """Cached AR Content""" 23 | self.cLibrary = [] 24 | # [content_identifier,content_name,content_size] 25 | content = [1, "City.fbx", 5000] 26 | self.cLibrary.append(content) 27 | content = [2, "Car.obj", 9000] 28 | self.cLibrary.append(content) 29 | content = [3, "Street.fbx", 3000] 30 | self.cLibrary.append(content) 31 | content = [4, "Heritage.jpg", 850] 32 | self.cLibrary.append(content) 33 | content = [5, "Mall.fbx", 5000] 34 | self.cLibrary.append(content) 35 | content = [6, "statue.obj", 9000] 36 | self.cLibrary.append(content) 37 | content = [7, "Sta.fbx", 3000] 38 | self.cLibrary.append(content) 39 | content = [8, "Hall.jpg", 850] 40 | self.cLibrary.append(content) 41 | 42 | 43 | def RequestContent(self, net, op=1): 44 | print ("\nAR content \t|\t Time \t\t| Status") 45 | print ("-----------\t|\t ----------\t| ----------") 46 | for i in range(1, 11): 47 | start3 = time.time() 48 | if (self.foundIncache(i)): 49 | result = "Found/cache" 50 | else: 51 | result = self.escalateRequest(i, Modes.MEC, net, op) 52 | if (result): 53 | result = "Found" 54 | else: 55 | result = "Not Found" 56 | 57 | if (op != 1): 58 | # TODO: this was added to emulate the latency for transfering the content to the other car 59 | time.sleep(0.03) 60 | end3 = time.time() 61 | with open('v2v.csv', 'a') as f: 62 | f.write('%s,%.12f \n' % (i, end3 - start3)) 63 | else: 64 | end3 = time.time() 65 | with open('v2i.csv', 'a') as f: 66 | f.write('%s,%.12f \n' % (i, end3 - start3)) 67 | 68 | print (" %s \t \t \t %.12f \t%s" % (i, end3 - start3, result)) 69 | 70 | def getAssociatedAP(self): 71 | result = self.cmd('iw dev %s-wlan0 link'%self.name) 72 | if(result != 'Not Connected'): 73 | mac_address = result.split()[2] 74 | return mac_address 75 | else: 76 | raise ValueError("Vehicle is not connected") 77 | 78 | 79 | def getExternalIP(self): 80 | result = self.cmd('ifconfig %s | grep "inet addr"'%self.params['wlan'][0]) 81 | ip_address = result.split()[1].split(':')[1] 82 | return ip_address 83 | 84 | def decodeRXResults(self): 85 | receiverLog = '%s-receiver.log'%self.name 86 | self.cmdPrint("ITGDec %s"%receiverLog) 87 | 88 | def escalateRequest(self, content_identifier, mode, net, op): 89 | if (mode == Modes.MEC): 90 | """getting accessPoint the station is associated to""" 91 | ap = self.params['associatedTo'][0] 92 | index = 0 93 | for accessPoint in net.aps: 94 | if (op == 1): 95 | if (accessPoint.params['mac'] == ap.params['mac']): 96 | result = net.aps[index].handleContentRequest( 97 | content_identifier, net) 98 | break 99 | else: 100 | index += 1 101 | else: # v2v (bgscan enabled) 102 | if (self.getAssociatedAP() in accessPoint.params[ 103 | 'mac']): 104 | result = net.aps[index].handleContentRequest( 105 | content_identifier, net) 106 | break 107 | else: 108 | index += 1 109 | 110 | return result 111 | 112 | else: 113 | """other modes""" 114 | 115 | def foundIncache(self, content_identifier): 116 | found = False 117 | for content in self.cLibrary: 118 | #print ("the content is: %s " % content[1]) 119 | if (content[0] == content_identifier): 120 | sleep_time = latencyModel.fileTransferLatency(content[2]) 121 | time.sleep(sleep_time) 122 | found = True 123 | else: 124 | # cache search peneality in the same car 125 | time.sleep(latencyModel.searchPenality()) 126 | pass 127 | 128 | if (found): 129 | break 130 | return found 131 | -------------------------------------------------------------------------------- /SDCD/sdcd-experimental.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os 4 | import sys 5 | 6 | from mininet.wifi.net import Mininet_wifi 7 | from mininet.wifi.link import wmediumd, mesh 8 | from mininet.wifi.cli import CLI_wifi 9 | 10 | sys.path.append('../') 11 | 12 | from time import sleep 13 | 14 | from Components.SDS_C_Car import SD_C_Car 15 | from Components.SDS_Car import SD_Car 16 | # SDS Dependencies 17 | from Components.SDS_Car_Switch import SD_Car_Switch 18 | from Components.SDS_Host import Cloud_Host 19 | from Components.SDS_Station import SDStorage_Station 20 | from Components.SDS_VANET_Controller import SDVanet_Controller 21 | from Components.SDS_eNodeB import SD_eNodeB 22 | from mininet.cli import CLI 23 | from mininet.log import setLogLevel 24 | from mininet.node import RemoteController 25 | from mininet.wifi.node import UserAP 26 | from mininet.wifi.wmediumdConnector import interference 27 | 28 | from Components.SDS_Switch import SDStor_Switch 29 | 30 | Vanet_controller = SDVanet_Controller 31 | SD_Switch = SDStor_Switch 32 | SD_station = SDStorage_Station 33 | eNodeB = SD_eNodeB 34 | Cloud_host = Cloud_Host 35 | 36 | 37 | class InbandController(RemoteController): 38 | 39 | def checkListening(self): 40 | "Overridden to do nothing." 41 | return 42 | 43 | 44 | def topology(): 45 | car_type = SD_Car 46 | op = raw_input("Choose Type of Experiment: (1)v2i \t (2)v2v \nChoice:") 47 | if(op == "1"): 48 | v2v = False 49 | pass 50 | else: 51 | v2v = True 52 | caching = input( 53 | "What do you prefere to run:\n (1)car-level caching enabled (2)car-level caching disbled \nChoice: ") 54 | if(caching == "1"): 55 | car_type = SD_C_Car 56 | else: 57 | car_type = SD_Car 58 | 59 | "Create a network." 60 | net = Mininet_wifi(controller=Vanet_controller, accessPoint=UserAP, 61 | switch=SD_Car_Switch, station=SD_station,link=wmediumd, 62 | wmediumd_mode=interference) 63 | 64 | print ("*** Creating nodes") 65 | cars = [] 66 | stas = [] 67 | for x in range(0, 10): 68 | cars.append(x) 69 | stas.append(x) 70 | for x in range(0, 10): 71 | cars[x] = net.addCar('car%s' % (x), wlans=1, 72 | ip='10.0.0.%s/8' % (x + 1), encrypt='wpa2', cls=car_type) 73 | 74 | e1 = net.addAccessPoint('e1', wlans=2, ssid='vanet-ssid,', mac='00:00:00:11:00:01', mode='g', channel='1', 75 | passwd='123456789a', encrypt='wpa2', position='3332.62,3253.92,0', cls=eNodeB, inNamespace=True) 76 | e2 = net.addAccessPoint('e2', wlans=2, ssid='vanet-ssid,', mac='00:00:00:11:00:02', mode='g', channel='1', 77 | passwd='123456789a', encrypt='wpa2', position='3279.02,3736.27,0', cls=eNodeB, inNamespace=True) 78 | e3 = net.addAccessPoint('e3', wlans=2, ssid='vanet-ssid,', mac='00:00:00:11:00:03', mode='g', channel='11', 79 | passwd='123456789a', encrypt='wpa2', position='2806.42,3395.22,0', cls=eNodeB, inNamespace=True) 80 | e4 = net.addAccessPoint('e4', wlans=2, ssid='vanet-ssid,', mac='00:00:00:11:00:04', mode='g', channel='6', 81 | passwd='123456789a', encrypt='wpa2', position='2320.82,3565.75,0', cls=eNodeB, inNamespace=True) 82 | e5 = net.addAccessPoint('e5', wlans=2, ssid='vanet-ssid,', mac='00:00:00:11:00:05', mode='g', channel='6', 83 | passwd='123456789a', encrypt='wpa2', position='2887.62,2935.61,0', cls=eNodeB, inNamespace=True) 84 | e6 = net.addAccessPoint('e6', wlans=2, ssid='vanet-ssid,', mac='00:00:00:11:00:06', mode='g', channel='11', 85 | passwd='123456789a', encrypt='wpa2', position='2351.68,3083.40,0', cls=eNodeB, inNamespace=True) 86 | 87 | client = net.addHost('cloud', cls=Cloud_host) 88 | switch = net.addSwitch('switch', dpid='4000000000000000', cls=SD_Switch) 89 | c1 = net.addController( 90 | 'c1', controller=Vanet_controller, ip='127.0.0.1', port=6653) 91 | # "logDistancePropagationLossModel" 92 | net.propagationModel(exp=2.8) 93 | 94 | if(v2v): 95 | print ("*** Setting bgscan") 96 | net.setBgscan(signal=-45, s_inverval=5, l_interval=10) 97 | 98 | print ("*** Configuring wifi nodes") 99 | net.configureWifiNodes() 100 | 101 | net.addLink(switch, e1) 102 | net.addLink(client, switch) 103 | """net.addLink(e1, e2) 104 | net.addLink(e2, e3) 105 | net.addLink(e3, e4) 106 | net.addLink(e4, e5) 107 | net.addLink(e5, e6)""" 108 | 109 | net.addLink(e1, intf = 'e1-wlan2', cls=mesh, ssid='mesh-ssid') 110 | net.addLink(e2, intf = 'e2-wlan2', cls=mesh, ssid='mesh-ssid') 111 | net.addLink(e3, intf = 'e3-wlan2', cls=mesh, ssid='mesh-ssid') 112 | net.addLink(e4, intf = 'e4-wlan2', cls=mesh, ssid='mesh-ssid') 113 | net.addLink(e5, intf = 'e5-wlan2', cls=mesh, ssid='mesh-ssid') 114 | net.addLink(e6, intf = 'e6-wlan2', cls=mesh, ssid='mesh-ssid') 115 | 116 | "Available Options: sumo, sumo-gui" 117 | net.useExternalProgram('sumo-gui', config_file='map.sumocfg') 118 | 119 | print ("*** Starting network") 120 | net.build() 121 | c1.start() 122 | e1.start([c1]) 123 | e2.start([c1]) 124 | e3.start([c1]) 125 | e4.start([c1]) 126 | e5.start([c1]) 127 | e6.start([c1]) 128 | 129 | i = 201 130 | for sw in net.carsSW: 131 | sw.start([c1]) 132 | os.system('ifconfig %s 10.0.0.%s' % (sw, i)) 133 | i += 1 134 | 135 | i = 1 136 | j = 2 137 | for car in cars: 138 | car.setIP('192.168.0.%s/24' % i, intf='%s-wlan0' % car) 139 | car.setIP('192.168.1.%s/24' % i, intf='%s-eth1' % car) 140 | car.cmd('ip route add 10.0.0.0/8 via 192.168.1.%s' % j) 141 | i += 2 142 | j += 2 143 | 144 | i = 1 145 | j = 2 146 | for carsta in net.carsSTA: 147 | carsta.setIP('10.0.0.%s/24' % i, intf='%s-mp0' % carsta) 148 | carsta.setIP('192.168.1.%s/24' % j, intf='%s-eth2' % carsta) 149 | # May be confuse, but it allows ping to the name instead of ip addr 150 | carsta.setIP('10.0.0.%s/24' % i, intf='%s-wlan0' % carsta) 151 | carsta.cmd('echo 1 > /proc/sys/net/ipv4/ip_forward') 152 | i += 1 153 | j += 2 154 | 155 | for carsta1 in net.carsSTA: 156 | i = 1 157 | j = 1 158 | for carsta2 in net.carsSTA: 159 | if carsta1 != carsta2: 160 | carsta1.cmd('route add -host 192.168.1.%s gw 10.0.0.%s' % (j, i)) 161 | i += 1 162 | j += 2 163 | 164 | # Assigning IPs for Access points wlan interfaces 165 | IPs = ['90','91','92','93','94','95','96'] 166 | for i in range(0,6): 167 | net.aps[i].cmd('ifconfig e%s-wlan1 192.168.0.%s'%(i+1,IPs[i])) 168 | net.aps[i].cmd('ifconfig e%s-mp2 192.168.2.%s'%(i+1,i+1)) 169 | net.aps[i].extIP = '192.168.0.%s'%(IPs[i]) 170 | 171 | c1.initializeNetworkResources(net) 172 | 173 | if(v2v): 174 | raw_input("Press Enter to continue (wait 30sec after t=28)...") 175 | os.system('clear') 176 | os.system('ovs-ofctl mod-flows car2SW in_port=2,actions=drop') 177 | cars[2].cmdPrint('iwconfig car2-wlan0') 178 | sleep(3) 179 | cars[6].cmdPrint('iwconfig car6-wlan0') 180 | print ("****************************************************") 181 | print ("*** Both car2 and car6 are associated to enodeB5 ***") 182 | print ("****************************************************") 183 | sleep(6) 184 | os.system('clear') 185 | print ("****************************************************************") 186 | print ("*** Car6 is so far from enodeB5. Trying to send data by car2 ***") 187 | print ("****************************************************************") 188 | sleep(6) 189 | os.system('clear') 190 | print ("**************************************") 191 | print ("*** Trying to send data to car6... ***") 192 | print ("**************************************") 193 | cars[2].cmdPrint('ping -c5 10.0.0.7') 194 | print ("****************************************************************************************************") 195 | print ("*** Car2: V2V is blocked! Car6 is unreachable! Controller, please let me talk directly with car6 ***") 196 | print ("****************************************************************************************************") 197 | sleep(6) 198 | os.system('clear') 199 | print ("***********************************************") 200 | print ("*** controller says: Car6 is now reachable! ***") 201 | print ("***********************************************") 202 | os.system('ovs-ofctl mod-flows car2SW in_port=2,actions=1') 203 | sleep(6) 204 | os.system('clear') 205 | cars[2].cmdPrint('ping -c5 10.0.0.7') 206 | os.system('clear') 207 | print ("***********************************") 208 | print ("*** Car2: Requesting Content for car6! ***") 209 | print ("***********************************") 210 | sleep(1) 211 | cars[2].RequestContent(net, 2) 212 | print ("***********************************") 213 | print ("*** Car2: Thank you Controller! ***") 214 | print ("***********************************") 215 | else: 216 | print ("***********************************") 217 | print ("******** V2I experiment **********") 218 | print ("***********************************") 219 | raw_input("PressEnter after T=28 ...") 220 | 221 | print ("type>> py car4.RequestContent(net)") 222 | 223 | print ("*** Running CLI") 224 | CLI_wifi(net) 225 | 226 | print ("*** Stopping network") 227 | net.stop() 228 | 229 | 230 | if __name__ == '__main__': 231 | setLogLevel('debug') 232 | topology() 233 | -------------------------------------------------------------------------------- /Components/SDS_Controller.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import sys 3 | from mininet.node import Controller 4 | 5 | import time 6 | from .config import Operations,Type 7 | 8 | 9 | class SDStorage_Controller( Controller ): 10 | "Controller to run a SDStorage functions." 11 | 12 | def __init__( self, name,custom_type=Type.SD_STORAGE_CONTROLLER, **kwargs ): 13 | Controller.__init__( self, name,**kwargs ) 14 | self.custom_type=custom_type 15 | 16 | 17 | def Initialize_resources(self,net): 18 | #HostID=1 19 | host_num_files=20 20 | host_num_dir=10 21 | host_size=5 22 | host_used=0 23 | """MEC STUFF""" 24 | basestation_num_files=100 25 | basestation_num_dir=50 26 | basestation_size=25 27 | basestation_used=0 28 | """Content""" 29 | cLibrary=[] 30 | #[content_identifier,content_name,content_size] 31 | content=[1,"City.fbx",5000] 32 | cLibrary.append(content) 33 | content=[2,"Car.obj",2000] 34 | cLibrary.append(content) 35 | content=[3,"Street.fbx",1000] 36 | cLibrary.append(content) 37 | content=[4,"Heritage.jpg",850] 38 | cLibrary.append(content) 39 | #nodes= net.hosts + net.stations 40 | """for host in net.hosts: 41 | host.NO_of_Dir=host_num_dir 42 | host.NO_of_files=host_num_files 43 | host.file_size=host_size 44 | host.Used_space=host_used 45 | msg=[] 46 | msg.append(host.IP()) 47 | Fun1=self.get_capacity(host,host.type) 48 | msg.append(Fun1) 49 | Fun2=self.isFull(host,host.type) 50 | msg.append(Fun2) 51 | Fun3=self.getNumOfFiles(host,host.type) 52 | msg.append(Fun3) 53 | Fun4=self.Available_space(host,host.type) 54 | msg.append(Fun4) 55 | msg.append(host.type) 56 | self.sendMsg_toSwitch("Add",msg,net)""" 57 | for station in net.stations: 58 | station.NO_of_Dir=host_num_dir 59 | station.NO_of_files=host_num_files 60 | station.file_size=host_size 61 | station.Used_space=host_used 62 | msg=[] 63 | msg.append(station.IP()) 64 | cap=self.get_capacity(station,station.type) 65 | msg.append(cap) 66 | isfull=self.isFull(station,station.type) 67 | msg.append(isfull) 68 | files=self.getNumOfFiles(station,station.type) 69 | msg.append(files) 70 | av_space=self.Available_space(station,station.type) 71 | msg.append(av_space) 72 | msg.append(station.type) 73 | #send message to access point 74 | self.send_msg_to_accesspoint("Add",station,msg,net) 75 | count=0 76 | for accessPoint in net.aps: 77 | accessPoint.NO_of_Dir=basestation_num_dir 78 | accessPoint.NO_of_files=basestation_num_files 79 | accessPoint.file_size=basestation_size 80 | accessPoint.used_space=basestation_used 81 | msg=[] 82 | msg.append(accessPoint.params['mac']) 83 | cap=self.get_capacity(accessPoint,accessPoint.type) 84 | msg.append(cap) 85 | isfull=self.isFull(accessPoint,accessPoint.type) 86 | msg.append(isfull) 87 | files=self.getNumOfFiles(accessPoint,accessPoint.type) 88 | msg.append(files) 89 | av_space=self.Available_space(accessPoint,accessPoint.type) 90 | msg.append(av_space) 91 | msg.append(accessPoint.type) 92 | #Localizing AR contnet for each accesspoint 93 | msg.append(cLibrary[count]) 94 | count+=1 95 | #new item 96 | self.send_msg_to_accesspoint(Operations.MEC,accessPoint,msg,net) 97 | 98 | def Handle_switch_packets(self,status,Used_space,HostID,net): 99 | " Get a message from the switch and handle it." 100 | if status == "Add": 101 | network=self.addDir(net) 102 | return network 103 | elif status == "Update": 104 | self.update_Switch_FT(Used_space,HostID,net) 105 | 106 | def Handle_AP_message(self,operation,data,sta_IP,mac_id,net): 107 | " Get a message from the access point and handle it" 108 | if (operation == "Add"): 109 | network=self.addDir(net) 110 | return network 111 | elif (operation == "Update"): 112 | self.update_AccessPoint_FT(data,sta_IP,net) 113 | elif (operation == "mec_Update"): 114 | self.update_AccessPoint_Mec(data,mac_id,net) 115 | elif (operation == Operations.CONTENT_DELIVERY): 116 | res=self.search_AR_MEC(data,mac_id,net) 117 | return res 118 | 119 | 120 | 121 | def sendMsg_toSwitch(self,status,message,Topo): 122 | " Send a message to the switch to notify it with any change " 123 | msg=message 124 | Topo.switches[0].Handle_controller_packets(status,msg) 125 | def send_msg_to_accesspoint(self,operation,node,FT,net): 126 | "send a message to the access point to notify the changes " 127 | if(node.type == Type.ACCESSPOINT): 128 | node.Handle_controller_FT_update(operation,FT) 129 | else: 130 | #node is station 131 | ap=node.params['associatedTo'][0] 132 | #print ("node type is %s associated to %s type"%(node.type,ap.type)) 133 | ap.Handle_controller_FT_update(operation,FT) 134 | 135 | def update_Switch_FT(self, Used_space,HostID,net): 136 | " Update the Functions valus in case a new store happend " 137 | for host in net.hosts: 138 | if host.IP()==HostID: 139 | #print host.Used_space ,host.NO_of_Dir ,host.NO_of_files,host.file_size , host.name 140 | host.Used_space+=Used_space 141 | msg=[] 142 | msg.append(host.IP()) 143 | 144 | Fun1=self.get_capacity(host,host.type) 145 | #print host.Used_space ,host.NO_of_Dir ,host.NO_of_files,host.file_size, host.name 146 | msg.append(Fun1) 147 | Fun2=self.isFull(host,host.type) 148 | msg.append(Fun2) 149 | Fun3=self.getNumOfFiles(host,host.type) 150 | msg.append(Fun3) 151 | Fun4=self.Available_space(host,host.type) 152 | msg.append(Fun4) 153 | 154 | self.sendMsg_toSwitch("Update",msg,net) 155 | #print "Why" 156 | break 157 | 158 | def update_AccessPoint_FT(self,used_space,sta_IP,net): 159 | "update stations parameters in case any new data is stored" 160 | for station in net.stations: 161 | if (station.IP() == sta_IP): 162 | station.Used_space+=used_space 163 | msg=[] 164 | msg.append(station.IP()) 165 | cap=self.get_capacity(station,station.type) 166 | msg.append(cap) 167 | isfull=self.isFull(station,station.type) 168 | msg.append(isfull) 169 | files=self.getNumOfFiles(station,station.type) 170 | msg.append(files) 171 | av_space=self.Available_space(station,station.type) 172 | msg.append(av_space) 173 | #send message to access point 174 | self.send_msg_to_accesspoint("Update",station,msg,net) 175 | 176 | def search_AR_MEC(self,data,mac_id,net): 177 | found=False 178 | #print ("controller received AR request for id:%s"%data) 179 | for ap in net.aps: 180 | if(ap.params['mac'] == mac_id): 181 | continue 182 | else: 183 | #search AP for requested AR content 184 | for content in ap.cLibrary: 185 | #print ("AR identifier inside AP is %s holding %s and passed identifier is %s "%(content[0],content[1],content_identifier)) 186 | if(content[0] == data): 187 | #print "AR content found" 188 | found = True 189 | #print("AR content found in AP[%s]"%(ap.params['mac'])) 190 | #sleep thread to memic search time in another MEC 191 | #Consider file size when applying latency 192 | sleep_time=(content[0+2]/1000)*0.0000018 193 | #Consider num of hubs when applying latency 194 | sleep_time+=0.03 195 | time.sleep(sleep_time) 196 | #print ("result in controller: %s"%found) 197 | return found 198 | else: 199 | time.sleep(0.03) 200 | 201 | if(not found): 202 | time.sleep(0.1) 203 | #print ("can not find the requested AR content within all accesspoints") 204 | return False 205 | 206 | 207 | 208 | def update_AccessPoint_Mec(self,used_space,mac_id,net): 209 | #print ("controller->Update MEC[%s] storage with %s datasize",used_space) 210 | for ap in net.aps: 211 | if (ap.params['mac'] == mac_id): 212 | ap.Used_space+=used_space 213 | msg=[] 214 | msg.append(ap.params['mac']) 215 | cap=self.get_capacity(ap,ap.type) 216 | msg.append(cap) 217 | isfull=self.isFull(ap,ap.type) 218 | msg.append(isfull) 219 | files=self.getNumOfFiles(ap,ap.type) 220 | msg.append(files) 221 | av_space=self.Available_space(ap,ap.type) 222 | msg.append(av_space) 223 | msg.append(ap.type) 224 | self.send_msg_to_accesspoint("mec_Update",ap,msg,net) 225 | break 226 | 227 | def addDir(self,net): 228 | " Add a Dir to the Storage_Host." 229 | #TODO: check if node type (this metho were handling hosts only, and has been changed to stations) 230 | for station in net.stations: 231 | station.NO_of_Dir+=1 232 | msg=[] 233 | #msg.append(HostID) 234 | msg.append(station.IP()) 235 | Fun1=self.get_capacity(station,station.type) 236 | msg.append(Fun1) 237 | Fun2=self.isFull(station,station.type) 238 | msg.append(Fun2) 239 | Fun3=self.getNumOfFiles(station,station.type) 240 | msg.append(Fun3) 241 | Fun4=self.Available_space(station,station.type) 242 | msg.append(Fun4) 243 | self.send_msg_to_accesspoint("Update",station,msg,net) 244 | return net 245 | 246 | def get_capacity(self,node,node_type): 247 | if(node_type == Type.HOST): 248 | Cap= (node.NO_of_Dir*node.NO_of_files*node.file_size) 249 | elif(node_type == Type.STATION): 250 | Cap= (node.NO_of_Dir*node.NO_of_files*node.file_size) 251 | elif(node_type == Type.ACCESSPOINT): 252 | Cap= (node.NO_of_Dir*node.NO_of_files*node.file_size) 253 | return Cap 254 | 255 | def isFull(self,node,node_type): #Fun2 256 | "Check if the storage host is full or not!" 257 | if (node_type == Type.HOST): 258 | if self.get_capacity(node,node_type)== node.Used_space: 259 | return "Yes" 260 | else: 261 | return "No" 262 | elif (node_type == Type.STATION): 263 | if self.get_capacity(node,node_type)== node.Used_space: 264 | return "Yes" 265 | else: 266 | return "No" 267 | elif (node_type == Type.ACCESSPOINT): 268 | if self.get_capacity(node,node_type)== node.Used_space: 269 | return "Yes" 270 | else: 271 | return "No" 272 | 273 | 274 | 275 | def getNumOfFiles(self,node,node_type): #Fun3 276 | "Return the total number of the files on the host storage" 277 | return node.NO_of_Dir*node.NO_of_files 278 | 279 | def Available_space(self,node,node_type): #Fun4 280 | "return total_space-used_space" 281 | res=self.get_capacity(node,node_type)- node.Used_space 282 | return res -------------------------------------------------------------------------------- /Components/SDS_RSU.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from mininet.wifi.node import UserAP 3 | from operator import itemgetter 4 | from .config import Modes, Operations,Type 5 | import time 6 | #TODO the implementation of this class should be identical from eNodeB class representing different functions. 7 | class SD_RSU (UserAP): 8 | "custom AccessPoint to support SDSecure Storage" 9 | def __init__(self, name, custom_type=Type.SD_RSU, NO_of_Dir=100, NO_of_files=50, file_size=25, NO_of_RACKS=1, Used_space=0, **pars): 10 | UserAP.__init__(self, name, **pars) 11 | # OVSKernelAP.__init__(self, name, **pars) 12 | """MEC Attributes""" 13 | self.NO_of_Dir=NO_of_Dir 14 | self.NO_of_files=NO_of_files 15 | self.file_size=file_size 16 | self.Used_space=Used_space 17 | self.NO_of_RACKS=NO_of_RACKS 18 | self.custom_type=custom_type 19 | self.MEC=[] 20 | """""" 21 | 22 | """Contents""" 23 | self.cLibrary=[] 24 | 25 | """""" 26 | self.Function_table=[] 27 | self.counter=0 28 | 29 | def insert_entry(self,SDSObject): 30 | self.Function_table.append([]) #initialize the function table 31 | for index in range(len(SDSObject)): 32 | self.Function_table[self.counter].append(SDSObject[index]) 33 | #sort the function table by the available space decending 34 | Sorted_FT=sorted(self.Function_table,key=itemgetter(4),reverse=True) 35 | self.Function_table=Sorted_FT 36 | self.counter+=1 37 | 38 | def update_entry(self,SDSObject): 39 | passed=False 40 | MEC_mac_address=SDSObject[0] 41 | if(MEC_mac_address == self.MEC[0]): 42 | passed=True 43 | if(passed): 44 | self.MEC = [] 45 | print ("UpdatingMEC-> Allocating storage \n **************************") 46 | for attrib in range(len(SDSObject)): 47 | self.MEC.append(SDSObject[attrib]) 48 | print ("attrib %s : %s"%(attrib,self.MEC[attrib])) 49 | 50 | 51 | def remove_entry(self, SDSObject): 52 | # get Station IP 53 | StationIP=SDSObject[0] 54 | index=0 55 | while( index < len(self.Function_table)): 56 | if(StationIP == self.Function_table[index][0]): 57 | self.Function_table.pop(index) 58 | break 59 | index+=1 60 | #resort AP-FT 61 | sorted(self.Function_table,itemgetter(4),reverse=True) 62 | 63 | def handleControllerUpdateRequest(self,operation, SDSObject): 64 | if(operation == 'Add'): 65 | self.insert_entry(SDSObject) 66 | elif(operation == 'Update'): 67 | self.update_entry(SDSObject) 68 | elif(operation == Operations.MEC): 69 | self.initializeMecContents(SDSObject) 70 | elif(operation == 'mec_Update'): 71 | self.update_mec(SDSObject) 72 | else: 73 | self.remove_entry(SDSObject) 74 | #this is temp should be removed 75 | def update_mec(self,msg): 76 | self.MEC=[] 77 | #print ("inside update_mec new available spce is%s"%msg[4]) 78 | for attrib in range(len(msg)): 79 | self.MEC.append(msg[attrib]) 80 | 81 | def initializeMecContents(self, msg): 82 | self.MEC=[] 83 | #print ("updating mec: adding attributes") 84 | #print ("********************************") 85 | for attrib in range(len(msg)-1): 86 | self.MEC.append(msg[attrib]) 87 | #print ("attrib %s -> %s"%(attrib,self.MEC[attrib])) 88 | self.cLibrary.append(msg[len(msg) - 1]) 89 | 90 | def listMecContents(self, mode, net): 91 | if(mode == Modes.MEC): 92 | print ("[MAC Address , Station Capacity , IsStationFull , Num of files , Available space]") 93 | for ap in net.aps: 94 | if(ap.custom_type == Type.SD_SWITCH): 95 | continue 96 | #ap=self.MEC 97 | #print ("length of MEC is:%s"%len(ap)) 98 | #print('[%s ,\t %s ,\t %s ,\t %s ,\t %s,\t %s,\t %s]' % (ap.MEC[0],ap.MEC[1],ap.MEC[2],ap.MEC[3],ap.MEC[4],ap.MEC[5],ap.AR_Library[0][1])) 99 | print('[%s ,\t %s ,\t %s ,\t %s ,\t %s,\t %s]' % (ap.MEC[0], ap.MEC[1], ap.MEC[2], ap.MEC[3], ap.MEC[4], ap.MEC[5])) 100 | elif(mode == Modes.CONTENT_DELIVERY): 101 | print ("[MAC Address]\t{AR Library} \n ***************************") 102 | for ap in net.aps: 103 | if (ap.custom_type == Type.SD_SWITCH): 104 | continue 105 | print ("%s \t "%ap.MEC[0]) 106 | count = 0 107 | for AR in ap.AR_Library: 108 | for i in range(len(AR)): 109 | print ("content: %s" % (AR[i])) 110 | count += 1 111 | print ("------") 112 | 113 | 114 | """ 115 | count=0 116 | for AR in self.AR_Library: 117 | print "content %s"%count 118 | for i in range(len(AR)): 119 | print ("content: %s"%(AR[i])) 120 | count+=1 121 | """ 122 | 123 | def Handle_controller_packets(self,status,message): 124 | " Get a message from the controller and handle it." 125 | packetstatus=status 126 | SDSObj= message 127 | 128 | if packetstatus == "Add": 129 | self.insert_entry(SDSObj) 130 | elif packetstatus =="Update": 131 | self.update_entry(SDSObj) 132 | else: 133 | self.remove_entry(SDSObj) 134 | 135 | def find_Node_with_available_space(self, datasize, net): 136 | found=False 137 | while(not found): 138 | for station_idx in range(len(self.Function_table)): 139 | Current_station=self.Function_table[station_idx] 140 | if (datasize == 0): 141 | found=True 142 | break 143 | else: 144 | #data sent ain't empty 145 | sta_available_space= Current_station[4] 146 | sta_IP=Current_station[0] 147 | 148 | if(datasize <= sta_available_space): 149 | used_space=datasize 150 | datasize=0 #the data have been stored successfully 151 | found=True 152 | #inform the controller 153 | self.sendMsg_toCon("Update",used_space,sta_IP,None,net) 154 | else: 155 | #the file_size is larger than the Available_space 156 | used_space=sta_available_space 157 | datasize=datasize-used_space 158 | #inform the controller 159 | self.sendMsg_toCon("Update",used_space,sta_IP,None,net) 160 | 161 | #if last station reached and the dataSize still large 162 | #inform the controller to find space else where in another switch (if any left unchecked) 163 | # in addition to inform the controller to activate new rackspaces in the stations 164 | if (station_idx == (len(self.Function_table)-1) and datasize != 0): 165 | self.sendMsg_toCon("Add",None,None,None,net) 166 | 167 | def sendMsg_toCon(self,operation,data,sta_IP,mac_id,net): 168 | if(operation == "Update"): 169 | net.controllers[0].Handle_AP_message("Update",data,sta_IP,None,net) 170 | elif (operation == "Add"): 171 | net.controllers[0].Handle_AP_message("Add",None,None,None,net) 172 | elif (operation == "mec_Update"): 173 | net.controllers[0].Handle_AP_message("mec_Update",data,None,mac_id,net) 174 | elif(operation == Operations.CONTENT_DELIVERY): 175 | res= net.controllers[0].Handle_AP_message(Operations.CONTENT_DELIVERY,data,None,mac_id,net) 176 | #print ("result in accesspoint(msg response): %s"%res) 177 | return res 178 | 179 | 180 | def send_msg_to_station(message): 181 | pass 182 | 183 | def Handle_AR_Content_Request(self,content_identifier,net): 184 | #print ("requested AR content has identifier %s"%content_identifier) 185 | #search current accessPoint 186 | index = 0 187 | found = False 188 | for AR_content in self.cLibrary: 189 | for c in AR_content: 190 | #print ("AR identifier inside AP is %s holding %s and passed identifier is %s "%(c[0],c[1],content_identifier)) 191 | if(c[0] == content_identifier): 192 | #print "AR content found locally" 193 | #Consider file size when applying latency 194 | sleep_time=(c[0+2]/1000)*0.0000018 195 | time.sleep(sleep_time) 196 | found = True 197 | else: 198 | # search peneality in the same MEC node 199 | time.sleep(0.0001) 200 | if(found): 201 | break 202 | if(not found): 203 | #ask the controller to search another MEC node 204 | A_MEC_mac_address=self.MEC[0] 205 | res=self.sendMsg_toCon(Operations.CONTENT_DELIVERY,content_identifier,None,A_MEC_mac_address,net) 206 | #print ("result in accessPoint(CO MEC): %s"%res) 207 | return res 208 | #print ("result in accesspoint(Local MEC): %s"%found) 209 | return found 210 | 211 | 212 | def store_data(self,datasize,net): 213 | stored=False 214 | THRESHOLD = 4 #NUMBER OF MEC NODES TO BE SEARCHED 215 | sleep_time = 0 216 | while(not stored): 217 | if(datasize == 0): 218 | stored=True 219 | print ("data sent is empty") 220 | break 221 | else: 222 | #data is not empty 223 | A_MEC_available_space= self.MEC[4] #associated mec available space 224 | A_MEC_mac_address=self.MEC[0] #associate MEC macaddress in order to be sent to the controller to update it's vision about it 225 | if(datasize<= A_MEC_available_space): 226 | print ("there is enough space for the data to be stored") 227 | used_space=datasize 228 | stored=True 229 | #print ("AP-> tell the controller to save %s inside MEC"%used_space) 230 | self.sendMsg_toCon("mec_Update",used_space,None,A_MEC_mac_address,net) 231 | 232 | #simulate the delay of the store operation 233 | sleep_time = (datasize/1000)*0.0000018 234 | time.sleep(sleep_time) 235 | else: 236 | #Seize the full amount of storage left inside the associated mec and 237 | #let the controller find some other mec to save the rest 238 | used_space=A_MEC_available_space 239 | datasize=datasize-used_space 240 | self.sendMsg_toCon("mec_Update",used_space,None,A_MEC_mac_address,net) 241 | sleep_time = (datasize / 1000) * 0.0000018 242 | time.sleep(sleep_time) 243 | #the rest need to be stored on the next closest MEC 244 | print ("only %s bytes has been stored, %s bytes need to be stored in another MEC node"%(used_space,datasize)) 245 | """Search AccessPoints in net""" 246 | #TODO: this implementation assume that all accesspoints in the net, and should be moved to controller thou 247 | # are connected to each others. it has to be optimized to consider only 248 | # accesspoints that are linked to the associated MEC accesspoint 249 | full=True 250 | NUM_OF_APS=len(net.aps) 251 | print ("Num of accesspoints is: %s"%NUM_OF_APS) 252 | counter=0 253 | for ap in net.aps: 254 | print ("%s accesspoints have been searched" % counter) 255 | if (counter == (NUM_OF_APS - 1) or (counter+1) >= THRESHOLD): #or (counter+1) >= THRESHOLD 256 | print ("All APs are full and there is %s bytes left unstored" % used_space) 257 | # Inform the controller to allocate storage inside accesspoints 258 | ap.sendMsg_toCon("Add", None, None, None, net) 259 | sleep_time = 0.05 260 | time.sleep(sleep_time) 261 | 262 | if(ap.params['mac'] == A_MEC_mac_address): 263 | counter+=1 264 | continue 265 | else: 266 | sleep_time=0.03; #added penality for MEC search 267 | sleep_time = sleep_time + (counter)*0.1; #penality added for data transfer 268 | time.sleep(sleep_time) 269 | print("another accesspoint found inside net with mac address:%s"%ap.params['mac']) 270 | ap_available_space=ap.MEC[4] 271 | ap_mac_address=ap.params['mac'] 272 | #check if there is available space 273 | if(datasize <= ap_available_space): 274 | used_space=datasize 275 | stored=True 276 | print ("CO AP->tell the controller to save %s inside CO MEC %s"%(used_space,ap_mac_address)) 277 | ap.sendMsg_toCon("mec_Update",used_space,None,ap_mac_address,net) 278 | #storage operation delay 279 | sleep_time = sleep_time + (datasize / 1000) * 0.0000018 280 | time.sleep(sleep_time) 281 | stored = True 282 | break #break the inner loop 283 | else: 284 | used_space=ap_available_space 285 | datasize=datasize-used_space 286 | ap.sendMsg_toCon("mec_Update",used_space,None,ap_mac_address,net) 287 | counter+=1 288 | #storage operation delay 289 | sleep_time = sleep_time + (datasize / 1000) * 0.0000018 290 | time.sleep(sleep_time) 291 | 292 | 293 | 294 | def printFT(self): 295 | print ("[IP Address , Station Capacity , IsStationFull , Num of files , Available space]") 296 | for index in range(len(self.Function_table)): 297 | station=self.Function_table[index] 298 | print('[%s ,\t %s ,\t %s ,\t %s ,\t %s]' % (station[0],station[1],station[2],station[3],station[4])) 299 | -------------------------------------------------------------------------------- /Components/SDS_VANET_Controller.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import sys 3 | from mininet.node import Controller, Switch 4 | from mininet.wifi.node import Car, AP 5 | from .config import Operations, Type 6 | from .latencyModel import latencyModel 7 | import time 8 | 9 | from Components.contentLibrary import contentLibrary 10 | 11 | 12 | class SDVanet_Controller( Controller ): 13 | "Controller to run a SDStorage functions." 14 | def __init__( self, name,custom_type=Type.SD_VANET_CONTROLLER, **kwargs ): 15 | Controller.__init__( self, name,**kwargs ) 16 | self.custom_type=custom_type 17 | self.RSUs=[] 18 | self.eNodeBs=[] 19 | 20 | def initializeNetworkResources(self, net): 21 | cLibrary= contentLibrary() 22 | #nodes= net.hosts + net.stations 23 | for host in net.hosts: 24 | if(host.custom_type == Type.SD_CLOUD_HOST): 25 | msg=[] 26 | msg.append(host.IP()) 27 | Fun1=self.get_capacity(host,Type.HOST) 28 | msg.append(Fun1) 29 | Fun2=self.isFull(host,Type.HOST) 30 | msg.append(Fun2) 31 | Fun3=self.getNumOfFiles(host,Type.HOST) 32 | msg.append(Fun3) 33 | Fun4=self.Available_space(host,Type.HOST) 34 | msg.append(Fun4) 35 | msg.append(Type.HOST) 36 | self.sendMsg_toSwitch("Add",host,msg,net) 37 | else: 38 | continue 39 | for switch in net.switches: 40 | if(switch.custom_type == Type.SD_SWITCH): 41 | msg = [] 42 | msg.append("'[02:00:00:00:0k:00]'") 43 | """cap = self.get_capacity(switch, switch.type) 44 | msg.append(cap) 45 | isfull = self.isFull(switch, switch.type) 46 | msg.append(isfull) 47 | files = self.getNumOfFiles(switch, switch.type) 48 | msg.append(files) 49 | av_space = self.Available_space(switch, switch.type) 50 | msg.append(av_space)""" 51 | msg.append(Type.SWITCH) 52 | # Localizing AR contnet for each accesspoint 53 | contents = [] 54 | for i in range(0,10): 55 | contents.append(cLibrary[i]) 56 | 57 | # msg.append(cLibrary[count]) 58 | msg.append(contents) 59 | # new item 60 | self.sendMsg_toSwitch(Operations.CONTENT_DELIVERY, switch, msg, net) 61 | 62 | else: 63 | continue 64 | for car in net.cars: 65 | msg=[] 66 | msg.append(car.IP()) 67 | cap=self.get_capacity(car,Type.VEHICLE) 68 | msg.append(cap) 69 | isfull=self.isFull(car,Type.VEHICLE) 70 | msg.append(isfull) 71 | files=self.getNumOfFiles(car,Type.VEHICLE) 72 | msg.append(files) 73 | av_space=self.Available_space(car,Type.VEHICLE) 74 | msg.append(av_space) 75 | msg.append(Type.VEHICLE) 76 | #send message to access point 77 | #self.send_msg_to_accesspoint("Add",car,msg,net) 78 | count=0 79 | for accessPoint in net.aps: 80 | #filter out accesspoints by custom_type 81 | if(accessPoint.custom_type == Type.SD_RSU): 82 | self.RSUs.append(accessPoint) 83 | elif(accessPoint.custom_type == Type.SD_E_NODEB): 84 | self.eNodeBs.append(accessPoint) 85 | elif(accessPoint.custom_type == Type.SD_SWITCH): 86 | continue; #main switch does not hold any MEC related function 87 | msg=[] 88 | msg.append(accessPoint.params['mac']) 89 | cap=self.get_capacity(accessPoint,Type.ACCESSPOINT) 90 | msg.append(cap) 91 | isfull=self.isFull(accessPoint,Type.ACCESSPOINT) 92 | msg.append(isfull) 93 | files=self.getNumOfFiles(accessPoint,Type.ACCESSPOINT) 94 | msg.append(files) 95 | av_space=self.Available_space(accessPoint,Type.ACCESSPOINT) 96 | msg.append(av_space) 97 | msg.append(Type.ACCESSPOINT) 98 | #Localizing AR contnet for each accesspoint 99 | contents=[] 100 | contents.append(cLibrary[count]) 101 | count+=1 102 | """contents.append(cLibrary[count]) 103 | count+=1 104 | if (count == 10): 105 | count =0""" 106 | #msg.append(cLibrary[count]) 107 | msg.append(contents) 108 | #new item 109 | self.send_msg_to_accesspoint(Operations.MEC,accessPoint,msg,net) 110 | 111 | def Handle_switch_packets(self,status,Used_space,HostID,net): 112 | " Get a message from the switch and handle it." 113 | if status == "Add": 114 | network=self.addRack(net) 115 | return network 116 | elif status == "Update": 117 | self.update_Switch_FT(Used_space,HostID,net) 118 | 119 | def Handle_AP_message(self,operation,data,sta_IP,mac_id,net): 120 | " Get a message from the access point and handle it" 121 | if (operation == "Add"): 122 | network=self.addRack(net) 123 | return network 124 | elif (operation == "Update"): 125 | self.update_AccessPoint_FT(data,sta_IP,net) 126 | elif (operation == "mec_Update"): 127 | self.update_AccessPoint_Mec(data,mac_id,net) 128 | elif (operation == Operations.CONTENT_DELIVERY): 129 | res=self.search_AR_MEC(data,mac_id,net) 130 | return res 131 | 132 | 133 | 134 | def sendMsg_toSwitch(self,operation,node,FT,net): 135 | " Send a message to the switch to notify it with any change " 136 | if isinstance(node, Switch): 137 | node.Handle_controller_packets(operation,FT) 138 | 139 | def send_msg_to_accesspoint(self,operation,node,FT,net): 140 | "send a message to the access point to notify the changes " 141 | if isinstance(node, AP): 142 | node.handleControllerUpdateRequest(operation, FT) 143 | elif isinstance(node, Car): 144 | #node is car 145 | ap=node.params['associatedTo'][0] 146 | #print ("node type is %s associated to %s type"%(node.type,ap.type)) 147 | ap.handleControllerUpdateRequest(operation, FT) 148 | else: 149 | ap= node.params['associatedTo'][0] 150 | ap.handleControllerUpdateRequest(operation, FT) 151 | #node is station 152 | 153 | def update_Switch_FT(self, Used_space,HostID,net): 154 | " Update the Functions valus in case a new store happend " 155 | for host in net.hosts: 156 | if host.IP()==HostID: 157 | #print host.Used_space ,host.NO_of_Dir ,host.NO_of_files,host.file_size , host.name 158 | host.Used_space+=Used_space 159 | msg=[] 160 | msg.append(host.IP()) 161 | 162 | Fun1=self.get_capacity(host,Type.HOST) 163 | #print host.Used_space ,host.NO_of_Dir ,host.NO_of_files,host.file_size, host.name 164 | msg.append(Fun1) 165 | Fun2=self.isFull(host,Type.HOST) 166 | msg.append(Fun2) 167 | Fun3=self.getNumOfFiles(host,Type.HOST) 168 | msg.append(Fun3) 169 | Fun4=self.Available_space(host,Type.HOST) 170 | msg.append(Fun4) 171 | 172 | self.sendMsg_toSwitch("Update",msg,net) 173 | #print "Why" 174 | break 175 | 176 | def update_AccessPoint_FT(self,used_space,sta_IP,net): 177 | "update stations parameters in case any new data is stored" 178 | for station in net.stations: 179 | if (station.IP() == sta_IP): 180 | station.Used_space+=used_space 181 | msg=[] 182 | msg.append(station.IP()) 183 | cap=self.get_capacity(station,Type.STATION) 184 | msg.append(cap) 185 | isfull=self.isFull(station,Type.STATION) 186 | msg.append(isfull) 187 | files=self.getNumOfFiles(station,Type.STATION) 188 | msg.append(files) 189 | av_space=self.Available_space(station,Type.STATION) 190 | msg.append(av_space) 191 | #send message to access point 192 | self.send_msg_to_accesspoint("Update",station,msg,net) 193 | 194 | def search_AR_MEC(self,data,mac_id,net): 195 | found=False 196 | THRESHOLD = 4 197 | counter = 1 198 | #print ("controller received AR request for id:%s"%data) 199 | for ap in net.aps: 200 | if (counter >= THRESHOLD): 201 | #print ("counter is %s"%counter) 202 | break 203 | if(ap.params['mac'] == mac_id): 204 | continue 205 | else: 206 | #search AP for requested AR content 207 | for content in ap.cLibrary: 208 | for c in content: 209 | if(c[0] == data): 210 | #print "content found" 211 | found = True 212 | sleep_time= latencyModel.fileTransferLatency(c[0+2]) 213 | #Consider num of hubs when applying latency 214 | sleep_time+=latencyModel.nextHopLatency() 215 | time.sleep(sleep_time) 216 | #print ("result in controller: %s"%found) 217 | return found 218 | else: 219 | # search peneality in the same MEC node 220 | time.sleep(latencyModel.searchPenality()) 221 | 222 | 223 | time.sleep(latencyModel.nextHopLatency()) 224 | #print ("counter: %s"%counter) 225 | counter = counter +1 226 | 227 | if(not found): 228 | #print ("can not find the requested content within all accesspoints") 229 | for sw in net.switches: 230 | if(sw.custom_type == Type.SD_SWITCH): 231 | for content in sw.cLibrary: 232 | for c in content: 233 | if (c[0] == data): 234 | found=True 235 | #print("AR content found in cloud") 236 | # Consider file size when applying latency 237 | sleep_time= latencyModel.fileTransferLatency(c[0+2]) 238 | #Consider num of hubs when applying latency 239 | sleep_time+=latencyModel.nextHopLatency() 240 | time.sleep(sleep_time) 241 | #print ("result in controller: %s"%found) 242 | return found 243 | else: 244 | # search peneality in the same MEC node 245 | time.sleep(latencyModel.searchPenality()) 246 | 247 | else: 248 | #not switch, might be (AP,MEC,eNodeB) 249 | continue; 250 | 251 | return found 252 | 253 | 254 | 255 | def update_AccessPoint_Mec(self,used_space,mac_id,net): 256 | #print ("controller->Update MEC[%s] storage with %s datasize",used_space) 257 | for ap in net.aps: 258 | if (ap.custom_type == Type.SD_SWITCH): 259 | continue 260 | if (ap.params['mac'] == mac_id): 261 | ap.Used_space+=used_space 262 | msg=[] 263 | msg.append(ap.params['mac']) 264 | cap=self.get_capacity(ap,Type.ACCESSPOINT) 265 | msg.append(cap) 266 | isfull=self.isFull(ap,Type.ACCESSPOINT) 267 | msg.append(isfull) 268 | files=self.getNumOfFiles(ap,Type.ACCESSPOINT) 269 | msg.append(files) 270 | av_space=self.Available_space(ap,Type.ACCESSPOINT) 271 | msg.append(av_space) 272 | msg.append(Type.ACCESSPOINT) 273 | self.send_msg_to_accesspoint("mec_Update",ap,msg,net) 274 | break 275 | 276 | def addRack(self, net): 277 | " Add a Dir to the Storage_Host." 278 | #TODO: check if node type (this metho were handling hosts only, and has been changed to stations) 279 | for MEC in net.aps: 280 | if (MEC.custom_type == Type.SD_SWITCH): 281 | continue 282 | MEC.NO_of_RACKS+=1 283 | msg=[] 284 | #msg.append(HostID) 285 | msg.append(MEC.params['mac']) 286 | Fun1=self.get_capacity(MEC,Type.ACCESSPOINT) 287 | msg.append(Fun1) 288 | Fun2=self.isFull(MEC,Type.ACCESSPOINT) 289 | msg.append(Fun2) 290 | Fun3=self.getNumOfFiles(MEC,Type.ACCESSPOINT) 291 | msg.append(Fun3) 292 | Fun4=self.Available_space(MEC,Type.ACCESSPOINT) 293 | msg.append(Fun4) 294 | msg.append(Type.ACCESSPOINT) 295 | self.send_msg_to_accesspoint("Update",MEC,msg,net) 296 | return net 297 | 298 | def get_capacity(self,node,node_type): 299 | if(node_type == Type.HOST): 300 | Cap= (node.NO_of_Dir*node.NO_of_files*node.file_size) 301 | elif(node_type == Type.STATION): 302 | Cap= (node.NO_of_Dir*node.NO_of_files*node.file_size) 303 | elif(node_type == Type.ACCESSPOINT): 304 | Cap= (node.NO_of_RACKS* node.NO_of_Dir*node.NO_of_files*node.file_size) 305 | elif(node_type == Type.VEHICLE): 306 | Cap= (node.NO_of_Dir*node.NO_of_files*node.file_size) 307 | return Cap 308 | 309 | def isFull(self,node,node_type): #Fun2 310 | "Check if the storage host is full or not!" 311 | if (node_type == Type.HOST): 312 | if self.get_capacity(node,node_type)== node.Used_space: 313 | return "Yes" 314 | else: 315 | return "No" 316 | elif (node_type == Type.STATION): 317 | if self.get_capacity(node,node_type)== node.Used_space: 318 | return "Yes" 319 | else: 320 | return "No" 321 | elif (node_type == Type.ACCESSPOINT): 322 | if self.get_capacity(node,node_type)== node.Used_space: 323 | return "Yes" 324 | else: 325 | return "No" 326 | elif (node_type == Type.VEHICLE): 327 | if self.get_capacity(node,node_type)== node.Used_space: 328 | return "Yes" 329 | else: 330 | return "No" 331 | 332 | 333 | 334 | def getNumOfFiles(self,node,node_type): #Fun3 335 | "Return the total number of the files on the host storage" 336 | return node.NO_of_Dir*node.NO_of_files 337 | 338 | def Available_space(self,node,node_type): #Fun4 339 | "return total_space-used_space" 340 | res=self.get_capacity(node,node_type)- node.Used_space 341 | return res 342 | 343 | 344 | #def Used_space(self, NO_of_Dir,NO_of_files,file_size) 345 | #for Dir in Dirs 346 | # for file in files 347 | # if file is not """ 348 | --------------------------------------------------------------------------------