FlexRAN agent app: trigger UE-slice assoc through IMSI regex
This commit is contained in:
@@ -1103,8 +1103,13 @@ add_library(flapp_sample SHARED
|
|||||||
${OPENAIR2_DIR}/ENB_APP/flexran_apps/sample.c
|
${OPENAIR2_DIR}/ENB_APP/flexran_apps/sample.c
|
||||||
)
|
)
|
||||||
set_target_properties(flapp_sample PROPERTIES C_VISIBILITY_PRESET hidden)
|
set_target_properties(flapp_sample PROPERTIES C_VISIBILITY_PRESET hidden)
|
||||||
|
add_library(flapp_imsi SHARED
|
||||||
|
${OPENAIR2_DIR}/ENB_APP/flexran_apps/imsi.c
|
||||||
|
)
|
||||||
|
set_target_properties(flapp_imsi PROPERTIES C_VISIBILITY_PRESET hidden)
|
||||||
add_custom_target(flapp_all DEPENDS
|
add_custom_target(flapp_all DEPENDS
|
||||||
flapp_sample
|
flapp_sample
|
||||||
|
flapp_imsi
|
||||||
)
|
)
|
||||||
#include_directories(${OPENAIR2_DIR}/ENB_APP)
|
#include_directories(${OPENAIR2_DIR}/ENB_APP)
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,6 @@ error:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int channel_container_init = 0;
|
int channel_container_init = 0;
|
||||||
int flexran_agent_start(mid_t mod_id)
|
int flexran_agent_start(mid_t mod_id)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3092,12 +3092,13 @@ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) {
|
|||||||
return slices->s[idx]->id;
|
return slices->s[idx]->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) {
|
int flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) {
|
||||||
if (!mac_is_present(mod_id)) return;
|
if (!mac_is_present(mod_id)) return 0;
|
||||||
int idx = flexran_find_dl_slice(mod_id, slice_id);
|
int idx = flexran_find_dl_slice(mod_id, slice_id);
|
||||||
if (idx < 0) return;
|
if (idx < 0) return 0;
|
||||||
pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl;
|
pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl;
|
||||||
dl->move_UE(dl->slices, ue_id, idx);
|
dl->move_UE(dl->slices, ue_id, idx);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) {
|
int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) {
|
||||||
@@ -3108,12 +3109,13 @@ int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) {
|
|||||||
return slices->s[idx]->id;
|
return slices->s[idx]->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) {
|
int flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) {
|
||||||
if (!mac_is_present(mod_id)) return;
|
if (!mac_is_present(mod_id)) return 0;
|
||||||
int idx = flexran_find_ul_slice(mod_id, slice_id);
|
int idx = flexran_find_ul_slice(mod_id, slice_id);
|
||||||
if (idx < 0) return;
|
if (idx < 0) return 0;
|
||||||
pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul;
|
pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul;
|
||||||
ul->move_UE(ul->slices, ue_id, idx);
|
ul->move_UE(ul->slices, ue_id, idx);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s, void *object) {
|
int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s, void *object) {
|
||||||
|
|||||||
@@ -669,12 +669,12 @@ int flexran_set_ul_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo);
|
|||||||
/* Get the DL slice ID for a UE */
|
/* Get the DL slice ID for a UE */
|
||||||
int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id);
|
int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id);
|
||||||
/* Set the DL slice for a UE */
|
/* Set the DL slice for a UE */
|
||||||
void flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id);
|
int flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id);
|
||||||
|
|
||||||
/* Get the UL slice ID for a UE */
|
/* Get the UL slice ID for a UE */
|
||||||
int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id);
|
int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id);
|
||||||
/* Set the UL slice for a UE */
|
/* Set the UL slice for a UE */
|
||||||
void flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id);
|
int flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id);
|
||||||
|
|
||||||
/* Create slice in DL, returns the new slice index, object can be shared
|
/* Create slice in DL, returns the new slice index, object can be shared
|
||||||
* library for the scheduler or NULL */
|
* library for the scheduler or NULL */
|
||||||
|
|||||||
@@ -0,0 +1,245 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \file imsi.c
|
||||||
|
* \brief flexran IMSI UE-slice association app
|
||||||
|
* \author Robert Schmidt, Firas Abdeljelil
|
||||||
|
* \date 2020
|
||||||
|
* \version 0.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <regex.h>
|
||||||
|
#include "flexran_agent_common.h"
|
||||||
|
#include "flexran_agent_async.h"
|
||||||
|
#include "flexran_agent_extern.h"
|
||||||
|
#include "flexran_agent_timer.h"
|
||||||
|
#include "flexran_agent_defs.h"
|
||||||
|
#include "flexran_agent_net_comm.h"
|
||||||
|
#include "flexran_agent_ran_api.h"
|
||||||
|
#include "flexran_agent_phy.h"
|
||||||
|
#include "flexran_agent_mac.h"
|
||||||
|
#include "flexran_agent_rrc.h"
|
||||||
|
#include "flexran_agent_pdcp.h"
|
||||||
|
#include "flexran_agent_s1ap.h"
|
||||||
|
#include "flexran_agent_app.h"
|
||||||
|
#include "common/utils/LOG/log.h"
|
||||||
|
#include "assertions.h"
|
||||||
|
#include "queue.h"
|
||||||
|
typedef struct Map_regex_slice slist_data_t;
|
||||||
|
struct Map_regex_slice {
|
||||||
|
char regex_[30] ;
|
||||||
|
int slice_dl;
|
||||||
|
int slice_ul;
|
||||||
|
regex_t regex;
|
||||||
|
SLIST_ENTRY (Map_regex_slice) entries;
|
||||||
|
};
|
||||||
|
bool reconfig = false;
|
||||||
|
int ue[MAX_MOBILES_PER_ENB]={ [0 ... MAX_MOBILES_PER_ENB - 1] = -1 };
|
||||||
|
|
||||||
|
SLIST_HEAD(slisthead, Map_regex_slice) head;
|
||||||
|
|
||||||
|
int dump_list(void) {
|
||||||
|
int len = 1;
|
||||||
|
slist_data_t *datap = NULL;
|
||||||
|
SLIST_FOREACH(datap, &head, entries) {
|
||||||
|
LOG_W(FLEXRAN_AGENT, "%d: regex %s DL %d UL %d\n", len++, datap->regex_,
|
||||||
|
datap->slice_dl, datap->slice_ul);
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ajout(char *regex, int dl, int ul) {
|
||||||
|
slist_data_t *datap = malloc(sizeof(slist_data_t));
|
||||||
|
if (!datap) {
|
||||||
|
LOG_E(FLEXRAN_AGENT, "cannot allocate memory for slist_data_t\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
strcpy(datap->regex_, regex);
|
||||||
|
datap->slice_dl = dl;
|
||||||
|
datap->slice_ul = ul;
|
||||||
|
regcomp(&datap->regex, datap->regex_, 0);
|
||||||
|
SLIST_INSERT_HEAD(&head, datap, entries);
|
||||||
|
if (ul==-1)
|
||||||
|
LOG_I(FLEXRAN_AGENT, "added new element to list: regex %s slice DL %d\n" ,regex, dl);
|
||||||
|
else if (dl==-1)
|
||||||
|
LOG_I(FLEXRAN_AGENT, "added new element to list: regex %s slice UL %d\n" ,regex, ul);
|
||||||
|
else
|
||||||
|
LOG_I(FLEXRAN_AGENT, "added new element to list: regex %s slice DL %d UL %d\n",
|
||||||
|
regex, dl, ul);
|
||||||
|
}
|
||||||
|
void remove_(char *regex) {
|
||||||
|
slist_data_t *datap = NULL;
|
||||||
|
SLIST_FOREACH(datap, &head, entries) {
|
||||||
|
if (strcmp(datap->regex_, regex) == 0) {
|
||||||
|
SLIST_REMOVE(&head, datap, Map_regex_slice, entries);
|
||||||
|
if (datap->slice_dl==-1)
|
||||||
|
LOG_I(FLEXRAN_AGENT, "removed element from list: regex %s slice UL %d\n",datap->regex_, datap->slice_ul);
|
||||||
|
else if (datap->slice_ul==-1)
|
||||||
|
LOG_I(FLEXRAN_AGENT, "removed element from list: regex %s slice DL %d\n",datap->regex_, datap->slice_dl);
|
||||||
|
else
|
||||||
|
LOG_I(FLEXRAN_AGENT, "removed element from list: regex %s slice DL %d UL %d\n",
|
||||||
|
datap->regex_, datap->slice_dl, datap->slice_ul);
|
||||||
|
regfree(&datap->regex);
|
||||||
|
free(datap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_E(FLEXRAN_AGENT, "no regex %s found in list\n", regex);
|
||||||
|
}
|
||||||
|
|
||||||
|
Protocol__FlexranMessage *matching_tick(
|
||||||
|
mid_t mod_id,
|
||||||
|
const Protocol__FlexranMessage *msg) {
|
||||||
|
const int num = flexran_get_mac_num_ues(mod_id);
|
||||||
|
for (int i = 0; i < num; i++) {
|
||||||
|
int ue_id = flexran_get_mac_ue_id(mod_id, i);
|
||||||
|
if (ue[ue_id] >= 0 && !reconfig)
|
||||||
|
continue;
|
||||||
|
rnti_t rnti = flexran_get_mac_ue_crnti(mod_id, ue_id);
|
||||||
|
uint64_t imsi = flexran_get_ue_imsi(mod_id, rnti);
|
||||||
|
char snum[20];
|
||||||
|
sprintf(snum, "%" PRIu64, imsi);
|
||||||
|
slist_data_t *datap = NULL;
|
||||||
|
SLIST_FOREACH(datap, &head, entries) {
|
||||||
|
if (regexec(&datap->regex, snum, 0, NULL, 0) == 0) {
|
||||||
|
|
||||||
|
int dl = datap->slice_dl;
|
||||||
|
if (dl >= 0 && dl != flexran_get_ue_dl_slice_id(mod_id, ue_id)) {
|
||||||
|
int ra = flexran_set_ue_dl_slice_id(mod_id, ue_id, dl);
|
||||||
|
if (ra)
|
||||||
|
LOG_I(FLEXRAN_AGENT,
|
||||||
|
"RNTI %04x/IMSI %s in the slice_dl %d\n",
|
||||||
|
rnti,
|
||||||
|
snum,
|
||||||
|
dl);
|
||||||
|
else
|
||||||
|
LOG_W(FLEXRAN_AGENT, "No such DL slice %d\n", dl);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ul = datap->slice_ul;
|
||||||
|
if (ul >= 0 && ul != flexran_get_ue_ul_slice_id(mod_id, ue_id)) {
|
||||||
|
int rb = flexran_set_ue_ul_slice_id(mod_id, ue_id, ul);
|
||||||
|
if (rb)
|
||||||
|
LOG_I(FLEXRAN_AGENT,
|
||||||
|
"RNTI %04x/IMSI %s in the slice_ul %d\n",
|
||||||
|
rnti,
|
||||||
|
snum,
|
||||||
|
ul);
|
||||||
|
else
|
||||||
|
LOG_W(FLEXRAN_AGENT, "No such DL slice %d\n", dl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ue[ue_id] = ue_id;
|
||||||
|
}
|
||||||
|
reconfig = false;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
void ajout_param(Protocol__FlexAgentReconfigurationSubsystem__ParamsEntry **p, int n_p) {
|
||||||
|
char s[30];
|
||||||
|
reconfig = true;
|
||||||
|
bool supp=false;
|
||||||
|
bool sl_E=false;
|
||||||
|
int dl=-1;
|
||||||
|
int ul=-1;
|
||||||
|
slist_data_t *datap = NULL;
|
||||||
|
for (int i = 0; i < n_p; ++i) {
|
||||||
|
switch (p[i]->value->param_case) {
|
||||||
|
case PROTOCOL__FLEX_AGENT_RECONFIGURATION_PARAM__PARAM__NOT_SET:
|
||||||
|
LOG_I(FLEXRAN_AGENT, " param %s is not set\n", p[i]->key);
|
||||||
|
break;
|
||||||
|
case PROTOCOL__FLEX_AGENT_RECONFIGURATION_PARAM__PARAM_INTEGER:
|
||||||
|
if( strcmp(p[i]->key, "slice_dl")==0)
|
||||||
|
dl= p[i]->value->integer;
|
||||||
|
else
|
||||||
|
ul= p[i]->value->integer;
|
||||||
|
sl_E=true;
|
||||||
|
break;
|
||||||
|
case PROTOCOL__FLEX_AGENT_RECONFIGURATION_PARAM__PARAM_STR:
|
||||||
|
strcpy(s,p[i]->value->str);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_W(FLEXRAN_AGENT, " type of param %s is unknown\n", p[i]->key);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!SLIST_EMPTY(&head)){
|
||||||
|
SLIST_FOREACH(datap, &head, entries) {
|
||||||
|
if (strcmp(datap->regex_, s) == 0) {
|
||||||
|
if (datap->slice_dl!=dl || datap->slice_ul!=ul)
|
||||||
|
supp=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sl_E==false)
|
||||||
|
remove_(s);
|
||||||
|
else {
|
||||||
|
if (supp==true)
|
||||||
|
remove_(s);
|
||||||
|
ajout(s,dl,ul);
|
||||||
|
}
|
||||||
|
/* re-verify all UEs again */
|
||||||
|
for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i)
|
||||||
|
ue[i] = -1;
|
||||||
|
}
|
||||||
|
/* imsi_start: entry point for imsi app. Installs a callback using the timer
|
||||||
|
* API to have function imsi_tick() called every 5s */
|
||||||
|
#define TIMER 32
|
||||||
|
int imsi_start(mid_t mod_id,
|
||||||
|
Protocol__FlexAgentReconfigurationSubsystem__ParamsEntry **p,
|
||||||
|
int n_p)
|
||||||
|
{
|
||||||
|
LOG_W(FLEXRAN_AGENT, "%s(): enable IMSI app timer\n", __func__);
|
||||||
|
flexran_agent_create_timer(mod_id,
|
||||||
|
500,
|
||||||
|
FLEXRAN_AGENT_TIMER_TYPE_PERIODIC,
|
||||||
|
TIMER,
|
||||||
|
matching_tick,
|
||||||
|
NULL);
|
||||||
|
SLIST_INIT(&head);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int imsi_reconfig(mid_t mod_id,
|
||||||
|
Protocol__FlexAgentReconfigurationSubsystem__ParamsEntry **p,
|
||||||
|
int n_p)
|
||||||
|
{
|
||||||
|
ajout_param(p, n_p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stop function: cleans up before app can be unloaded. Here: stop the timer */
|
||||||
|
int imsi_stop(mid_t mod_id) {
|
||||||
|
LOG_W(FLEXRAN_AGENT, "%s(): disable IMSI app timer\n", __func__);
|
||||||
|
flexran_agent_destroy_timer(mod_id, TIMER);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* app definition. visibility should be set to default so this symbol is
|
||||||
|
* reachable from outside */
|
||||||
|
flexran_agent_app_t __attribute__ ((visibility ("default"))) app = {
|
||||||
|
.start = imsi_start,
|
||||||
|
.reconfig = imsi_reconfig,
|
||||||
|
.stop = imsi_stop
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user