def put(self, *args, **kwargs):
        """Update an account.

        Args:
            [0]: the username

        Request:
            version: protocol version (1.0)
            username: username
            password: password
            role: tole
            name: name
            surname: surname
            email: email

        Example URLs:
            PUT /api/v1/accounts/test
            {
              "version" : 1.0,
              "username" : "foo",
              "password" : "foo",
              "role" : "user",
              "name" : "foo",
              "surname" : "foo",
              "email" : "*****@*****.**"
            }
        """

        RUNTIME.update_account(args[0], kwargs)
Beispiel #2
0
    def delete(self, *args, **kwargs):
        """ Unload a component.

        Args:
            tenant_id: the tenant id
            component_id: the id of a component istance

        Example URLs:

            DELETE /api/v1/tenants/52313ecb-9d00-4b7d-b873-b55d3d9ada26/<id>

        """

        try:

            if len(args) != 2:
                raise ValueError("Invalid url")

            tenant_id = UUID(args[0])
            app_id = args[1]

            RUNTIME.unregister_app(tenant_id, app_id)

        except ValueError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)

        self.set_status(204, None)
Beispiel #3
0
    def delete(self, *args, **kwargs):
        """ Delete a tenant request.

        Args:
            tenant_id: network name of a tenant

        Example URLs:

            PUT /api/v1/pending/52313ecb-9d00-4b7d-b873-b55d3d9ada26

        """

        try:

            if len(args) == 0:

                pendings = RUNTIME.load_pending_tenants()

                for pending in pendings:
                    RUNTIME.reject_tenant(pending.tenant_id)

            else:

                tenant_id = UUID(args[0])
                RUNTIME.reject_tenant(tenant_id)

        except ValueError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)
        self.set_status(204, None)
    def delete(self, *args, **kwargs):
        """ Unload a component.

        Args:
            tenant_id: the tenant id
            component_id: the id of a component istance

        Example URLs:

            DELETE /api/v1/tenants/52313ecb-9d00-4b7d-b873-b55d3d9ada26/<id>

        """

        try:

            if len(args) != 2:
                raise ValueError("Invalid url")

            tenant_id = UUID(args[0])
            app_id = args[1]

            RUNTIME.unregister_app(tenant_id, app_id)

        except ValueError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)

        self.set_status(204, None)
Beispiel #5
0
    def delete(self, *args, **kwargs):
        """ Unload a component.

        Args:
            component_id: the id of a component istance

        Example URLs:

            DELETE /api/v1/components/component

        """

        try:

            if len(args) != 1:
                raise ValueError("Invalid url")

            RUNTIME.unregister(args[0])

        except ValueError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)

        self.set_status(204, None)
    def delete(self, *args, **kwargs):
        """ Unload a component.

        Args:
            username: the username

        Example URLs:

            DELETE /api/v1/accounts/test

        """

        try:

            if len(args) != 1:
                raise ValueError("Invalid url")

            RUNTIME.remove_account(args[0])

        except ValueError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)

        self.set_status(204, None)
    def delete(self, *args, **kwargs):
        """ Unload a component.

        Args:
            component_id: the id of a component istance

        Example URLs:

            DELETE /api/v1/components/component

        """

        try:

            if len(args) != 1:
                raise ValueError("Invalid url")

            RUNTIME.unregister(args[0])

        except ValueError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)

        self.set_status(204, None)
Beispiel #8
0
    def _handle_ue_ho_response(self, vbs, hdr, event, ho):
        """Handle an incoming UE_HO_RESPONSE message.
        Args:
            ho, a UE_HO_RESPONSE message
        Returns:
            None
        """

        addr = hex_to_ether(ho.origin_eNB)
        origin_vbs = RUNTIME.vbses[addr]
        ue = RUNTIME.find_ue_by_rnti(ho.origin_rnti, ho.origin_pci, origin_vbs)

        if event.op == EP_OPERATION_SUCCESS:

            # UE was removed from source eNB
            if ue.is_ho_in_progress_removing():
                ue.set_ho_in_progress_adding()
                return

            # UE was added to target eNB
            if ue.is_ho_in_progress_adding():
                ue._cell = vbs.get_cell_by_pci(hdr.cellid)
                ue.rnti = ho.target_rnti
                ue.set_active()
                return

        self.log.error("Error while performing handover")
        RUNTIME.remove_ue(ue.ue_id)
    def _on_disconnect(self):
        """ Handle WTP disconnection """

        if not self.wtp:
            return

        self.log.info("WTP disconnected: %s", self.wtp.addr)

        # remove hosted lvaps
        for lvap in list(RUNTIME.lvaps.values()):
            wtps = [x.radio for x in lvap.blocks]
            if self.wtp in wtps:
                RUNTIME.remove_lvap(lvap.addr)

        # remove hosted vaps
        for tenant_id in list(RUNTIME.tenants.keys()):
            for vap_id in list(RUNTIME.tenants[tenant_id].vaps.keys()):
                vap = RUNTIME.tenants[tenant_id].vaps[vap_id]
                if vap.block.radio == self.wtp:
                    self.log.info("Deleting VAP: %s", vap.bssid)
                    del RUNTIME.tenants[tenant_id].vaps[vap.bssid]

        # reset state
        self.wtp.set_disconnected()
        self.wtp.last_seen = 0
        self.wtp.connection = None
        self.wtp.supports = set()
        self.wtp.datapath = None
        self.wtp = None
    def post(self, *args, **kwargs):
        """Create a new account.

        Request:
            version: protocol version (1.0)
            username: username
            password: password
            role: tole
            name: name
            surname: surname
            email: email

        Example URLs:
            POST /api/v1/accounts
            {
              "version" : 1.0,
              "username" : "foo",
              "password" : "foo",
              "role" : "user",
              "name" : "foo",
              "surname" : "foo",
              "email" : "*****@*****.**"
            }
        """

        RUNTIME.create_account(kwargs['username'], kwargs['password'],
                               kwargs['role'], kwargs['name'],
                               kwargs['surname'], kwargs['email'])
Beispiel #11
0
    def delete(self, *args, **kwargs):
        """ Unload a component.

        Args:
            username: the username

        Example URLs:

            DELETE /api/v1/accounts/test

        """

        try:

            if len(args) != 1:
                raise ValueError("Invalid url")

            RUNTIME.remove_account(args[0])

        except ValueError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)

        self.set_status(204, None)
    def post(self, *args, **kwargs):
        """Add a component.

        Request:

            version: protocol version (1.0)
            component: the component id
            params: dictionary of parametes supported by the component
                    as reported by the GET request

        Example URLs:
            POST /api/v1/components
            {
              "version" : 1.0,
              "component" : "empower.apps.mobilitymanager.mobilitymanager"
              "params": {
                "every": 1000
              }
            }
        """

        func = getattr(import_module(kwargs["component"]), "launch")

        if "params" in kwargs:
            RUNTIME.register(kwargs["component"], func, kwargs["params"])
        else:
            RUNTIME.register(kwargs["component"], func, dict())
Beispiel #13
0
    def get(self, *args, **kwargs):
        """ Lists all the tenants requested. Returns 404 if the requested
        tenant does not exists.

        Args:
            tenant_id: network name of a tenant

        Example URLs:

            GET /api/v1/pending
            GET /api/v1/pending/TenantName

        """

        try:
            if len(args) > 1:
                raise ValueError("Invalid url")
            if len(args) == 0:
                user = self.get_argument("user", default=None)
                if user:
                    pendings = RUNTIME.load_pending_tenants(user)
                else:
                    pendings = RUNTIME.load_pending_tenants()
                self.write(json.dumps(pendings, cls=EmpowerEncoder))
            else:
                tenant_id = UUID(args[0])
                pending = RUNTIME.load_pending_tenant(tenant_id)
                self.write(json.dumps(pending, cls=EmpowerEncoder))
        except ValueError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)
    def post(self, *args, **kwargs):
        """ Add a component.

        Args:
            [0]: the tenant id

        Request:
            version: protocol version (1.0)
            component: module name
            params: dictionary of parametes supported by the component
                    as reported by the GET request

        Example URLs:
            POST /api/v1/components
            {
              "version" : 1.0,
              "component" : "empower.lvapp.bin_counter.bin_counter"
              "params": {}
            }
        """

        func = getattr(import_module(kwargs["component"]), "launch")

        kwargs["params"]["tenant_id"] = UUID(args[0])

        RUNTIME.register_app(kwargs["component"], func, kwargs["params"])
Beispiel #15
0
    def _on_disconnect(self):
        """ Handle WTP disconnection """

        if not self.wtp:
            return

        LOG.info("WTP disconnected: %s", self.wtp.addr)

        # remove hosted lvaps
        for addr in list(RUNTIME.lvaps.keys()):
            lvap = RUNTIME.lvaps[addr]
            dl_wtps = [block.radio for block in lvap.downlink.keys()]
            ul_wtps = [block.radio for block in lvap.uplink.keys()]
            # in case the downlink went down, the remove also the uplinks
            if self.wtp in dl_wtps:
                RUNTIME.remove_lvap(lvap.addr)
            elif self.wtp in ul_wtps:
                LOG.info("Deleting LVAP (UL): %s", lvap.addr)
                lvap.clear_uplink()

        # remove hosted vaps
        for tenant_id in RUNTIME.tenants.keys():
            for vap_id in list(RUNTIME.tenants[tenant_id].vaps.keys()):
                vap = RUNTIME.tenants[tenant_id].vaps[vap_id]
                if vap.wtp == self.wtp:
                    LOG.info("Deleting VAP: %s", vap.net_bssid)
                    del RUNTIME.tenants[tenant_id].vaps[vap.net_bssid]

        # reset state
        self.wtp.last_seen = 0
        self.wtp.connection = None
        self.wtp.ports = {}
        self.wtp.supports = set()
        self.wtp = None
    def _on_disconnect(self):
        """ Handle WTP disconnection """

        if not self.wtp:
            return

        LOG.info("WTP disconnected: %s", self.wtp.addr)

        # remove hosted lvaps
        for addr in list(RUNTIME.lvaps.keys()):
            lvap = RUNTIME.lvaps[addr]
            dl_wtps = [block.radio for block in lvap.downlink.keys()]
            ul_wtps = [block.radio for block in lvap.uplink.keys()]
            # in case the downlink went down, the remove also the uplinks
            if self.wtp in dl_wtps:
                RUNTIME.remove_lvap(lvap.addr)
            elif self.wtp in ul_wtps:
                LOG.info("Deleting LVAP (UL): %s", lvap.addr)
                lvap.clear_uplink()

        # remove hosted vaps
        for tenant_id in RUNTIME.tenants.keys():
            for vap_id in list(RUNTIME.tenants[tenant_id].vaps.keys()):
                vap = RUNTIME.tenants[tenant_id].vaps[vap_id]
                if vap.wtp == self.wtp:
                    LOG.info("Deleting VAP: %s", vap.net_bssid)
                    del RUNTIME.tenants[vap.tenant_id].vaps[vap.net_bssid]

        # reset state
        self.wtp.last_seen = 0
        self.wtp.connection = None
        self.wtp.ports = {}
        self.wtp.supports = ResourcePool()
        self.wtp = None
    def _handle_auth_request(self, wtp, request):
        """Handle an incoming AUTH_REQUEST message.
        Args:
            request, a AUTH_REQUEST message
        Returns:
            None
        """

        if not wtp.connection:
            LOG.info("Auth request from disconnected WTP %s", wtp.addr)
            return

        sta = EtherAddress(request.sta)
        bssid = EtherAddress(request.bssid)

        if sta not in RUNTIME.lvaps:
            LOG.info("Auth request from unknown LVAP %s", sta)
            return

        lvap = RUNTIME.lvaps[sta]

        if not RUNTIME.is_allowed(sta):
            LOG.info("Auth request from %s ignored (white list)", sta)
            return

        if RUNTIME.is_denied(sta):
            LOG.info("Auth request from %s ignored (black list)", sta)
            return

        lvap_bssid = None

        # the request bssid is the lvap's unique bssid
        if lvap.net_bssid == bssid:

            lvap_bssid = lvap.net_bssid

        # else if is a shared bssid
        else:

            shared_tenants = [x for x in RUNTIME.tenants.values()
                              if x.bssid_type == T_TYPE_SHARED]

            wtp = RUNTIME.wtps[wtp.addr]

            # look for bssid in shared tenants
            for tenant in shared_tenants:
                if bssid in tenant.vaps and tenant.vaps[bssid].wtp == wtp:
                    lvap_bssid = bssid
                    break

        # invalid bssid, ignore request
        if not lvap_bssid:
            return

        # this will trigger an add lvap message to update the bssid
        lvap.lvap_bssid = lvap_bssid

        LOG.info("Auth request from %s for BSSID %s, replying", sta, bssid)

        self.send_auth_response(lvap)
    def post(self, *args, **kwargs):
        """Create a new tenant.

        Args:
            [0], the tenant id

        Request:
            version: protocol version (1.0)
            owner: the username of the requester
            tenant_name: the network name
            desc: a description for the new tenant
            bssid_type: shared or unique
            plmn_id: the PLMN id
        """

        bssid_type = kwargs["bssid_type"] \
            if "bssid_type" in kwargs else T_TYPE_UNIQUE

        plmn_id = PLMNID(kwargs["plmn_id"]) if "plmn_id" in kwargs else None

        tenant_id = UUID(args[0]) if args else None

        RUNTIME.add_tenant(kwargs['owner'], kwargs['desc'],
                           kwargs['tenant_name'], bssid_type, tenant_id,
                           plmn_id)

        self.set_header("Location", "/api/v1/tenants/%s" % tenant_id)
    def get(self, *args, **kwargs):
        """ Lists all the tenants requested. Returns 404 if the requested
        tenant does not exists.

        Args:
            tenant_id: network name of a tenant

        Example URLs:

            GET /api/v1/pending
            GET /api/v1/pending/TenantName

        """

        try:
            if len(args) > 1:
                raise ValueError("Invalid url")
            if len(args) == 0:
                user = self.get_argument("user", default=None)
                if user:
                    pendings = RUNTIME.load_pending_tenants(user)
                else:
                    pendings = RUNTIME.load_pending_tenants()
                self.write_as_json(pendings)
            else:
                tenant_id = UUID(args[0])
                pending = RUNTIME.load_pending_tenant(tenant_id)
                self.write_as_json(pending)
        except ValueError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)
Beispiel #20
0
    def _handle_auth_request(self, wtp, request):
        """Handle an incoming AUTH_REQUEST message.
        Args:
            request, a AUTH_REQUEST message
        Returns:
            None
        """

        if not wtp.connection:
            LOG.info("Auth request from disconnected WTP %s", wtp.addr)
            return

        sta = EtherAddress(request.sta)
        bssid = EtherAddress(request.bssid)

        if sta not in RUNTIME.lvaps:
            LOG.info("Auth request from unknown LVAP %s", sta)
            return

        lvap = RUNTIME.lvaps[sta]

        if not RUNTIME.is_allowed(sta):
            LOG.info("Auth request from %s ignored (white list)", sta)
            return

        if RUNTIME.is_denied(sta):
            LOG.info("Auth request from %s ignored (black list)", sta)
            return

        lvap_bssid = None

        # the request bssid is the lvap's unique bssid
        if lvap.net_bssid == bssid:

            lvap_bssid = lvap.net_bssid

        # else if is a shared bssid
        else:

            shared_tenants = [x for x in RUNTIME.tenants.values()
                              if x.bssid_type == T_TYPE_SHARED]

            wtp = RUNTIME.wtps[wtp.addr]

            # look for bssid in shared tenants
            for tenant in shared_tenants:
                if bssid in tenant.vaps and tenant.vaps[bssid].wtp == wtp:
                    lvap_bssid = bssid
                    break

        # invalid bssid, ignore request
        if not lvap_bssid:
            return

        # this will trigger an add lvap message to update the bssid
        lvap.lvap_bssid = lvap_bssid

        LOG.info("Auth request from %s for BSSID %s, replying", sta, bssid)

        self.send_auth_response(lvap)
Beispiel #21
0
    def delete(self, *args, **kwargs):
        """ Delete a tenant.

        Args:
            tenant_id: network name of a tenant

        Request:
            version: protocol version (1.0)

        Example URLs:

            DELETE /api/v1/tenants/52313ecb-9d00-4b7d-b873-b55d3d9ada26

        """
        try:

            if len(args) == 0:

                for tenant in list(RUNTIME.tenants.keys()):
                    RUNTIME.remove_tenant(tenant)

            else:

                tenant_id = UUID(args[0])
                RUNTIME.remove_tenant(tenant_id)

        except ValueError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)
        self.set_status(204, None)
    def delete(self, *args, **kwargs):
        """ Delete a tenant request.

        Args:
            tenant_id: network name of a tenant

        Example URLs:

            PUT /api/v1/pending/52313ecb-9d00-4b7d-b873-b55d3d9ada26

        """

        try:

            if len(args) == 0:

                pendings = RUNTIME.load_pending_tenants()

                for pending in pendings:
                    RUNTIME.reject_tenant(pending.tenant_id)

            else:

                tenant_id = UUID(args[0])
                RUNTIME.reject_tenant(tenant_id)

        except ValueError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)
        self.set_status(204, None)
    def delete(self, *args, **kwargs):
        """ Delete a tenant.

        Args:
            tenant_id: network name of a tenant

        Request:
            version: protocol version (1.0)

        Example URLs:

            DELETE /api/v1/tenants/52313ecb-9d00-4b7d-b873-b55d3d9ada26

        """
        try:

            if len(args) == 0:

                for tenant in list(RUNTIME.tenants.keys()):
                    RUNTIME.remove_tenant(tenant)

            else:

                tenant_id = UUID(args[0])
                RUNTIME.remove_tenant(tenant_id)

        except ValueError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)
        self.set_status(204, None)
Beispiel #24
0
    def _running_disconnecting(self):

        self._state = PROCESS_DISCONNECTING

        from empower.main import RUNTIME

        # remove UE from the RUNTIME
        RUNTIME.remove_ue(self.ue_id)
    def _handle_assoc_request(self, request):
        """Handle an incoming ASSOC_REQUEST message.
        Args:
            request, a ASSOC_REQUEST message
        Returns:
            None
        """

        wtp_addr = EtherAddress(request.wtp)

        try:
            wtp = RUNTIME.wtps[wtp_addr]
        except KeyError:
            LOG.info("Assoc request from unknown WTP %s", wtp_addr)
            return

        if not wtp.connection:
            LOG.info("Assoc request from disconnected WTP %s", wtp_addr)
            return

        sta = EtherAddress(request.sta)

        if sta not in RUNTIME.lvaps:
            LOG.info("Assoc request from unknown LVAP %s", sta)
            return

        lvap = RUNTIME.lvaps[sta]

        if not RUNTIME.is_allowed(sta):
            LOG.info("Assoc request from %s ignored (white list)", sta)
            return

        if RUNTIME.is_denied(sta):
            LOG.info("Assoc request from %s ignored (black list)", sta)
            return

        ssid = SSID(request.ssid.decode('UTF-8'))

        matches = [x for x in RUNTIME.tenants.values()
                   if SSID(x.tenant_name) == ssid]

        if not matches:
            LOG.info("Assoc request to unknown SSID: %s ", request.ssid)
            return

        # this will trigger an add lvap message to update the ssid
        lvap.ssid = ssid

        # this will trigger an add lvap message to update the assoc id
        lvap.assoc_id = self.server.assoc_id

        LOG.info("Assoc request sta %s assoc id %u ssid %s, sending response",
                 lvap.addr,
                 lvap.assoc_id,
                 lvap.ssid)

        self.send_assoc_response(lvap)
Beispiel #26
0
    def _handle_ue_report_response(self, vbs, hdr, event, ue_report):
        """Handle an incoming UE_REPORT message.
        Args:
            hello, a UE_REPORT message
        Returns:
            None
        """

        incoming = []

        for ue in ue_report.ues:

            if RUNTIME.find_ue_by_rnti(ue.rnti, ue.pci, vbs):
                continue

            plmn_id = PLMNID(ue.plmn_id[1:].hex())
            tenant = RUNTIME.load_tenant_by_plmn_id(plmn_id)

            if not tenant:
                self.log.info("Unable to find PLMN id %s", plmn_id)
                continue

            if vbs.addr not in tenant.vbses:
                self.log.info("VBS %s not in PLMN id %s", vbs.addr, plmn_id)
                continue

            cell = vbs.get_cell_by_pci(ue.pci)

            if not cell:
                self.log.info("PCI %u not found", u.pci)
                continue

            if ue.imsi != 0:
                ue_id = uuid.uuid5(uuid.NAMESPACE_DNS, str(ue.imsi))
            else:
                ue_id = uuid.uuid4()

            ue = UE(ue_id, ue.imsi, ue.rnti, cell, plmn_id, tenant)
            ue.set_active()

            RUNTIME.ues[ue.ue_id] = ue
            tenant.ues[ue.ue_id] = ue

            incoming.append(ue.ue_id)

            self.server.send_ue_join_message_to_self(ue)

        # check for leaving UEs
        for ue_id in list(RUNTIME.ues.keys()):
            if RUNTIME.ues[ue_id].vbs != vbs:
                continue
            if not RUNTIME.ues[ue_id].is_active():
                self.log.info("Handover in progress for %u, ignoring", ue_id)
                continue
            if ue_id not in incoming:
                RUNTIME.remove_ue(ue_id)
Beispiel #27
0
    def delete(self, *args, **kwargs):
        """Unload a component.

        Args:
            component_id: the id of a component istance

        Example URLs:
            DELETE /api/v1/components/component
        """

        RUNTIME.unregister(args[0])
Beispiel #28
0
    def put(self, *args, **kwargs):
        """ Update an account.

        Args:
            username: the username

        Request:
            version: protocol version (1.0)
            username: username
            password: password
            role: tole
            name: name
            surname: surname
            email: email

        Example URLs:

            PUT /api/v1/accounts/test
            {
              "version" : 1.0,
              "username" : "foo",
              "password" : "foo",
              "role" : "user",
              "name" : "foo",
              "surname" : "foo",
              "email" : "*****@*****.**"
            }

        """

        try:

            if len(args) != 1:
                raise ValueError("Invalid url")

            request = tornado.escape.json_decode(self.request.body)

            if "version" not in request:
                raise ValueError("missing version element")

            del request['version']

            RUNTIME.update_account(args[0], request)

        except ValueError as ex:
            self.send_error(400, message=ex)
        except AttributeError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)

        self.set_status(204, None)
    def _handle_ue_report_response(self, vbs, hdr, event, msg):
        """Handle an incoming UE_REPORT message.
        Args:
            hello, a UE_REPORT message
        Returns:
            None
        """

        for raw_entry in msg.options:

            if raw_entry.type not in UE_REPORT_TYPES:
                self.log.warning("Unknown options %u", raw_entry)
                continue

            prop = UE_REPORT_TYPES[raw_entry.type].name
            option = UE_REPORT_TYPES[raw_entry.type].parse(raw_entry.data)

            self.log.warning("Processing options %s", prop)

            if raw_entry.type == EP_UE_REPORT_IDENTITY:

                plmn_id = PLMNID(option.plmn_id)
                tenant = RUNTIME.load_tenant_by_plmn_id(plmn_id)

                if not tenant:
                    self.log.info("Unknown tenant %s", plmn_id)
                    continue

                # TODO: Implement fallback mechanism IMSI->TMSI->RNTI
                ue_id = uuid.UUID(int=option.imsi)

                # UE already known, update its parameters
                if ue_id in RUNTIME.ues:

                    ue = RUNTIME.ues[ue_id]
                    ue.rnti = option.rnti

                    # UE is disconnecting
                    if option.state == 1:
                        RUNTIME.remove_ue(ue_id)

                else:

                    cell = vbs.cells[hdr.cellid]

                    ue = UE(ue_id, option.rnti, option.imsi, option.timsi,
                            cell, tenant)

                    RUNTIME.ues[ue.ue_id] = ue
                    tenant.ues[ue.ue_id] = ue

                    # UE is connected
                    if option.state == 0:
                        self.server.send_ue_join_message_to_self(ue)
    def delete(self, *args, **kwargs):
        """Unload a component.

        Args:
            [0]: the username

        Example URLs:
            DELETE /api/v1/accounts/test
        """

        RUNTIME.remove_account(args[0])
    def delete(self, *args, **kwargs):
        """ Delete entry from ACL.

        Args:
            [0]: the station address

        Example URLs:

            DELETE /api/v1/allow/11:22:33:44:55:66
        """

        RUNTIME.remove_allowed(EtherAddress(args[0]))
Beispiel #32
0
    def _handle_ue_report_response(self, vbs, hdr, event, ue_report):
        """Handle an incoming UE_REPORT message.
        Args:
            hello, a UE_REPORT message
        Returns:
            None
        """

        ues = {u.imsi: u for u in ue_report.ues}

        # check for new UEs
        for u in ues.values():

            # UE already known
            if u.imsi in RUNTIME.ues:
                continue

            plmn_id = PLMNID(u.plmn_id[1:].hex())
            tenant = RUNTIME.load_tenant_by_plmn_id(plmn_id)

            if not tenant:
                self.log.info("Unable to find PLMN id %s", plmn_id)
                continue

            if vbs.addr not in tenant.vbses:
                self.log.info("VBS %s not in PLMN id %s", vbs.addr, plmn_id)
                continue

            cell = None

            for c in vbs.cells:
                if c.pci == u.pci:
                    cell = c
                    break

            if not cell:
                self.log.info("PCI %u not found", u.pci)
                continue

            ue = UE(u.imsi, u.rnti, cell, plmn_id, tenant)
            ue.set_active()

            RUNTIME.ues[u.imsi] = ue
            tenant.ues[u.imsi] = ue

            self.server.send_ue_join_message_to_self(ue)

        # check for leaving UEs
        for imsi in list(RUNTIME.ues.keys()):
            if RUNTIME.ues[imsi].vbs != vbs:
                continue
            if imsi not in ues:
                RUNTIME.remove_ue(imsi)
    def delete(self, *args, **kwargs):
        """Delete a tenant.

        Args:
            [0]: network name of a tenant

        Example URLs:
            DELETE /api/v1/tenants
            DELETE /api/v1/tenants/52313ecb-9d00-4b7d-b873-b55d3d9ada26
        """

        RUNTIME.remove_tenant(UUID(args[0]))
Beispiel #34
0
    def put(self, *args, **kwargs):
        """ Update an account.

        Args:
            username: the username

        Request:
            version: protocol version (1.0)
            username: username
            password: password
            role: tole
            name: name
            surname: surname
            email: email

        Example URLs:

            PUT /api/v1/accounts/test
            {
              "version" : 1.0,
              "username" : "foo",
              "password" : "foo",
              "role" : "user",
              "name" : "foo",
              "surname" : "foo",
              "email" : "*****@*****.**"
            }

        """

        try:

            if len(args) != 1:
                raise ValueError("Invalid url")

            request = tornado.escape.json_decode(self.request.body)

            if "version" not in request:
                raise ValueError("missing version element")

            del request['version']

            RUNTIME.update_account(args[0], request)

        except ValueError as ex:
            self.send_error(400, message=ex)
        except AttributeError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)

        self.set_status(204, None)
    def delete(self, *args, **kwargs):
        """Unload a component.

        Args:

            [0]: the component id

        Example URLs:

            DELETE /api/v1/components/
              empower.apps.mobilitymanager.mobilitymanager
        """

        RUNTIME.unregister(args[0])
    def delete(self, *args, **kwargs):
        """ Unload a component.

        Args:
            tenant_id: the tenant id
            component_id: the id of a component istance

        Example URLs:

            DELETE /api/v1/tenants/52313ecb-9d00-4b7d-b873-b55d3d9ada26/<id>

        """

        RUNTIME.unregister_app(UUID(args[0]), args[1])
    def put(self, *args, **kwargs):
        """Update a component.

        Args:

            [0]: the component id

        Request:

            version: protocol version (1.0)
            params: dictionary of parametes supported by the component
                    as reported by the GET request

        Example URLs:

            PUT /api/v1/components/empower.apps.mobilitymanager.mobilitymanager
            {
              "version" : 1.0,
              "params": {
                "every": 1000
              }
            }
        """

        components = RUNTIME.load_main_components()
        component = components[args[0]]

        for param in kwargs['params']:

            if "params" not in component or param not in component['params']:
                msg = "Cannot set %s on compoment %s" % (param, args[0])
                raise ValueError(msg)

            setattr(component, param, kwargs['params'][param])
Beispiel #38
0
    def _handle_status_vap(cls, wtp, status):
        """Handle an incoming STATUS_VAP message.
        Args:
            status, a STATUS_VAP message
        Returns:
            None
        """

        if not wtp.connection:
            LOG.info("VAP Status from disconnected WTP %s", wtp.addr)
            return

        net_bssid_addr = EtherAddress(status.net_bssid)
        ssid = SSID(status.ssid)
        tenant = RUNTIME.load_tenant(ssid)

        if not tenant:
            LOG.info("VAP %s from unknown tenant %s", net_bssid_addr, ssid)
            return

        incoming = ResourceBlock(wtp, EtherAddress(status.hwaddr),
                                 status.channel, status.band)

        LOG.info("VAP status update from %s", net_bssid_addr)

        # If the VAP does not exists, then create a new one
        if net_bssid_addr not in tenant.vaps:
            vap = VAP(net_bssid_addr, incoming, wtp, tenant)
            tenant.vaps[net_bssid_addr] = vap

        vap = tenant.vaps[net_bssid_addr]

        LOG.info("VAP status %s", vap)
    def _handle_status_vap(self, wtp, status):
        """Handle an incoming STATUS_VAP message.
        Args:
            status, a STATUS_VAP message
        Returns:
            None
        """

        bssid = EtherAddress(status.bssid)
        ssid = SSID(status.ssid)
        tenant = RUNTIME.load_tenant(ssid)

        if not tenant:
            self.log.info("VAP %s from unknown tenant %s", bssid, ssid)
            return

        # Check if block is valid
        valid = wtp.get_block(status.hwaddr, status.channel, status.band)

        if not valid:
            self.log.warning("No valid intersection found. Removing VAP.")
            wtp.connection.send_del_vap(bssid)
            return

        # If the VAP does not exists, then create a new one
        if bssid not in tenant.vaps:
            vap = VAP(bssid, valid, tenant)
            tenant.vaps[bssid] = vap

        vap = tenant.vaps[bssid]

        self.log.info("VAP status %s", vap)
Beispiel #40
0
    def send_del_ran_mac_slice_request(self, cell, plmn_id, dscp):
        """Send an DEL_SLICE message. """

        tenant = RUNTIME.load_tenant_by_plmn_id(plmn_id)

        # check if tenant is valid
        if not tenant:
            self.log.info("Unknown tenant %s", plmn_id)
            return

        # check if slice is valid
        if dscp in tenant.slices:
            # UEs already present in the slice must be moved to the default slice
            # before deleting the current slice
            for ue in list(RUNTIME.ues.values()):

                if self.vbs == ue.vbs and dscp == ue.slice:
                    ue.slice = DSCP("0x00")
        else:
            self.log.warning("DSCP %s not found. Removing slice.", dscp)

        # Then proceed to remove the current slice
        msg = Container(plmn_id=plmn_id.to_raw(),
                        dscp=dscp.to_raw(),
                        padding=b'\x00\x00\x00',
                        length=REM_RAN_MAC_SLICE_REQUEST.sizeof())

        self.send_message(msg,
                          E_TYPE_SINGLE,
                          EP_ACT_RAN_MAC_SLICE,
                          REM_RAN_MAC_SLICE_REQUEST,
                          opcode=EP_OPERATION_REM,
                          cellid=cell.pci)
Beispiel #41
0
    def post(self, *args, **kwargs):
        """ Create a new tenant.

        Args:
            None

        Request:
            version: protocol version (1.0)
            owner: the username of the requester
            tenant_id: the network name
            desc: a description for the new tenant

        Example URLs:

            POST /api/v1/tenants

        """

        try:

            if len(args) > 1:
                raise ValueError("Invalid url")

            request = tornado.escape.json_decode(self.request.body)

            if "version" not in request:
                raise ValueError("missing version element")

            if "owner" not in request:
                raise ValueError("missing owner element")

            if "desc" not in request:
                raise ValueError("missing desc element")

            if "tenant_name" not in request:
                raise ValueError("missing tenant_name element")

            if len(args) == 1:
                tenant_id = UUID(args[0])
            else:
                tenant_id = None

            tenant_id = \
                RUNTIME.add_tenant(request['owner'],
                                   request['desc'],
                                   request['tenant_name'],
                                   tenant_id)

            self.set_header("Location", "/api/v1/tenants/%s" % tenant_id)

        except ValueError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)

        self.set_status(201, None)
    def _on_disconnect(self):
        """Handle VBSP disconnection."""

        if not self.vbs:
            return

        LOG.info("VBS disconnected: %s", self.vbs.addr)

        # remove hosted ues
        for addr in list(RUNTIME.ues.keys()):
            ue = RUNTIME.ues[addr]
            if ue.vbs == self.vbs:
                RUNTIME.remove_ue(ue.addr)

        # reset state
        self.vbs.last_seen = 0
        self.vbs.connection = None
        self.vbs.ues = {}
        self.vbs.period = 0
 def post(self):
     username = self.get_argument("username", "")
     password = self.get_argument("password", "")
     if RUNTIME.check_permission(username, password):
         self.set_secure_cookie("user", username)
         self.redirect(self.get_argument("next", "/"))
     else:
         error_msg = "Login incorrect."
         self.redirect("/auth/login/" +
                       "?error=" +
                       tornado.escape.url_escape(error_msg))
    def _handle_auth_request(self, request):
        """Handle an incoming AUTH_REQUEST message.
        Args:
            request, a AUTH_REQUEST message
        Returns:
            None
        """

        wtp_addr = EtherAddress(request.wtp)

        try:
            wtp = RUNTIME.wtps[wtp_addr]
        except KeyError:
            LOG.info("Auth request from unknown WTP %s", wtp_addr)
            return

        if not wtp.connection:
            LOG.info("Auth request from disconnected WTP %s", wtp_addr)
            return

        sta = EtherAddress(request.sta)

        if sta not in RUNTIME.lvaps:
            LOG.info("Auth request from unknown LVAP %s", sta)
            return

        lvap = RUNTIME.lvaps[sta]

        if not RUNTIME.is_allowed(sta):
            LOG.info("Auth request from %s ignored (white list)", sta)
            return

        if RUNTIME.is_denied(sta):
            LOG.info("Auth request from %s ignored (black list)", sta)
            return

        LOG.info("Auth request from %s, sending auth response", sta)
        self.send_auth_response(lvap)
    def _handle_status_lvap(self, status):
        """Handle an incoming STATUS_LVAP message.
        Args:
            status, a STATUS_LVAP message
        Returns:
            None
        """

        wtp_addr = EtherAddress(status.wtp)

        try:
            wtp = RUNTIME.wtps[wtp_addr]
        except KeyError:
            LOG.info("Status from unknown WTP %s", wtp_addr)
            return

        if not wtp.connection:
            LOG.info("Status from disconnected WTP %s", wtp_addr)
            return

        sta_addr = EtherAddress(status.sta)
        set_mask = bool(status.flags.set_mask)

        lvap = None
        hwaddr = EtherAddress(status.hwaddr)
        block = ResourceBlock(wtp, hwaddr, status.channel, status.band)

        LOG.info("LVAP status update from %s", sta_addr)

        # If the LVAP does not exists, then create a new one
        if sta_addr not in RUNTIME.lvaps:

            net_bssid_addr = EtherAddress(status.net_bssid)
            lvap_bssid_addr = EtherAddress(status.lvap_bssid)
            lvap = LVAP(sta_addr, net_bssid_addr, lvap_bssid_addr)

            # TODO: This should be built starting from the status message
            lvap.supports.add(ResourceBlock(lvap, sta_addr, 1, BT_L20))
            lvap.supports.add(ResourceBlock(lvap, sta_addr, 2, BT_L20))
            lvap.supports.add(ResourceBlock(lvap, sta_addr, 3, BT_L20))
            lvap.supports.add(ResourceBlock(lvap, sta_addr, 4, BT_L20))
            lvap.supports.add(ResourceBlock(lvap, sta_addr, 5, BT_L20))
            lvap.supports.add(ResourceBlock(lvap, sta_addr, 6, BT_L20))
            lvap.supports.add(ResourceBlock(lvap, sta_addr, 7, BT_L20))
            lvap.supports.add(ResourceBlock(lvap, sta_addr, 8, BT_L20))
            lvap.supports.add(ResourceBlock(lvap, sta_addr, 9, BT_L20))
            lvap.supports.add(ResourceBlock(lvap, sta_addr, 10, BT_L20))
            lvap.supports.add(ResourceBlock(lvap, sta_addr, 11, BT_L20))
            lvap.supports.add(ResourceBlock(lvap, sta_addr, 36, BT_L20))
            lvap.supports.add(ResourceBlock(lvap, sta_addr, 48, BT_L20))

            RUNTIME.lvaps[sta_addr] = lvap

        lvap = RUNTIME.lvaps[sta_addr]

        # incoming block
        pool = ResourcePool()
        pool.add(block)

        match = wtp.supports & pool

        if not match:
            LOG.error("Incoming block %s is invalid", block)
            return

        # this will try to updated the lvap object with the resource block
        # coming in this status update message.
        try:

            if set_mask:

                # set downlink+uplink block
                lvap._downlink.setitem(block, RadioPort(lvap, block))

            else:

                # set uplink only blocks
                lvap._uplink.setitem(block, RadioPort(lvap, block))

        except ValueError:
            LOG.error("Error while importing block %s, removing.", block)
            block.radio.connection.send_del_lvap(lvap)
            return

        lvap.authentication_state = bool(status.flags.authenticated)
        lvap.association_state = bool(status.flags.associated)

        lvap._assoc_id = status.assoc_id
        lvap._encap = EtherAddress(status.encap)
        ssids = [SSID(x.ssid) for x in status.ssids]

        if lvap.ssid:

            # Raise LVAP leave event
            LOG.info("LVAP LEAVE %s (%s)", lvap.addr, lvap.ssid)
            for handler in self.server.pt_types_handlers[PT_LVAP_LEAVE]:
                handler(lvap)

            # removing LVAP from tenant, need first to look for right tenant
            if lvap.addr in lvap.tenant.lvaps:
                LOG.info("Removing %s from tenant %s", lvap.addr, lvap.ssid)
                del lvap.tenant.lvaps[lvap.addr]

        lvap._tenant = None

        if ssids[0]:

            # setting tenant without seding out add lvap message
            lvap._tenant = RUNTIME.load_tenant(ssids[0])

            # adding LVAP to tenant
            LOG.info("Adding %s to tenant %s", lvap.addr, ssids[0])
            lvap.tenant.lvaps[lvap.addr] = lvap

            # Raise LVAP join event
            LOG.info("LVAP JOIN %s (%s)", lvap.addr, lvap.ssid)
            for handler in self.server.pt_types_handlers[PT_LVAP_JOIN]:
                handler(lvap)

        # update remaining ssids
        lvap._ssids = ssids[1:]

        # set ports
        lvap.set_ports()

        LOG.info("LVAP status %s", lvap)
    def _handle_assoc_request(self, request):
        """Handle an incoming ASSOC_REQUEST message.
        Args:
            request, a ASSOC_REQUEST message
        Returns:
            None
        """

        wtp_addr = EtherAddress(request.wtp)

        try:
            wtp = RUNTIME.wtps[wtp_addr]
        except KeyError:
            LOG.info("Assoc request from unknown WTP %s", wtp_addr)
            return

        if not wtp.connection:
            LOG.info("Assoc request from disconnected WTP %s", wtp_addr)
            return

        sta = EtherAddress(request.sta)

        if sta not in RUNTIME.lvaps:
            LOG.info("Assoc request from unknown LVAP %s", sta)
            return

        lvap = RUNTIME.lvaps[sta]

        if not RUNTIME.is_allowed(sta):
            LOG.info("Assoc request from %s ignored (white list)", sta)
            return

        if RUNTIME.is_denied(sta):
            LOG.info("Assoc request from %s ignored (black list)", sta)
            return

        ssid = SSID(request.ssid.decode('UTF-8'))
        bssid = EtherAddress(request.bssid)

        tenant_name = None

        # look for ssid in shared tenants
        for tenant_id in RUNTIME.tenants:

            tenant = RUNTIME.tenants[tenant_id]

            if tenant.bssid_type == T_TYPE_UNIQUE:
                continue

            if bssid in tenant.vaps and ssid == tenant.tenant_name:
                tenant_name = tenant.tenant_name

        # otherwise this must be the lvap unique bssid
        if lvap.net_bssid == bssid and ssid in lvap.ssids:
            tenant_name = ssid

        if not tenant_name:
            LOG.info("Assoc request sta %s for ssid %s bssid %s, ignoring",
                     lvap.addr, lvap.ssid, lvap.lvap_bssid)
            return

        # this will trigger an add lvap message to update the ssid
        lvap.tenant = RUNTIME.load_tenant(tenant_name)

        # this will trigger an add lvap message to update the assoc id
        lvap.assoc_id = self.server.assoc_id

        LOG.info("Assoc request sta %s ssid %s bssid %s assoc id %u, replying",
                 lvap.addr, lvap.ssid, lvap.lvap_bssid, lvap.assoc_id)

        self.send_assoc_response(lvap)
    def _handle_probe_request(self, request):
        """Handle an incoming PROBE_REQUEST message.
        Args:
            request, a PROBE_REQUEST message
        Returns:
            None
        """

        wtp_addr = EtherAddress(request.wtp)

        try:
            wtp = RUNTIME.wtps[wtp_addr]
        except KeyError:
            LOG.info("Probe request from unknown WTP (%s)", wtp_addr)
            return

        if not wtp.connection:
            LOG.info("Probe request from disconnected WTP %s", wtp_addr)
            return

        sta = EtherAddress(request.sta)

        if sta in RUNTIME.lvaps:
            return

        if not RUNTIME.is_allowed(sta):
            return

        if RUNTIME.is_denied(sta):
            return

        ssid = SSID(request.ssid)

        if request.ssid == b'':
            LOG.info("Probe request from %s ssid %s", sta, "Broadcast")
        else:
            LOG.info("Probe request from %s ssid %s", sta, ssid)

        # generate list of available SSIDs
        ssids = set()

        for tenant in RUNTIME.tenants.values():
            if tenant.bssid_type == T_TYPE_SHARED:
                continue
            for wtp_in_tenant in tenant.wtps.values():
                if wtp_addr == wtp_in_tenant.addr:
                    ssids.add(tenant.tenant_name)

        if not ssids:
            LOG.info("No SSIDs available at this WTP")
            return

        # spawn new LVAP
        LOG.info("Spawning new LVAP %s on %s", sta, wtp.addr)
        net_bssid = generate_bssid(BASE_MAC, sta)
        lvap = LVAP(sta, net_bssid, net_bssid)
        lvap._ssids = ssids

        RUNTIME.lvaps[sta] = lvap

        # TODO: This should be built starting from the probe request
        lvap.supports.add(ResourceBlock(lvap, sta, 1, BT_L20))
        lvap.supports.add(ResourceBlock(lvap, sta, 2, BT_L20))
        lvap.supports.add(ResourceBlock(lvap, sta, 3, BT_L20))
        lvap.supports.add(ResourceBlock(lvap, sta, 4, BT_L20))
        lvap.supports.add(ResourceBlock(lvap, sta, 5, BT_L20))
        lvap.supports.add(ResourceBlock(lvap, sta, 6, BT_L20))
        lvap.supports.add(ResourceBlock(lvap, sta, 7, BT_L20))
        lvap.supports.add(ResourceBlock(lvap, sta, 8, BT_L20))
        lvap.supports.add(ResourceBlock(lvap, sta, 9, BT_L20))
        lvap.supports.add(ResourceBlock(lvap, sta, 10, BT_L20))
        lvap.supports.add(ResourceBlock(lvap, sta, 11, BT_L20))
        lvap.supports.add(ResourceBlock(lvap, sta, 36, BT_L20))
        lvap.supports.add(ResourceBlock(lvap, sta, 48, BT_L20))

        # This will trigger an LVAP ADD message (and REMOVE if necessary)
        requested = ResourcePool()
        hwaddr = EtherAddress(request.hwaddr)
        channel = request.channel
        band = request.band
        requested.add(ResourceBlock(wtp, hwaddr, channel, band))

        lvap.scheduled_on = wtp.supports & requested

        LOG.info("Sending probe response to %s", lvap.addr)
        self.send_probe_response(lvap)
    def post(self, *args, **kwargs):
        """ Create a new tenant request.

        Args:
            None

        Request:
            version: protocol version (1.0)
            owner: the username of the requester
            tenant_id: the network name
            desc: a description for the new tenant
            bssid_type: shared or unique

        Example URLs:

            POST /api/v1/pending

        """

        try:

            if len(args) > 1:
                raise ValueError("Invalid url")

            request = tornado.escape.json_decode(self.request.body)

            if "version" not in request:
                raise ValueError("missing version element")

            if "desc" not in request:
                raise ValueError("missing desc element")

            if "tenant_name" not in request:
                raise ValueError("missing tenant_name element")

            if "bssid_type" not in request:
                bssid_type = T_TYPE_UNIQUE
            else:
                bssid_type = request['bssid_type']

            if bssid_type not in T_TYPES:
                raise ValueError("invalid bssid_type %s" % bssid_type)

            if len(args) == 1:
                tenant_id = UUID(args[0])
            else:
                tenant_id = None

            tenant_name = SSID(request['tenant_name'])

            RUNTIME.request_tenant(self.account.username,
                                   request['desc'],
                                   tenant_name,
                                   bssid_type,
                                   tenant_id)

            self.set_header("Location", "/api/v1/pendig/%s" % tenant_id)

        except KeyError as ex:
            self.send_error(404, message=ex)
        except ValueError as ex:
            self.send_error(400, message=ex)

        self.set_status(201, None)
    def _handle_UEs_id_repl(self, main_msg):
        """Handle an incoming UEs ID reply.

        Args:
            message, a emage_msg containing UE IDs (RNTIs)
        Returns:
            None
        """

        active_ues = {}
        inactive_ues = {}

        event_type = main_msg.WhichOneof("event_types")
        msg = protobuf_to_dict(main_msg)
        ues_id_msg_repl = msg[event_type]["mUEs_id"]["repl"]

        if ues_id_msg_repl["status"] != configs_pb2.CREQS_SUCCESS:
            return

        # List of active UEs
        if "active_ue_id" in ues_id_msg_repl:
            for ue in ues_id_msg_repl["active_ue_id"]:
                active_ues[ue["rnti"]] = {}
                if "imsi" in ue:
                    active_ues[ue["rnti"]]["imsi"] = ue["imsi"]
                else:
                    active_ues[ue["rnti"]]["imsi"] = None
                if "plmn_id" in ue:
                    active_ues[ue["rnti"]]["plmn_id"] = ue["plmn_id"]
                else:
                    active_ues[ue["rnti"]]["plmn_id"] = None

        # List of inactive UEs
        if "inactive_ue_id" in ues_id_msg_repl:
            for ue in ues_id_msg_repl["inactive_ue_id"]:
                inactive_ues[ue["rnti"]] = {}
                if "imsi" in ue:
                    inactive_ues[ue["rnti"]]["imsi"] = ue["imsi"]
                else:
                    inactive_ues[ue["rnti"]]["imsi"] = None
                if "plmn_id" in ue:
                    inactive_ues[ue["rnti"]]["plmn_id"] = ue["plmn_id"]
                else:
                    inactive_ues[ue["rnti"]]["plmn_id"] = None

        for rnti in active_ues:

            ue_id = hex_to_ether(rnti)

            if ue_id not in RUNTIME.ues:

                ue_id = hex_to_ether(rnti)
                imsi = active_ues[ue["rnti"]]["imsi"]
                new_ue = UE(ue_id, imsi, self.vbs)

                RUNTIME.ues[ue_id] = new_ue

            ue = RUNTIME.ues[ue_id]
            plmn_id = int(active_ues[rnti]["plmn_id"])

            if not ue.plmn_id and plmn_id:

                # setting tenant
                ue.tenant = RUNTIME.load_tenant_by_plmn_id(plmn_id)

                if ue.tenant:

                    # adding UE to tenant
                    LOG.info("Adding %s to tenant %s", ue.addr,
                             ue.tenant.plmn_id)
                    ue.tenant.ues[ue.addr] = ue

                    # Raise UE join
                    self.server.send_ue_join_message_to_self(ue)

            if ue.plmn_id and not plmn_id:

                # removing UE from tenant
                LOG.info("Removing %s from tenant %s", ue.addr,
                         ue.tenant.plmn_id)
                del ue.tenant.ues[ue.addr]

                # Raise UE leave
                self.server.send_ue_leave_message_to_self(ue)

                # setting tenant
                ue.tenant = None

        existing_ues = []
        existing_ues.extend(RUNTIME.ues.keys())

        for ue_id in existing_ues:
            if ether_to_hex(ue_id) not in active_ues:
                RUNTIME.remove_ue(ue_id)
    def prepare(self):
        """Prepare to handler reply."""

        self.set_header('Content-Type', 'application/json')

        if not self.RIGHTS[self.request.method]:
            return

        auth_header = self.request.headers.get('Authorization')

        if auth_header is None or not auth_header.startswith('Basic '):
            self.set_header('WWW-Authenticate', 'Basic realm=Restricted')
            self.send_error(401)
            return

        auth_bytes = bytes(auth_header[6:], 'utf-8')
        auth_decoded = base64.b64decode(auth_bytes).decode()
        username, password = auth_decoded.split(':', 2)

        # account does not exists
        if not RUNTIME.check_permission(username, password):
            self.send_error(401)
            return

        self.account = RUNTIME.get_account(username)

        if self.account.role in self.RIGHTS[self.request.method]:

            if self.account.role == ROLE_ADMIN:
                return

            if self.request.uri.startswith("/api/v1/accounts"):

                pattern = re.compile("/api/v1/accounts/([a-zA-Z0-9:-]*)/?")
                match = pattern.match(self.request.uri)

                if match and match.group(1):
                    if match.group(1) in RUNTIME.accounts:
                        account = RUNTIME.accounts[match.group(1)]
                        if self.account.username == account.username:
                            return
                        else:
                            self.send_error(401)
                            return

                return

            if self.request.uri.startswith("/api/v1/pending"):
                pattern = re.compile("/api/v1/pending/([a-zA-Z0-9-]*)/?")
                match = pattern.match(self.request.uri)
                if match and match.group(1):
                    try:
                        tenant_id = UUID(match.group(1))
                    except ValueError:
                        self.send_error(400)
                        return
                    pending = RUNTIME.load_pending_tenant(tenant_id)
                    if pending:
                        if self.account.username == pending.owner:
                            return
                        self.send_error(401)
                        return

                return

            if self.request.uri.startswith("/api/v1/tenants"):

                pattern = re.compile("/api/v1/tenants/([a-zA-Z0-9-]*)/?")
                match = pattern.match(self.request.uri)

                if match and match.group(1):
                    tenant_id = UUID(match.group(1))
                    if tenant_id in RUNTIME.tenants:
                        tenant = RUNTIME.tenants[tenant_id]
                        if self.account.username == tenant.owner:
                            return
                        self.send_error(401)
                        return

                return

        self.send_error(401)
        return
    def post(self, *args, **kwargs):
        """ Create a new account.

        Request:
            version: protocol version (1.0)
            username: username
            password: password
            role: tole
            name: name
            surname: surname
            email: email

        Example URLs:

            POST /api/v1/accounts
            {
              "version" : 1.0,
              "username" : "foo",
              "password" : "foo",
              "role" : "user",
              "name" : "foo",
              "surname" : "foo",
              "email" : "*****@*****.**"
            }

        """

        try:

            if len(args) != 0:
                raise ValueError("Invalid url")

            request = tornado.escape.json_decode(self.request.body)

            if "version" not in request:
                raise ValueError("missing version element")

            if "username" not in request:
                raise ValueError("missing username element")

            if "password" not in request:
                raise ValueError("missing password element")

            if "role" not in request:
                raise ValueError("missing role element")

            if "name" not in request:
                raise ValueError("missing name element")

            if "surname" not in request:
                raise ValueError("missing surname element")

            if "email" not in request:
                raise ValueError("missing email element")

            if request['role'] not in [ROLE_ADMIN, ROLE_USER]:
                raise ValueError("Invalid role %s" % request['role'])

            RUNTIME.create_account(request['username'],
                                   request['password'],
                                   request['role'],
                                   request['name'],
                                   request['surname'],
                                   request['email'])

        except ValueError as ex:
            self.send_error(400, message=ex)
        except KeyError as ex:
            self.send_error(404, message=ex)

        self.set_status(201, None)
    def _handle_UEs_id_repl(self, main_msg):
        """Handle an incoming UEs ID reply.

        Args:
            message, a emage_msg containing UE IDs (RNTIs)
        Returns:
            None
        """

        active_ues = {}
        inactive_ues = {}

        event_type = main_msg.WhichOneof("event_types")
        msg = protobuf_to_dict(main_msg)
        ues_id_msg_repl = msg[event_type]["mUEs_id"]["repl"]

        if ues_id_msg_repl["status"] != configs_pb2.CREQS_SUCCESS:
            return

        # List of active UEs
        if "active_ue_id" in ues_id_msg_repl:
            for ue in ues_id_msg_repl["active_ue_id"]:
                active_ues[(self.vbs.addr, ue["rnti"])] = {}
                if "imsi" in ue:
                    active_ues[(self.vbs.addr, ue["rnti"])]["imsi"] = ue["imsi"]
                else:
                    active_ues[(self.vbs.addr, ue["rnti"])]["imsi"] = None
                if "plmn_id" in ue:
                    active_ues[(self.vbs.addr, ue["rnti"])]["plmn_id"] = \
                                                                ue["plmn_id"]
                else:
                    active_ues[(self.vbs.addr, ue["rnti"])]["plmn_id"] = None

        # List of inactive UEs
        if "inactive_ue_id" in ues_id_msg_repl:
            for ue in ues_id_msg_repl["inactive_ue_id"]:
                inactive_ues[(self.vbs.addr, ue["rnti"])] = {}
                if "imsi" in ue:
                    inactive_ues[(self.vbs.addr, ue["rnti"])]["imsi"] = \
                                                                    ue["imsi"]
                else:
                    inactive_ues[(self.vbs.addr, ue["rnti"])]["imsi"] = None
                if "plmn_id" in ue:
                    inactive_ues[(self.vbs.addr, ue["rnti"])]["plmn_id"] = \
                                                                ue["plmn_id"]
                else:
                    inactive_ues[(self.vbs.addr, ue["rnti"])]["plmn_id"] = None

        for vbs_id, rnti in active_ues.keys():

            ue_id = (self.vbs.addr, rnti)

            if ue_id not in RUNTIME.ues:
                new_ue = UE(ue_id, ue_id[1], self.vbs)
                RUNTIME.ues[ue_id] = new_ue

            ue = RUNTIME.ues[ue_id]

            imsi = active_ues[ue_id]["imsi"]
            plmn_id = int(active_ues[ue_id]["plmn_id"])

            # Setting IMSI of UE
            ue.imsi = imsi

            if not ue.plmn_id and plmn_id:

                # Setting tenant
                ue.tenant = RUNTIME.load_tenant_by_plmn_id(plmn_id)

                if ue.tenant:

                    # Adding UE to tenant
                    LOG.info("Adding %s to tenant %s", ue.addr,
                             ue.tenant.plmn_id)
                    ue.tenant.ues[ue.addr] = ue

                    # Raise UE join
                    self.server.send_ue_join_message_to_self(ue)

                    # Create a trigger for reporting RRC measurements config.
                    from empower.ue_confs.ue_rrc_meas_confs import ue_rrc_meas_confs

                    conf_req = {
                        "event_type": "trigger"
                    }

                    ue_rrc_meas_confs(tenant_id=ue.tenant.tenant_id,
                                      vbs=ue.vbs.addr,
                                      ue=ue.rnti,
                                      conf_req=conf_req)

            if ue.plmn_id and not plmn_id:

                # Raise UE leave
                self.server.send_ue_leave_message_to_self(ue)

                # Removing UE from tenant
                LOG.info("Removing %s from tenant %s", ue.addr,
                         ue.tenant.plmn_id)
                del ue.tenant.ues[ue.addr]

                # Resetting tenant
                ue.tenant = None

        existing_ues = []
        existing_ues.extend(RUNTIME.ues.keys())

        for ue_addr in existing_ues:
            if ue_addr not in active_ues:
                RUNTIME.remove_ue(ue_addr)