def cleanup(self): """Remove this module.""" self.log.info("Cleanup %s (id=%u)", self.module_type, self.module_id) vbses = RUNTIME.tenants[self.tenant_id].vbses if self.vbs not in vbses: return vbs = vbses[self.vbs] ue_addr = (self.vbs, self.ue) if ue_addr not in RUNTIME.tenants[self.tenant_id].ues: return ue = RUNTIME.tenants[self.tenant_id].ues[ue_addr] if not vbs.connection or vbs.connection.stream.closed(): self.log.info("VBS %s not connected", vbs.addr) return meas = self.meas for m in meas.keys(): if m in ue.rrc_meas: del ue.rrc_meas[m] rrc_m_req = main_pb2.emage_msg() enb_id = ether_to_hex(self.vbs) # Transaction identifier is zero by default. create_header(self.module_id, enb_id, rrc_m_req.head) # Creating a trigger message to delete UE's RRC measurements trigger trigger_msg = rrc_m_req.te trigger_msg.action = main_pb2.EA_DEL rrc_m_msg = trigger_msg.mRRC_meas rrc_m_req_msg = rrc_m_msg.req rrc_m_req_msg.rnti = ue.rnti rrc_m_req_msg.measId = 0 rrc_m_req_msg.m_obj.measObjId = 0 rrc_m_req_msg.r_conf.reportConfId = 0 meas_req = self.meas_req rrc_m_req_msg.rat = RRC_STATS_RAT_TYPE[meas_req["rat_type"]] connection = vbs.connection enb_id = connection.vbs.enb_id vbs.connection.stream_send(rrc_m_req)
def cleanup(self): """Remove this module.""" self.log.info("Cleanup %s (id=%u)", self.module_type, self.module_id) vbses = RUNTIME.tenants[self.tenant_id].vbses if self.vbs not in vbses: return vbs = vbses[self.vbs] tenant = RUNTIME.tenants[self.tenant_id] ue_addr = (self.vbs, self.ue) if ue_addr not in tenant.ues: return ue = tenant.ues[ue_addr] if not vbs.connection or vbs.connection.stream.closed(): self.log.info("VBS %s not connected", vbs.addr) return cf_req = self.conf_req rrc_m_conf_req = main_pb2.emage_msg() enb_id = ether_to_hex(self.vbs) create_header(self.module_id, enb_id, rrc_m_conf_req.head) # Creating a message to fetch UEs RRC measurement configuration event_type_msg = None if cf_req["event_type"] == "trigger": event_type_msg = rrc_m_conf_req.te event_type_msg.action = main_pb2.EA_DEL elif cf_req["event_type"] == "schedule": event_type_msg = rrc_m_conf_req.sche event_type_msg.action = main_pb2.EA_DEL else: return rrc_m_conf_msg = event_type_msg.mUE_rrc_meas_conf rrc_m_conf_req_msg = rrc_m_conf_msg.req rrc_m_conf_req_msg.rnti = ue.rnti connection = vbs.connection vbs.connection.stream_send(rrc_m_conf_req)
def send_UEs_id_req(self): """ Send request for UEs ID registered in VBS """ ues_id_req = main_pb2.emage_msg() enb_id = ether_to_hex(self.vbs.addr) # Transaction identifier is one by default. create_header(1, enb_id, ues_id_req.head) # Creating a trigger message to fetch UE RNTIs trigger_msg = ues_id_req.te trigger_msg.action = main_pb2.EA_ADD UEs_id_msg = trigger_msg.mUEs_id UEs_id_req_msg = UEs_id_msg.req UEs_id_req_msg.dummy = 1 LOG.info("Sending UEs request to VBS %s (%u)", self.vbs.addr, enb_id) self.stream_send(ues_id_req)
def send_rrc_meas_conf_req(self, ue): """ Sends a request for RRC measurements configuration of UE """ rrc_m_conf_req = main_pb2.emage_msg() enb_id = ether_to_hex(self.vbs.addr) # Transaction identifier is zero by default. create_header(0, enb_id, rrc_m_conf_req.head) # Creating a trigger message to fetch UE RNTIs trigger_msg = rrc_m_conf_req.te trigger_msg.action = main_pb2.EA_ADD rrc_m_conf_msg = trigger_msg.mUE_rrc_meas_conf rrc_m_conf_req_msg = rrc_m_conf_msg.req rrc_m_conf_req_msg.rnti = ue.rnti LOG.info("Sending UEs RRC measurement config request to VBS %s (%u)", self.vbs.addr, enb_id) self.stream_send(rrc_m_conf_req)
def send_UEs_id_req(self): """ Send request for UEs ID registered in VBS """ ues_id_req = main_pb2.emage_msg() enb_id = ether_to_hex(self.vbs.addr) # Transaction identifier is zero by default. create_header(0, enb_id, ues_id_req.head) # Creating a trigger message to fetch UE RNTIs trigger_msg = ues_id_req.te trigger_msg.action = main_pb2.EA_ADD UEs_id_msg = trigger_msg.mUEs_id UEs_id_req_msg = UEs_id_msg.req UEs_id_req_msg.dummy = 1 LOG.info("Sending UEs request to VBS %s (%u)", self.vbs.addr, enb_id) self.stream_send(ues_id_req)
def send_rrc_meas_conf_req(self, ue): """ Sends a request for RRC measurements configuration of UE """ rrc_m_conf_req = main_pb2.emage_msg() enb_id = ether_to_hex(self.vbs.addr) # Transaction identifier is one by default. create_header(1, enb_id, rrc_m_conf_req.head) # Creating a trigger message to fetch UE RNTIs trigger_msg = rrc_m_conf_req.te trigger_msg.action = main_pb2.EA_ADD rrc_m_conf_msg = trigger_msg.mUE_rrc_meas_conf rrc_m_conf_req_msg = rrc_m_conf_msg.req rrc_m_conf_req_msg.rnti = ue.rnti LOG.info("Sending UEs RRC measurement config request to VBS %s (%u)", self.vbs.addr, enb_id) self.stream_send(rrc_m_conf_req)
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 run_once(self): """Send out RRC measurements request.""" if self.tenant_id not in RUNTIME.tenants: self.log.info("Tenant %s not found", self.tenant_id) self.unload() return tenant = RUNTIME.tenants[self.tenant_id] ue_addr = (self.vbs, self.ue) if ue_addr not in tenant.ues: self.log.info("UE %s not found", ue_addr) return ue = tenant.ues[ue_addr] if not ue.vbs.connection or ue.vbs.connection.stream.closed(): self.log.info("VBS %s not connected", ue.vbs.addr) return st_req = self.meas_req rrc_m_req = main_pb2.emage_msg() enb_id = ether_to_hex(self.vbs) create_header(self.module_id, enb_id, rrc_m_req.head) # Creating a trigger message to fetch UE's RRC measurements trigger_msg = rrc_m_req.te trigger_msg.action = main_pb2.EA_ADD rrc_m_msg = trigger_msg.mRRC_meas rrc_m_req_msg = rrc_m_msg.req rrc_m_req_msg.rnti = ue.rnti rrc_m_req_msg.rat = RRC_STATS_RAT_TYPE[st_req["rat_type"]] rrc_m_req_msg.measId = 0 rrc_m_req_msg.m_obj.measObjId = 0 rrc_m_req_msg.r_conf.reportConfId = 0 if st_req["rat_type"] == "EUTRA": m_obj = rrc_m_req_msg.m_obj measObj_EUTRA = m_obj.measObj_EUTRA measObj_EUTRA.carrier_freq = st_req["carrier_freq"] measObj_EUTRA.meas_bw = RRC_STATS_BW[st_req["bandwidth"]] if "cells_to_measure" in st_req: for c in st_req["cells_to_measure"]: measObj_EUTRA.cells.append(st_req["cells_to_measure"][c]) if "blacklist_cells" in st_req: for c in st_req["blacklist_cells"]: measObj_EUTRA.bkl_cells.append( st_req["blacklist_cells"][c]) if st_req["rat_type"] == "EUTRA": # EUTRA report configuration r_conf = rrc_m_req_msg.r_conf rc_EUTRA = r_conf.rc_EUTRA # Setting default values rc_EUTRA.hysteresis = 0 rc_EUTRA.trigg_time = configs_pb2.TTRIG_ms0 rc_EUTRA.report_quant = configs_pb2.REPQ_BOTH rc_EUTRA.ue_rxtx_time_diff = configs_pb2.UERXTXTD_SETUP rc_EUTRA.trigg_quant = \ RRC_STATS_TRIGGER_QUANT[st_req["trigger_quantity"]] rc_EUTRA.max_rep_cells = st_req["max_report_cells"] rc_EUTRA.rep_interval = \ RRC_STATS_REPORT_INTR[st_req["report_interval"]] rc_EUTRA.rep_amount = \ RRC_STATS_NUM_REPORTS[st_req["num_of_reports"]] if st_req["report_type"] == "periodical_ref_signal": rc_EUTRA.periodical.purpose = \ configs_pb2.PERRP_REPORT_STRONGEST_CELLS elif st_req["report_type"] == "A1": a1 = rc_EUTRA.a1 if st_req["threshold1"]["type"] == "RSRP": a1.a1_threshold.RSRP = st_req["threshold1"]["value"] else: a1.a1_threshold.RSRQ = st_req["threshold1"]["value"] elif st_req["report_type"] == "A2": a2 = rc_EUTRA.a2 if st_req["threshold1"]["type"] == "RSRP": a2.a2_threshold.RSRP = st_req["threshold1"]["value"] else: a2.a2_threshold.RSRQ = st_req["threshold1"]["value"] elif st_req["report_type"] == "A3": a3 = rc_EUTRA.a3 a3.a3_offset = st_req["a3_offset"] a3.report_on_leave = 1 elif st_req["report_type"] == "A4": a4 = rc_EUTRA.a4 if st_req["threshold1"]["type"] == "RSRP": a4.a4_threshold.RSRP = st_req["threshold1"]["value"] else: a4.a4_threshold.RSRQ = st_req["threshold1"]["value"] elif st_req["report_type"] == "A5": a5 = rc_EUTRA.a5 if st_req["threshold1"]["type"] == "RSRP": a5.a5_threshold1.RSRP = st_req["threshold1"]["value"] else: a5.a5_threshold1.RSRQ = st_req["threshold1"]["value"] if st_req["threshold2"]["type"] == "RSRP": a5.a5_threshold2.RSRP = st_req["threshold2"]["value"] else: a5.a5_threshold2.RSRQ = st_req["threshold2"]["value"] self.log.info("Sending RRC stats request to %s (id=%u)", ue.vbs.addr, self.module_id) ue.vbs.connection.stream_send(rrc_m_req) ueleave(tenant_id=self.tenant_id, callback=self.ue_leave_callback)
def run_once(self): """Send out RRC measurements configuration request.""" if self.tenant_id not in RUNTIME.tenants: self.log.info("Tenant %s not found", self.tenant_id) self.unload() return vbses = RUNTIME.tenants[self.tenant_id].vbses if self.vbs not in vbses: return vbs = vbses[self.vbs] tenant = RUNTIME.tenants[self.tenant_id] ue_addr = (self.vbs, self.ue) if ue_addr not in tenant.ues: raise ValueError("Invalid ue rnti") ue = tenant.ues[ue_addr] if not vbs.connection or vbs.connection.stream.closed(): self.log.info("VBS %s not connected", vbs.addr) return cf_req = self.conf_req rrc_m_conf_req = main_pb2.emage_msg() enb_id = ether_to_hex(self.vbs) create_header(self.module_id, enb_id, rrc_m_conf_req.head) # Creating a message to fetch UEs RRC measurement configuration event_type_msg = None if cf_req["event_type"] == "trigger": event_type_msg = rrc_m_conf_req.te event_type_msg.action = main_pb2.EA_ADD elif cf_req["event_type"] == "schedule": event_type_msg = rrc_m_conf_req.sche event_type_msg.action = main_pb2.EA_ADD event_type_msg.interval = cf_req["periodicity"] else: event_type_msg = rrc_m_conf_req.se rrc_m_conf_msg = event_type_msg.mUE_rrc_meas_conf rrc_m_conf_req_msg = rrc_m_conf_msg.req rrc_m_conf_req_msg.rnti = ue.rnti connection = vbs.connection self.log.info("Sending UEs RRC meas. config req to %s (id=%u)", vbs.addr, self.module_id) vbs.connection.stream_send(rrc_m_conf_req) ueleave(tenant_id=self.tenant_id, callback=self.ue_leave_callback)
def enb_id(self): """Return tenant id.""" return ether_to_hex(self.addr)
def run_once(self): """Send out RRC measurements request.""" if self.tenant_id not in RUNTIME.tenants: self.log.info("Tenant %s not found", self.tenant_id) self.unload() return tenant = RUNTIME.tenants[self.tenant_id] ue_addr = (self.vbs, self.ue) if ue_addr not in tenant.ues: self.log.info("UE %s not found", ue_addr) return ue = tenant.ues[ue_addr] if not ue.vbs.connection or ue.vbs.connection.stream.closed(): self.log.info("VBS %s not connected", ue.vbs.addr) return st_req = self.meas_req rrc_m_req = main_pb2.emage_msg() enb_id = ether_to_hex(self.vbs) create_header(self.module_id, enb_id, rrc_m_req.head) # Creating a trigger message to fetch UE's RRC measurements trigger_msg = rrc_m_req.te trigger_msg.action = main_pb2.EA_ADD rrc_m_msg = trigger_msg.mRRC_meas rrc_m_req_msg = rrc_m_msg.req rrc_m_req_msg.rnti = ue.rnti rrc_m_req_msg.rat = RRC_STATS_RAT_TYPE[st_req["rat_type"]] rrc_m_req_msg.measId = 0 rrc_m_req_msg.m_obj.measObjId = 0 rrc_m_req_msg.r_conf.reportConfId = 0 if st_req["rat_type"] == "EUTRA": m_obj = rrc_m_req_msg.m_obj measObj_EUTRA = m_obj.measObj_EUTRA measObj_EUTRA.carrier_freq = st_req["carrier_freq"] measObj_EUTRA.meas_bw = RRC_STATS_BW[st_req["bandwidth"]] if "cells_to_measure" in st_req: for c in st_req["cells_to_measure"]: measObj_EUTRA.cells.append(st_req["cells_to_measure"][c]) if "blacklist_cells" in st_req: for c in st_req["blacklist_cells"]: measObj_EUTRA.bkl_cells.append(st_req["blacklist_cells"][c]) if st_req["rat_type"] == "EUTRA": # EUTRA report configuration r_conf = rrc_m_req_msg.r_conf rc_EUTRA = r_conf.rc_EUTRA # Setting default values rc_EUTRA.hysteresis = 0 rc_EUTRA.trigg_time = configs_pb2.TTRIG_ms0 rc_EUTRA.report_quant = configs_pb2.REPQ_BOTH rc_EUTRA.ue_rxtx_time_diff = configs_pb2.UERXTXTD_SETUP rc_EUTRA.trigg_quant = \ RRC_STATS_TRIGGER_QUANT[st_req["trigger_quantity"]] rc_EUTRA.max_rep_cells = st_req["max_report_cells"] rc_EUTRA.rep_interval = \ RRC_STATS_REPORT_INTR[st_req["report_interval"]] rc_EUTRA.rep_amount = \ RRC_STATS_NUM_REPORTS[st_req["num_of_reports"]] if st_req["report_type"] == "periodical_ref_signal": rc_EUTRA.periodical.purpose = \ configs_pb2.PERRP_REPORT_STRONGEST_CELLS elif st_req["report_type"] == "A1": a1 = rc_EUTRA.a1 if st_req["threshold1"]["type"] == "RSRP": a1.a1_threshold.RSRP = st_req["threshold1"]["value"] else: a1.a1_threshold.RSRQ = st_req["threshold1"]["value"] elif st_req["report_type"] == "A2": a2 = rc_EUTRA.a2 if st_req["threshold1"]["type"] == "RSRP": a2.a2_threshold.RSRP = st_req["threshold1"]["value"] else: a2.a2_threshold.RSRQ = st_req["threshold1"]["value"] elif st_req["report_type"] == "A3": a3 = rc_EUTRA.a3 a3.a3_offset = st_req["a3_offset"] a3.report_on_leave = 1 elif st_req["report_type"] == "A4": a4 = rc_EUTRA.a4 if st_req["threshold1"]["type"] == "RSRP": a4.a4_threshold.RSRP = st_req["threshold1"]["value"] else: a4.a4_threshold.RSRQ = st_req["threshold1"]["value"] elif st_req["report_type"] == "A5": a5 = rc_EUTRA.a5 if st_req["threshold1"]["type"] == "RSRP": a5.a5_threshold1.RSRP = st_req["threshold1"]["value"] else: a5.a5_threshold1.RSRQ = st_req["threshold1"]["value"] if st_req["threshold2"]["type"] == "RSRP": a5.a5_threshold2.RSRP = st_req["threshold2"]["value"] else: a5.a5_threshold2.RSRQ = st_req["threshold2"]["value"] self.log.info("Sending RRC stats request to %s (id=%u)", ue.vbs.addr, self.module_id) ue.vbs.connection.stream_send(rrc_m_req) ueleave(tenant_id=self.tenant_id, callback=self.ue_leave_callback)