def _handle_status_lvap(self, wtp, status):
        """Handle an incoming STATUS_LVAP message.
        Args:
            status, a STATUS_LVAP message
        Returns:
            None
        """

        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

        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)

            RUNTIME.lvaps[sta_addr] = lvap

        lvap = RUNTIME.lvaps[sta_addr]

        # incoming block
        lvap.supported = ResourcePool()
        hwaddr = EtherAddress(status.hwaddr)
        channel = status.channel
        band = status.band
        lvap.supported.add(ResourceBlock(lvap, hwaddr, channel, band))

        match = wtp.supports & lvap.supported

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

        block = match.pop()

        # 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
            self.server.send_lvap_leave_message_to_self(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]:

            tenant = RUNTIME.load_tenant(ssids[0])

            if not tenant:
                LOG.info("LVAP %s from unknown tenant %s", lvap.addr, ssids[0])
                RUNTIME.remove_lvap(lvap.addr)
                return

            # setting tenant without seding out add lvap message
            lvap._tenant = tenant

            # 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
            self.server.send_lvap_join_message_to_self(lvap)

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

        # set ports
        lvap.set_ports()

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

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

        if not wtp.port():
            LOG.info("WTP %s not ready", 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.set_ssids(list(ssids))

        RUNTIME.lvaps[sta] = lvap

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

        lvap.scheduled_on = wtp.supports & lvap.supported

        LOG.info("Sending probe response to %s", lvap.addr)
        self.send_probe_response(lvap)