profile.py 8.79 KB
Newer Older
Jonathon Duerig's avatar
Jonathon Duerig committed
1 2
#!/usr/bin/env python

3 4 5 6 7 8 9 10 11
#
# Standard geni-lib/portal libraries
#
import geni.portal as portal
import geni.rspec.pg as rspec
import geni.rspec.emulab as elab
import geni.rspec.igext as IG
import geni.urn as URN

Jonathon Duerig's avatar
Jonathon Duerig committed
12

13
tourDescription = """
Jonathon Duerig's avatar
Jonathon Duerig committed
14 15 16 17 18 19 20 21 22 23 24 25
Use this profile to instantiate an experiment using Open Air Interface
to realize an end-to-end SDR-based mobile network. This profile includes
the following resources:

  * Off-the-shelf Nexus 5 UE running Android 4.4.4 KitKat ('rue1')
  * SDR eNodeB (Intel NUC + USRP B210) running OAI on Ubuntu 16 ('enb1')
  * All-in-one EPC node (HSS, MME, SPGW) running OAI on Ubuntu 16 ('epc')
  * A node providing out-of-band ADB access to the UE ('adb-tgt')

PhantomNet startup scripts automatically configure OAI for the
specific allocated resources.

26 27
For more detailed information:

28
  * [Getting Started](https://gitlab.flux.utah.edu/powder-profiles/OAI-Real-Hardware/blob/master/README.md)
Jonathon Duerig's avatar
Jonathon Duerig committed
29

30 31 32
""";

tourInstructions = """
33 34 35 36 37 38
After booting is complete,
For Simulated UE, log onto `epc` node and run:

    sudo /local/repository/bin/start_oai.pl -r sim

Else, log onto either the `enb1` or `epc` nodes. From there, you will be able to start all OAI services across the network by running:
39 40 41

    sudo /local/repository/bin/start_oai.pl

42
Above command will stop any currently running OAI services, start all services (both epc and enodeb) again, and then interactively show a tail of the logs of the mme and enodeb services. Once you see the logs, you can exit at any time with Ctrl-C, but the services stay running in the background and save logs to `/var/log/oai/*` on the `enb1` and `epc` nodes.
43 44 45

Once all the services are running, the UE device will typically connect on its own, but if it doesn't you can reboot the phone. You can manage the UE by logging into the `adb-tgt` node, running `pnadb -a` to connect, and then managing it via any `adb` command such as `adb shell` or `adb reboot`.

46 47 48 49
For Simulated UE experiment, check the connectivity by logging into the `sim-enb` node and run:

    ping -I oip1 8.8.8.8

50
While OAI is still a system in development and may be unstable, you can usually recover from any issue by running `start_oai.pl` to restart all the services.
51 52 53

  * [Full Documentation](https://gitlab.flux.utah.edu/powder-profiles/OAI-Real-Hardware/blob/master/README.md)

54
""";
Jonathon Duerig's avatar
Jonathon Duerig committed
55

Jonathon Duerig's avatar
Jonathon Duerig committed
56 57 58 59 60

#
# PhantomNet extensions.
#
import geni.rspec.emulab.pnext as PN
Jonathon Duerig's avatar
Jonathon Duerig committed
61

Jonathon Duerig's avatar
Jonathon Duerig committed
62 63 64 65 66
#
# Globals
#
class GLOBALS(object):
    OAI_DS = "urn:publicid:IDN+emulab.net:phantomnet+ltdataset+oai-develop"
Sonika's avatar
Sonika committed
67
    OAI_SIM_DS = "urn:publicid:IDN+emulab.net:phantomnet+dataset+PhantomNet:oai"
Jonathon Duerig's avatar
Jonathon Duerig committed
68 69 70
    UE_IMG  = URN.Image(PN.PNDEFS.PNET_AM, "PhantomNet:ANDROID444-STD")
    ADB_IMG = URN.Image(PN.PNDEFS.PNET_AM, "PhantomNet:UBUNTU14-64-PNTOOLS")
    OAI_EPC_IMG = URN.Image(PN.PNDEFS.PNET_AM, "PhantomNet:UBUNTU16-64-OAIEPC")
71
    OAI_ENB_IMG = URN.Image(PN.PNDEFS.PNET_AM, "PhantomNet:OAI-Real-Hardware.enb1")
Sonika's avatar
Sonika committed
72
    OAI_SIM_IMG = URN.Image(PN.PNDEFS.PNET_AM, "PhantomNet:UBUNTU14-64-OAI")
73
    OAI_CONF_SCRIPT = "/usr/bin/sudo /local/repository/bin/config_oai.pl"
Sonika's avatar
Sonika committed
74
    SIM_HWTYPE = "d430"
Jonathon Duerig's avatar
Jonathon Duerig committed
75 76 77
    NUC_HWTYPE = "nuc5300"
    UE_HWTYPE = "nexus5"

Sonika's avatar
Sonika committed
78
def connectOAI_DS(node, sim):
Jonathon Duerig's avatar
Jonathon Duerig committed
79 80
    # Create remote read-write clone dataset object bound to OAI dataset
    bs = request.RemoteBlockstore("ds-%s" % node.name, "/opt/oai")
Sonika's avatar
Sonika committed
81 82 83 84
    if sim == 1:
	bs.dataset = GLOBALS.OAI_SIM_DS
    else:
	bs.dataset = GLOBALS.OAI_DS
Jonathon Duerig's avatar
Jonathon Duerig committed
85 86 87 88 89 90 91 92 93 94 95 96 97
    bs.rwclone = True

    # Create link from node to OAI dataset rw clone
    node_if = node.addInterface("dsif_%s" % node.name)
    bslink = request.Link("dslink_%s" % node.name)
    bslink.addInterface(node_if)
    bslink.addInterface(bs.interface)
    bslink.vlan_tagging = True
    bslink.best_effort = True

#
# This geni-lib script is designed to run in the PhantomNet Portal.
#
Jonathon Duerig's avatar
Jonathon Duerig committed
98 99
pc = portal.Context()

Jonathon Duerig's avatar
Jonathon Duerig committed
100 101 102 103
#
# Profile parameters.
#
pc.defineParameter("FIXED_UE", "Bind to a specific UE",
104 105
                   portal.ParameterType.STRING, "", advanced=True,
                   longDescription="Input the name of a PhantomNet UE node to allocate (e.g., 'ue1').  Leave blank to let the mapping algorithm choose.")
Jonathon Duerig's avatar
Jonathon Duerig committed
106
pc.defineParameter("FIXED_ENB", "Bind to a specific eNodeB",
107 108
                   portal.ParameterType.STRING, "", advanced=True,
                   longDescription="Input the name of a PhantomNet eNodeB device to allocate (e.g., 'nuc1').  Leave blank to let the mapping algorithm choose.  If you bind both UE and eNodeB devices, mapping will fail unless there is path between them via the attenuator matrix.")
Jonathon Duerig's avatar
Jonathon Duerig committed
109

110
pc.defineParameter("TYPE", "Experiment type",
111
                   portal.ParameterType.STRING,"ota",[("sim","Simulated UE"),("atten","Real UE with attenuator"),("ota","Over the air")],
112
                   longDescription="*Simulated UE*: OAI simulated UE connects to an OAI eNodeB and EPC. *Real UE with attenuator*: Real RF devices will be connected via transmission lines with variable attenuator control. *Over the air*: Real RF devices with real antennas and transmissions propagated through free space will be selected.")
113

114 115 116 117
#pc.defineParameter("RADIATEDRF", "Radiated (over-the-air) RF transmissions",
#                   portal.ParameterType.BOOLEAN, False,
#                   longDescription="When enabled, RF devices with real antennas and transmissions propagated through free space will be selected.  Leave disabled (default) to assign RF devices connected via transmission lines with variable attenuator control.")

Jonathon Duerig's avatar
Jonathon Duerig committed
118 119 120 121 122 123 124 125 126 127 128 129
params = pc.bindParameters()

#
# Give the library a chance to return nice JSON-formatted exception(s) and/or
# warnings; this might sys.exit().
#
pc.verifyParameters()

#
# Create our in-memory model of the RSpec -- the resources we're going
# to request in our experiment, and their configuration.
#
Jonathon Duerig's avatar
Jonathon Duerig committed
130
request = pc.makeRequestRSpec()
Jincao Zhu's avatar
Jincao Zhu committed
131
hacklan = request.Link("s1-lan")
Jincao Zhu's avatar
Jincao Zhu committed
132
#epclink2= request.Link("s1-lan2")
Jonathon Duerig's avatar
Jonathon Duerig committed
133

Sonika's avatar
Sonika committed
134 135
# Checking for oaisim

136 137
if params.TYPE == "sim":
    sim_enb = request.RawPC("sim-enb")
Sonika's avatar
Sonika committed
138 139 140 141
    sim_enb.disk_image = GLOBALS.OAI_SIM_IMG
    sim_enb.hardware_type = GLOBALS.SIM_HWTYPE
    sim_enb.addService(rspec.Execute(shell="sh", command=GLOBALS.OAI_CONF_SCRIPT + " -r SIM_ENB"))
    connectOAI_DS(sim_enb, 1)
142 143 144 145 146 147 148 149 150 151 152 153 154
    epclink.addNode(sim_enb)
else:
    # Add a node to act as the ADB target host
    adb_t = request.RawPC("adb-tgt")
    adb_t.disk_image = GLOBALS.ADB_IMG

    # Add a NUC eNB node.
    enb1 = request.RawPC("enb1")
    if params.FIXED_ENB:
        enb1.component_id = params.FIXED_ENB
    enb1.hardware_type = GLOBALS.NUC_HWTYPE
    enb1.disk_image = GLOBALS.OAI_ENB_IMG
    enb1.Desire( "rf-radiated" if params.TYPE == "ota" else "rf-controlled", 1 )
Sonika's avatar
Sonika committed
155
    connectOAI_DS(enb1, 0)
156 157
    enb1.addService(rspec.Execute(shell="sh", command=GLOBALS.OAI_CONF_SCRIPT + " -r ENB"))
    enb1_rue1_rf = enb1.addInterface("rue1_rf")
Jincao Zhu's avatar
Jincao Zhu committed
158
    enb1_s1_if = enb1.addInterface("enb1_s1if")
Jincao Zhu's avatar
Jincao Zhu committed
159

160

161 162 163 164 165 166 167
    # Add another NUC eNB node.
    enb2 = request.RawPC("enb2")
    if params.FIXED_ENB:
        enb2.component_id = params.FIXED_ENB
    enb2.hardware_type = GLOBALS.NUC_HWTYPE
    enb2.disk_image = GLOBALS.OAI_ENB_IMG
    enb2.Desire( "rf-radiated" if params.TYPE == "ota" else "rf-controlled", 1 )
Jincao Zhu's avatar
Jincao Zhu committed
168
    connectOAI_DS(enb2, 0)
169 170
    enb2.addService(rspec.Execute(shell="sh", command=GLOBALS.OAI_CONF_SCRIPT + " -r ENB"))
    enb2_rue1_rf = enb2.addInterface("rue1_rf")
Jincao Zhu's avatar
Jincao Zhu committed
171
    enb2_s1_if = enb2.addInterface("enb2_s1if")
Jincao Zhu's avatar
Jincao Zhu committed
172

173

174
    # Add an OTS (Nexus 5) UE
Jincao Zhu's avatar
Jincao Zhu committed
175 176
    #rue1 = request.UE("rue1",component_id='ue6')
    rue1 = request.UE("rue1")
177 178 179 180 181 182 183
    if params.FIXED_UE:
        rue1.component_id = params.FIXED_UE
    rue1.hardware_type = GLOBALS.UE_HWTYPE
    rue1.disk_image = GLOBALS.UE_IMG
    rue1.Desire( "rf-radiated" if params.TYPE == "ota" else "rf-controlled", 1 )
    rue1.adb_target = "adb-tgt"
    rue1_enb1_rf = rue1.addInterface("enb1_rf")
Jincao Zhu's avatar
Jincao Zhu committed
184
    rue1_enb2_rf = rue1.addInterface("enb2_rf")
185 186

    # Create the RF link between the Nexus 5 UE and eNodeB
Jincao Zhu's avatar
Jincao Zhu committed
187 188 189
    rflink2 = request.RFLink("rflink2")
    rflink2.addInterface(enb2_rue1_rf)
    rflink2.addInterface(rue1_enb2_rf)
190 191 192 193 194 195

    rflink1 = request.RFLink("rflink1")
    rflink1.addInterface(enb1_rue1_rf)
    rflink1.addInterface(rue1_enb1_rf)
    
    
196
    # Add a link connecting the NUC eNB and the OAI EPC node.
Jincao Zhu's avatar
Jincao Zhu committed
197 198 199 200 201
    #epclink].addNode(enb1)
    #epclink2.addNode(enb2)
    hacklan.addInterface(enb1_s1_if)
    hacklan.addInterface(enb2_s1_if)

Jonathon Duerig's avatar
Jonathon Duerig committed
202 203 204 205 206

# Add OAI EPC (HSS, MME, SPGW) node.
epc = request.RawPC("epc")
epc.disk_image = GLOBALS.OAI_EPC_IMG
epc.addService(rspec.Execute(shell="sh", command=GLOBALS.OAI_CONF_SCRIPT + " -r EPC"))
Sonika's avatar
Sonika committed
207
connectOAI_DS(epc, 0)
Jincao Zhu's avatar
Jincao Zhu committed
208
epc_s1_if = epc.addInterface("epc_s1if")
209
 
Jincao Zhu's avatar
Jincao Zhu committed
210 211 212 213 214 215
#epclink.addNode(epc)
#epclink.link_multiplexing = True
#epclink.vlan_tagging = True
#epclink.best_effort = True

#epclink2.addNode(epc)
Jincao Zhu's avatar
Jincao Zhu committed
216
hacklan.addInterface(epc_s1_if)
Jincao Zhu's avatar
Jincao Zhu committed
217 218 219
hacklan.link_multiplexing = True
hacklan.vlan_tagging = True
hacklan.best_effort = True
220

221 222 223
tour = IG.Tour()
tour.Description(IG.Tour.MARKDOWN, tourDescription)
tour.Instructions(IG.Tour.MARKDOWN, tourInstructions)
224
request.addTour(tour)
225

Jonathon Duerig's avatar
Jonathon Duerig committed
226 227 228
#
# Print and go!
#
229
pc.printRequestRSpec(request)