Merge branch 'DRX_develop' into 374-missing-rrc-inactivity-timer-missing-default-drx-ie-in-s1-setup-ue-s1-id-unknown-after-detach-for-switch-off
This commit is contained in:
@@ -141,7 +141,7 @@ x_image *x_create_image(x_connection *_x, unsigned char *data,
|
||||
ret = calloc(1, sizeof(struct x_image)); if (ret == NULL) OOM;
|
||||
|
||||
template.class = TrueColor;
|
||||
template.depth = 24;
|
||||
template.depth = 32;
|
||||
template.red_mask = 0xff0000;
|
||||
template.green_mask = 0x00ff00;
|
||||
template.blue_mask = 0x0000ff;
|
||||
|
||||
@@ -65,7 +65,7 @@ typedef int32_t sdu_size_t;
|
||||
typedef uint32_t frame_t;
|
||||
typedef int32_t sframe_t;
|
||||
typedef uint32_t sub_frame_t;
|
||||
typedef uint16_t module_id_t;
|
||||
typedef uint16_t module_id_t;
|
||||
typedef uint8_t slice_id_t;
|
||||
typedef uint8_t eNB_index_t;
|
||||
typedef uint16_t ue_id_t;
|
||||
|
||||
+231
-38
@@ -2041,37 +2041,162 @@ int RCconfig_gtpu(void ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int RCconfig_S1(MessageDef *msg_p, uint32_t i) {
|
||||
int j,k = 0;
|
||||
int enb_id;
|
||||
int32_t my_int;
|
||||
const char *active_enb[MAX_ENB];
|
||||
char *address = NULL;
|
||||
char *cidr = NULL;
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* Configure the s1ap_register_enb_req in itti message for future
|
||||
* communications between eNB(s) and MME.
|
||||
*/
|
||||
int RCconfig_S1(
|
||||
MessageDef *msg_p,
|
||||
uint32_t i)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
int enb_id = 0;
|
||||
int32_t my_int = 0;
|
||||
const char *active_enb[MAX_ENB];
|
||||
char *address = NULL;
|
||||
char *cidr = NULL;
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* the only reason for all these variables is, that they are "hard-encoded" into
|
||||
* the CCPARAMS_DESC macro and we need it for the default_DRX value ...
|
||||
*/
|
||||
char *frame_type = NULL;
|
||||
int32_t tdd_config = 0;
|
||||
int32_t tdd_config_s = 0;
|
||||
char *prefix_type = NULL;
|
||||
char *pbch_repetition = NULL;
|
||||
int32_t eutra_band = 0;
|
||||
long long int downlink_frequency = 0;
|
||||
int32_t uplink_frequency_offset = 0;
|
||||
int32_t Nid_cell = 0;
|
||||
int32_t Nid_cell_mbsfn = 0;
|
||||
int32_t N_RB_DL = 0;
|
||||
int32_t nb_antenna_ports = 0;
|
||||
int32_t prach_root = 0;
|
||||
int32_t prach_config_index = 0;
|
||||
char *prach_high_speed = NULL;
|
||||
int32_t prach_zero_correlation = 0;
|
||||
int32_t prach_freq_offset = 0;
|
||||
int32_t pucch_delta_shift = 0;
|
||||
int32_t pucch_nRB_CQI = 0;
|
||||
int32_t pucch_nCS_AN = 0;
|
||||
int32_t pucch_n1_AN = 0;
|
||||
int32_t pdsch_referenceSignalPower = 0;
|
||||
int32_t pdsch_p_b = 0;
|
||||
int32_t pusch_n_SB = 0;
|
||||
char *pusch_hoppingMode = NULL;
|
||||
int32_t pusch_hoppingOffset = 0;
|
||||
char *pusch_enable64QAM = NULL;
|
||||
char *pusch_groupHoppingEnabled = NULL;
|
||||
int32_t pusch_groupAssignment = 0;
|
||||
char *pusch_sequenceHoppingEnabled = NULL;
|
||||
int32_t pusch_nDMRS1 = 0;
|
||||
char *phich_duration = NULL;
|
||||
char *phich_resource = NULL;
|
||||
char *srs_enable = NULL;
|
||||
int32_t srs_BandwidthConfig = 0;
|
||||
int32_t srs_SubframeConfig = 0;
|
||||
char *srs_ackNackST = NULL;
|
||||
char *srs_MaxUpPts = NULL;
|
||||
int32_t pusch_p0_Nominal = 0;
|
||||
char *pusch_alpha = NULL;
|
||||
int32_t pucch_p0_Nominal = 0;
|
||||
int32_t msg3_delta_Preamble = 0;
|
||||
char *pucch_deltaF_Format1 = NULL;
|
||||
char *pucch_deltaF_Format1b = NULL;
|
||||
char *pucch_deltaF_Format2 = NULL;
|
||||
char *pucch_deltaF_Format2a = NULL;
|
||||
char *pucch_deltaF_Format2b = NULL;
|
||||
int32_t rach_numberOfRA_Preambles = 0;
|
||||
char *rach_preamblesGroupAConfig = NULL;
|
||||
int32_t rach_sizeOfRA_PreamblesGroupA = 0;
|
||||
int32_t rach_messageSizeGroupA = 0;
|
||||
char *rach_messagePowerOffsetGroupB = NULL;
|
||||
int32_t rach_powerRampingStep = 0;
|
||||
int32_t rach_preambleInitialReceivedTargetPower = 0;
|
||||
int32_t rach_preambleTransMax = 0;
|
||||
int32_t rach_raResponseWindowSize = 10;
|
||||
int32_t rach_macContentionResolutionTimer = 0;
|
||||
int32_t rach_maxHARQ_Msg3Tx = 0;
|
||||
int32_t pcch_defaultPagingCycle = 0;
|
||||
char *pcch_nB = NULL;
|
||||
int32_t bcch_modificationPeriodCoeff = 0;
|
||||
int32_t ue_TimersAndConstants_t300 = 0;
|
||||
int32_t ue_TimersAndConstants_t301 = 0;
|
||||
int32_t ue_TimersAndConstants_t310 = 0;
|
||||
int32_t ue_TimersAndConstants_t311 = 0;
|
||||
int32_t ue_TimersAndConstants_n310 = 0;
|
||||
int32_t ue_TimersAndConstants_n311 = 0;
|
||||
int32_t ue_TransmissionMode = 0;
|
||||
int32_t ue_multiple_max = 0;
|
||||
//TTN - for D2D
|
||||
//SIB18
|
||||
const char *rxPool_sc_CP_Len = NULL;
|
||||
const char *rxPool_sc_Period = NULL;
|
||||
const char *rxPool_data_CP_Len = NULL;
|
||||
libconfig_int rxPool_ResourceConfig_prb_Num = 0;
|
||||
libconfig_int rxPool_ResourceConfig_prb_Start = 0;
|
||||
libconfig_int rxPool_ResourceConfig_prb_End = 0;
|
||||
const char *rxPool_ResourceConfig_offsetIndicator_present = NULL;
|
||||
libconfig_int rxPool_ResourceConfig_offsetIndicator_choice = 0;
|
||||
const char *rxPool_ResourceConfig_subframeBitmap_present = NULL;
|
||||
char *rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = NULL;
|
||||
libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 0;
|
||||
libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
|
||||
//SIB19
|
||||
//For discRxPool
|
||||
const char *discRxPool_cp_Len = NULL;
|
||||
const char *discRxPool_discPeriod = NULL;
|
||||
libconfig_int discRxPool_numRetx = 0;
|
||||
libconfig_int discRxPool_numRepetition = 0;
|
||||
libconfig_int discRxPool_ResourceConfig_prb_Num = 0;
|
||||
libconfig_int discRxPool_ResourceConfig_prb_Start = 0;
|
||||
libconfig_int discRxPool_ResourceConfig_prb_End = 0;
|
||||
const char *discRxPool_ResourceConfig_offsetIndicator_present = NULL;
|
||||
libconfig_int discRxPool_ResourceConfig_offsetIndicator_choice = 0;
|
||||
const char *discRxPool_ResourceConfig_subframeBitmap_present = NULL;
|
||||
char *discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = NULL;
|
||||
libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 0;
|
||||
libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
|
||||
//For discRxPoolPS
|
||||
const char *discRxPoolPS_cp_Len = NULL;
|
||||
const char *discRxPoolPS_discPeriod = NULL;
|
||||
libconfig_int discRxPoolPS_numRetx = 0;
|
||||
libconfig_int discRxPoolPS_numRepetition = 0;
|
||||
libconfig_int discRxPoolPS_ResourceConfig_prb_Num = 0;
|
||||
libconfig_int discRxPoolPS_ResourceConfig_prb_Start = 0;
|
||||
libconfig_int discRxPoolPS_ResourceConfig_prb_End = 0;
|
||||
const char *discRxPoolPS_ResourceConfig_offsetIndicator_present = NULL;
|
||||
libconfig_int discRxPoolPS_ResourceConfig_offsetIndicator_choice = 0;
|
||||
const char *discRxPoolPS_ResourceConfig_subframeBitmap_present = NULL;
|
||||
char *discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf = NULL;
|
||||
libconfig_int discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size = 0;
|
||||
libconfig_int discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
|
||||
/*------------------------------------------------------------------------------*/
|
||||
// for no gcc warnings
|
||||
(void)my_int;
|
||||
memset((char *)active_enb, 0, MAX_ENB * sizeof(char *));
|
||||
memset((char *)active_enb, 0, MAX_ENB * sizeof(char *));
|
||||
paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
|
||||
paramdef_t ENBParams[] = ENBPARAMS_DESC;
|
||||
paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0};
|
||||
paramdef_t ENBParams[] = ENBPARAMS_DESC;
|
||||
paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST, NULL, 0};
|
||||
/* get global parameters, defined outside any section in the config file */
|
||||
config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL);
|
||||
AssertFatal (i<ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt,
|
||||
config_get(ENBSParams, sizeof(ENBSParams)/sizeof(paramdef_t), NULL);
|
||||
AssertFatal (i < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt,
|
||||
"Failed to parse config file %s, %uth attribute %s \n",
|
||||
RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
|
||||
|
||||
if (ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt>0) {
|
||||
if (ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt > 0) {
|
||||
// Output a list of all eNBs.
|
||||
config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),NULL);
|
||||
config_getlist(&ENBParamList, ENBParams, sizeof(ENBParams)/sizeof(paramdef_t), NULL);
|
||||
|
||||
if (ENBParamList.numelt > 0) {
|
||||
for (k = 0; k < ENBParamList.numelt; k++) {
|
||||
for (int k = 0; k < ENBParamList.numelt; k++) {
|
||||
if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) {
|
||||
// Calculate a default eNB ID
|
||||
if (EPC_MODE_ENABLED) {
|
||||
uint32_t hash;
|
||||
hash = s1ap_generate_eNB_id ();
|
||||
uint32_t hash = 0;
|
||||
hash = s1ap_generate_eNB_id();
|
||||
enb_id = k + (hash & 0xFFFF8);
|
||||
} else {
|
||||
enb_id = k;
|
||||
@@ -2081,22 +2206,33 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) {
|
||||
}
|
||||
|
||||
// search if in active list
|
||||
for (j=0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) {
|
||||
for (int j = 0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) {
|
||||
if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) {
|
||||
paramdef_t PLMNParams[] = PLMNPARAMS_DESC;
|
||||
paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0};
|
||||
|
||||
paramdef_t CCsParams[] = CCPARAMS_DESC;
|
||||
|
||||
/* map parameter checking array instances to parameter definition array instances */
|
||||
checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK;
|
||||
for (int I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) {
|
||||
CCsParams[I].chkPptr = &(config_check_CCparams[I]);
|
||||
}
|
||||
|
||||
/* map parameter checking array instances to parameter definition array instances */
|
||||
checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK;
|
||||
|
||||
for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
|
||||
for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) {
|
||||
PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
|
||||
}
|
||||
|
||||
paramdef_t S1Params[] = S1PARAMS_DESC;
|
||||
paramlist_def_t S1ParamList = {ENB_CONFIG_STRING_MME_IP_ADDRESS, NULL, 0};
|
||||
paramdef_t SCTPParams[] = SCTPPARAMS_DESC;
|
||||
paramdef_t NETParams[] = NETPARAMS_DESC;
|
||||
|
||||
paramdef_t S1Params[] = S1PARAMS_DESC;
|
||||
paramlist_def_t S1ParamList = {ENB_CONFIG_STRING_MME_IP_ADDRESS,NULL,0};
|
||||
paramdef_t SCTPParams[] = SCTPPARAMS_DESC;
|
||||
paramdef_t NETParams[] = NETPARAMS_DESC;
|
||||
char aprefix[MAX_OPTNAME_SIZE*2 + 8];
|
||||
sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
|
||||
sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k);
|
||||
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id;
|
||||
|
||||
if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) {
|
||||
@@ -2104,13 +2240,16 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) {
|
||||
} else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) {
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB;
|
||||
} else {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
|
||||
RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr));
|
||||
AssertFatal(0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
|
||||
RC.config_file_name,
|
||||
i,
|
||||
*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr));
|
||||
}
|
||||
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr));
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr;
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr));
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr;
|
||||
|
||||
AssertFatal(!ENBParamList.paramarray[k][ENB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr
|
||||
&& !ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX_OLD].strptr,
|
||||
"It seems that you use an old configuration file. Please change the existing\n"
|
||||
@@ -2120,11 +2259,13 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) {
|
||||
"to\n"
|
||||
" tracking_area_code = 1; // no string!!\n"
|
||||
" plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n");
|
||||
|
||||
config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
|
||||
|
||||
if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6)
|
||||
if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6){
|
||||
AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n",
|
||||
PLMNParamList.numelt);
|
||||
}
|
||||
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).num_plmn = PLMNParamList.numelt;
|
||||
|
||||
@@ -2132,34 +2273,81 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) {
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).mcc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_COUNTRY_CODE_IDX].uptr;
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).mnc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_NETWORK_CODE_IDX].uptr;
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][ENB_MNC_DIGIT_LENGTH].u8ptr;
|
||||
|
||||
AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length[l] == 3
|
||||
|| S1AP_REGISTER_ENB_REQ(msg_p).mnc[l] < 100,
|
||||
"MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n",
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).mnc[l]);
|
||||
}
|
||||
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0;
|
||||
config_getlist( &S1ParamList,S1Params,sizeof(S1Params)/sizeof(paramdef_t),aprefix);
|
||||
/* Default DRX param */
|
||||
/*
|
||||
* Here we get the config of the first CC, since the s1ap_register_enb_req_t doesn't support multiple CC.
|
||||
* There is a unique value of defaultPagingCycle per eNB (same for multiple cells).
|
||||
* Hence, it should be stated somewhere that the value should be the same for every CC, or put the value outside the CC
|
||||
* in the conf file.
|
||||
*/
|
||||
sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, 0);
|
||||
config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix);
|
||||
switch (pcch_defaultPagingCycle) {
|
||||
case 32: {
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 64: {
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case 128: {
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
case 256: {
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
LOG_E(S1AP, "Default I-DRX value in conf file is invalid (%i). Should be 32, 64, 128 or 256. \
|
||||
Default DRX set to 32 in MME configuration\n",
|
||||
pcch_defaultPagingCycle);
|
||||
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* MME connection params */
|
||||
sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k);
|
||||
|
||||
config_getlist(&S1ParamList, S1Params, sizeof(S1Params)/sizeof(paramdef_t), aprefix);
|
||||
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).nb_mme = 0;
|
||||
|
||||
for (int l = 0; l < S1ParamList.numelt; l++) {
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).nb_mme += 1;
|
||||
|
||||
strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4_address,*(S1ParamList.paramarray[l][ENB_MME_IPV4_ADDRESS_IDX].strptr));
|
||||
strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6_address,*(S1ParamList.paramarray[l][ENB_MME_IPV6_ADDRESS_IDX].strptr));
|
||||
|
||||
if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1;
|
||||
|
||||
} else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) {
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1;
|
||||
|
||||
} else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) {
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1;
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1;
|
||||
}
|
||||
|
||||
if (S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].iptr)
|
||||
if (S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].iptr) {
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].numelt;
|
||||
else
|
||||
} else {
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = 0;
|
||||
}
|
||||
|
||||
AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] <= S1AP_REGISTER_ENB_REQ(msg_p).num_plmn,
|
||||
"List of broadcast PLMN to be sent to MME can not be longer than actual "
|
||||
@@ -2170,6 +2358,7 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) {
|
||||
for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l]; ++el) {
|
||||
/* UINTARRAY gets mapped to int, see config_libconfig.c:223 */
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].iptr[el];
|
||||
|
||||
AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] >= 0
|
||||
&& S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn,
|
||||
"index for MME's MCC/MNC (%d) is an invalid index for the registered PLMN IDs (%d)\n",
|
||||
@@ -2181,8 +2370,9 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) {
|
||||
if (S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] == 0) {
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1AP_REGISTER_ENB_REQ(msg_p).num_plmn;
|
||||
|
||||
for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; ++el)
|
||||
for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; ++el){
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = el;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2192,15 +2382,18 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) {
|
||||
|
||||
if (EPC_MODE_ENABLED) {
|
||||
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG);
|
||||
|
||||
config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix);
|
||||
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr);
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr);
|
||||
}
|
||||
|
||||
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
|
||||
|
||||
// NETWORK_INTERFACES
|
||||
config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix);
|
||||
// S1AP_REGISTER_ENB_REQ (msg_p).enb_interface_name_for_S1U = strdup(enb_interface_name_for_S1U);
|
||||
|
||||
cidr = *(NETParams[ENB_IPV4_ADDRESS_FOR_S1_MME_IDX].strptr);
|
||||
address = strtok(cidr, "/");
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv6 = 0;
|
||||
|
||||
@@ -466,6 +466,8 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP,
|
||||
int header_length_last;
|
||||
int header_length_total;
|
||||
|
||||
rrc_eNB_ue_context_t *ue_contextP = NULL;
|
||||
|
||||
start_meas(&eNB->schedule_dlsch);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN);
|
||||
|
||||
@@ -1033,68 +1035,86 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP,
|
||||
// TODO: check if the lcid is active
|
||||
|
||||
LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n",
|
||||
module_idP, frameP, lcid, TBS,
|
||||
TBS - ta_len - header_length_total - sdu_length_total - 3);
|
||||
module_idP,
|
||||
frameP,
|
||||
lcid,
|
||||
TBS,
|
||||
TBS - ta_len - header_length_total - sdu_length_total - 3);
|
||||
|
||||
if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
|
||||
rlc_status = mac_rlc_status_ind(module_idP,
|
||||
rnti,
|
||||
module_idP,
|
||||
frameP,
|
||||
subframeP,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
TBS - ta_len - header_length_total - sdu_length_total - 3
|
||||
rnti,
|
||||
module_idP,
|
||||
frameP,
|
||||
subframeP,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
TBS - ta_len - header_length_total - sdu_length_total - 3
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
,0, 0
|
||||
, 0, 0
|
||||
#endif
|
||||
);
|
||||
|
||||
|
||||
);
|
||||
|
||||
if (rlc_status.bytes_in_buffer > 0) {
|
||||
LOG_D(MAC,
|
||||
"[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n",
|
||||
module_idP, frameP,
|
||||
TBS - ta_len - header_length_total - sdu_length_total - 3,
|
||||
LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n",
|
||||
module_idP,
|
||||
frameP,
|
||||
TBS - ta_len - header_length_total - sdu_length_total - 3,
|
||||
lcid,
|
||||
header_length_total);
|
||||
|
||||
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid,
|
||||
TBS, //not used
|
||||
(char *)&dlsch_buffer[sdu_length_total]
|
||||
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
|
||||
rnti,
|
||||
module_idP,
|
||||
frameP,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
TBS, //not used
|
||||
(char *)&dlsch_buffer[sdu_length_total]
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
,0, 0
|
||||
, 0, 0
|
||||
#endif
|
||||
);
|
||||
);
|
||||
|
||||
T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
|
||||
T_INT(CC_id), T_INT(rnti), T_INT(frameP),
|
||||
T_INT(subframeP), T_INT(harq_pid),
|
||||
T_INT(lcid), T_INT(sdu_lengths[num_sdus]));
|
||||
T(T_ENB_MAC_UE_DL_SDU,
|
||||
T_INT(module_idP),
|
||||
T_INT(CC_id),
|
||||
T_INT(rnti),
|
||||
T_INT(frameP),
|
||||
T_INT(subframeP),
|
||||
T_INT(harq_pid),
|
||||
T_INT(lcid),
|
||||
T_INT(sdu_lengths[num_sdus]));
|
||||
|
||||
LOG_D(MAC,
|
||||
"[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",
|
||||
module_idP, sdu_lengths[num_sdus], lcid);
|
||||
LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",
|
||||
module_idP,
|
||||
sdu_lengths[num_sdus],
|
||||
lcid);
|
||||
|
||||
sdu_lcids[num_sdus] = lcid;
|
||||
sdu_length_total += sdu_lengths[num_sdus];
|
||||
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++;
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid;
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus];
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid;
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus];
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus];
|
||||
|
||||
header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
|
||||
header_length_total += header_length_last;
|
||||
header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
|
||||
header_length_total += header_length_last;
|
||||
|
||||
num_sdus++;
|
||||
|
||||
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
|
||||
}
|
||||
} else {
|
||||
// no TBS left
|
||||
break;
|
||||
|
||||
// reset RRC inactivity timer after uplane activity
|
||||
ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti);
|
||||
ue_contextP->ue_context.ue_rrc_inactivity_timer = 1;
|
||||
|
||||
} // end if (rlc_status.bytes_in_buffer > 0)
|
||||
} else { // no TBS left
|
||||
break; // break for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1404,85 +1404,95 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
|
||||
header_len_dtch = 0;
|
||||
header_len_dtch_last = 0; // the header length of the last mac sdu
|
||||
// lcid has to be sorted before the actual allocation (similar struct as ue_list).
|
||||
/* TODO limited lcid for performance */
|
||||
for (lcid = DTCH; lcid >= DTCH; lcid--) {
|
||||
// TBD: check if the lcid is active
|
||||
/* TODO limited lcid for performance */
|
||||
for (lcid = DTCH; lcid >= DTCH; lcid--) {
|
||||
// TBD: check if the lcid is active
|
||||
header_len_dtch += 3;
|
||||
header_len_dtch_last = 3;
|
||||
|
||||
header_len_dtch += 3;
|
||||
header_len_dtch_last = 3;
|
||||
LOG_D(MAC,
|
||||
"[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n",
|
||||
module_idP, frameP, lcid, TBS,
|
||||
TBS - ta_len - header_len_dcch -
|
||||
sdu_length_total - header_len_dtch);
|
||||
LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n",
|
||||
module_idP,
|
||||
frameP,
|
||||
lcid,
|
||||
TBS,
|
||||
TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch);
|
||||
|
||||
if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ?
|
||||
rlc_status = mac_rlc_status_ind(module_idP,
|
||||
rnti,
|
||||
module_idP,
|
||||
frameP,
|
||||
subframeP,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
TBS - ta_len -
|
||||
header_len_dcch -
|
||||
sdu_length_total -
|
||||
header_len_dtch
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
,0, 0
|
||||
if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ?
|
||||
rlc_status = mac_rlc_status_ind(module_idP,
|
||||
rnti,
|
||||
module_idP,
|
||||
frameP,
|
||||
subframeP,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch
|
||||
#ifdef Rel14
|
||||
, 0, 0
|
||||
#endif
|
||||
);
|
||||
);
|
||||
|
||||
|
||||
if (rlc_status.bytes_in_buffer > 0) {
|
||||
|
||||
LOG_D(MAC,
|
||||
"[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n",
|
||||
module_idP, frameP,
|
||||
TBS - header_len_dcch -
|
||||
sdu_length_total - header_len_dtch, lcid,
|
||||
if (rlc_status.bytes_in_buffer > 0) {
|
||||
LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n",
|
||||
module_idP,
|
||||
frameP,
|
||||
TBS - header_len_dcch - sdu_length_total - header_len_dtch,
|
||||
lcid,
|
||||
header_len_dtch);
|
||||
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, TBS, //not used
|
||||
(char
|
||||
*)
|
||||
&dlsch_buffer
|
||||
[sdu_length_total]
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
,0, 0
|
||||
#endif
|
||||
);
|
||||
T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
|
||||
T_INT(CC_id), T_INT(rnti), T_INT(frameP),
|
||||
T_INT(subframeP), T_INT(harq_pid),
|
||||
T_INT(lcid), T_INT(sdu_lengths[num_sdus]));
|
||||
|
||||
LOG_D(MAC,
|
||||
"[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",
|
||||
module_idP, sdu_lengths[num_sdus], lcid);
|
||||
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
|
||||
rnti,
|
||||
module_idP,
|
||||
frameP,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
TBS, //not used
|
||||
(char *)&dlsch_buffer[sdu_length_total]
|
||||
#ifdef Rel14
|
||||
, 0, 0
|
||||
#endif
|
||||
);
|
||||
|
||||
T(T_ENB_MAC_UE_DL_SDU,
|
||||
T_INT(module_idP),
|
||||
T_INT(CC_id),
|
||||
T_INT(rnti),
|
||||
T_INT(frameP),
|
||||
T_INT(subframeP),
|
||||
T_INT(harq_pid),
|
||||
T_INT(lcid),
|
||||
T_INT(sdu_lengths[num_sdus]));
|
||||
|
||||
LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",
|
||||
module_idP,
|
||||
sdu_lengths[num_sdus],
|
||||
lcid);
|
||||
|
||||
sdu_lcids[num_sdus] = lcid;
|
||||
sdu_length_total += sdu_lengths[num_sdus];
|
||||
UE_list->
|
||||
eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]
|
||||
+= 1;
|
||||
UE_list->
|
||||
eNB_UE_stats[CC_id][UE_id].num_bytes_tx
|
||||
[lcid] += sdu_lengths[num_sdus];
|
||||
if (sdu_lengths[num_sdus] < 128) {
|
||||
header_len_dtch--;
|
||||
header_len_dtch_last--;
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1;
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus];
|
||||
|
||||
if (sdu_lengths[num_sdus] < 128) {
|
||||
header_len_dtch--;
|
||||
header_len_dtch_last--;
|
||||
}
|
||||
|
||||
num_sdus++;
|
||||
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
|
||||
} // no data for this LCID
|
||||
else {
|
||||
header_len_dtch -= 3;
|
||||
}
|
||||
} // no TBS left
|
||||
else {
|
||||
header_len_dtch -= 3;
|
||||
break;
|
||||
}
|
||||
|
||||
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
|
||||
|
||||
} else { // no data for this LCID
|
||||
header_len_dtch -= 3;
|
||||
}
|
||||
|
||||
} else { // no TBS left
|
||||
header_len_dtch -= 3;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (header_len_dtch == 0)
|
||||
header_len_dtch_last = 0;
|
||||
|
||||
@@ -111,6 +111,8 @@ rx_sdu(const module_id_t enb_mod_idP,
|
||||
(RA_t *) & RC.mac[enb_mod_idP]->common_channels[CC_idP].ra[0];
|
||||
int first_rb = 0;
|
||||
|
||||
rrc_eNB_ue_context_t *ue_contextP = NULL;
|
||||
|
||||
start_meas(&mac->rx_ulsch_sdu);
|
||||
|
||||
if ((UE_id > MAX_MOBILES_PER_ENB) || (UE_id == -1))
|
||||
@@ -672,69 +674,92 @@ rx_sdu(const module_id_t enb_mod_idP,
|
||||
// }
|
||||
break;
|
||||
|
||||
// all the DRBS
|
||||
// all the DRBS
|
||||
case DTCH:
|
||||
|
||||
default:
|
||||
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
|
||||
LOG_T(MAC, "offset: %d\n",
|
||||
(unsigned char) ((unsigned char *) payload_ptr - sduP));
|
||||
(unsigned char) ((unsigned char *) payload_ptr - sduP));
|
||||
|
||||
for (j = 0; j < 32; j++) {
|
||||
LOG_T(MAC, "%x ", payload_ptr[j]);
|
||||
LOG_T(MAC, "%x ", payload_ptr[j]);
|
||||
}
|
||||
|
||||
LOG_T(MAC, "\n");
|
||||
#endif
|
||||
if (rx_lcids[i] < NB_RB_MAX) {
|
||||
LOG_D(MAC,
|
||||
"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n",
|
||||
enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id,
|
||||
rx_lcids[i]);
|
||||
|
||||
if (UE_id != -1) {
|
||||
// adjust buffer occupancy of the correponding logical channel group
|
||||
LOG_D(MAC,
|
||||
"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n",
|
||||
enb_mod_idP, CC_idP, frameP, rx_lengths[i],
|
||||
UE_id, rx_lcids[i],
|
||||
UE_list->UE_template[CC_idP][UE_id].
|
||||
lcgidmap[rx_lcids[i]],
|
||||
UE_list->UE_template[CC_idP][UE_id].
|
||||
ul_buffer_info[UE_list->UE_template[CC_idP]
|
||||
[UE_id].lcgidmap[rx_lcids[i]]]);
|
||||
#endif
|
||||
|
||||
if (rx_lcids[i] < NB_RB_MAX) {
|
||||
|
||||
LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n",
|
||||
enb_mod_idP,
|
||||
CC_idP,
|
||||
frameP,
|
||||
rx_lengths[i],
|
||||
UE_id,
|
||||
rx_lcids[i]);
|
||||
|
||||
if (UE_id != -1) {
|
||||
// adjust buffer occupancy of the correponding logical channel group
|
||||
LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n",
|
||||
enb_mod_idP,
|
||||
CC_idP,
|
||||
frameP,
|
||||
rx_lengths[i],
|
||||
UE_id,
|
||||
rx_lcids[i],
|
||||
UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]],
|
||||
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]]);
|
||||
|
||||
if (lcgid_updated[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] == 0) {
|
||||
if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i])
|
||||
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i];
|
||||
else
|
||||
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0;
|
||||
if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) {
|
||||
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i];
|
||||
} else {
|
||||
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0;
|
||||
}
|
||||
|
||||
UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer =
|
||||
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] +
|
||||
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] +
|
||||
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] +
|
||||
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3];
|
||||
//UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4;
|
||||
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] +
|
||||
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] +
|
||||
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] +
|
||||
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3];
|
||||
}
|
||||
|
||||
if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block
|
||||
mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status);
|
||||
if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block
|
||||
mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL);
|
||||
|
||||
UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1;
|
||||
UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i];
|
||||
//clear uplane_inactivity_timer
|
||||
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
|
||||
} else { /* rx_length[i] */
|
||||
UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1;
|
||||
LOG_E(MAC,
|
||||
"[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ",
|
||||
enb_mod_idP, CC_idP, frameP, rx_lcids[i],
|
||||
UE_id);
|
||||
}
|
||||
} else { /*(UE_id != -1 */
|
||||
LOG_E(MAC,
|
||||
"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ",
|
||||
enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id);
|
||||
}
|
||||
UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1;
|
||||
UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i];
|
||||
|
||||
//clear uplane_inactivity_timer
|
||||
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
|
||||
|
||||
// reset RRC inactivity timer after uplane activity
|
||||
ue_contextP = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], rntiP);
|
||||
ue_contextP->ue_context.ue_rrc_inactivity_timer = 1;
|
||||
|
||||
} else { /* rx_length[i] */
|
||||
UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1;
|
||||
|
||||
LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ",
|
||||
enb_mod_idP,
|
||||
CC_idP,
|
||||
frameP,
|
||||
rx_lcids[i],
|
||||
UE_id);
|
||||
}
|
||||
|
||||
} else { // end if (UE_id != -1)
|
||||
LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ",
|
||||
enb_mod_idP,
|
||||
CC_idP,
|
||||
frameP,
|
||||
rx_lcids[i],
|
||||
UE_id);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -279,6 +279,9 @@ mac_rrc_data_ind(
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* Get RRC status (Connected, Idle...) of UE from RNTI
|
||||
*/
|
||||
int
|
||||
mac_eNB_get_rrc_status(
|
||||
const module_id_t Mod_idP,
|
||||
@@ -287,9 +290,7 @@ mac_eNB_get_rrc_status(
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = NULL;
|
||||
ue_context_p = rrc_eNB_get_ue_context(
|
||||
RC.rrc[Mod_idP],
|
||||
rntiP);
|
||||
ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP], rntiP);
|
||||
|
||||
if (ue_context_p != NULL) {
|
||||
return(ue_context_p->ue_context.Status);
|
||||
|
||||
@@ -184,43 +184,43 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich
|
||||
asn_enc_rval_t enc_rval;
|
||||
LTE_BCCH_BCH_Message_t *mib=&carrier->mib ;
|
||||
uint8_t sfn = (uint8_t)((frame>>2)&0xff);
|
||||
uint16_t *spare= calloc(1, sizeof(uint16_t));
|
||||
uint16_t *spare = calloc(1, sizeof(uint16_t));
|
||||
if (spare == NULL) abort();
|
||||
|
||||
switch (N_RB_DL) {
|
||||
|
||||
case 6:
|
||||
mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n6;
|
||||
break;
|
||||
case 6:
|
||||
mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n6;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n15;
|
||||
break;
|
||||
case 15:
|
||||
mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n15;
|
||||
break;
|
||||
|
||||
case 25:
|
||||
mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n25;
|
||||
break;
|
||||
case 25:
|
||||
mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n25;
|
||||
break;
|
||||
|
||||
case 50:
|
||||
mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n50;
|
||||
break;
|
||||
case 50:
|
||||
mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n50;
|
||||
break;
|
||||
|
||||
case 75:
|
||||
mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n75;
|
||||
break;
|
||||
case 75:
|
||||
mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n75;
|
||||
break;
|
||||
|
||||
case 100:
|
||||
mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n100;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Unknown dl_Bandwidth %d\n",N_RB_DL);
|
||||
case 100:
|
||||
mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n100;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Unknown dl_Bandwidth %d\n",N_RB_DL);
|
||||
}
|
||||
|
||||
AssertFatal(phich_Resource <= LTE_PHICH_Config__phich_Resource_two,"Illegal phich_Resource\n");
|
||||
mib->message.phich_Config.phich_Resource = phich_Resource;
|
||||
AssertFatal(phich_duration <= LTE_PHICH_Config__phich_Duration_extended,"Illegal phich_Duration\n");
|
||||
mib->message.phich_Config.phich_Duration = phich_duration;
|
||||
LOG_I(RRC,"[MIB] systemBandwidth %x, phich_duration %x, phich_resource %x,sfn %x\n",
|
||||
LOG_I(RRC,"[MIB] systemBandwidth %x, phich_duration %x, phich_resource %x, sfn %x\n",
|
||||
(uint32_t)mib->message.dl_Bandwidth,
|
||||
(uint32_t)phich_duration,
|
||||
(uint32_t)phich_Resource,
|
||||
@@ -704,6 +704,9 @@ uint8_t do_SIB23(uint8_t Mod_id,
|
||||
= configuration->pcch_defaultPagingCycle[CC_id];
|
||||
(*sib2)->radioResourceConfigCommon.pcch_Config.nB
|
||||
= configuration->pcch_nB[CC_id];
|
||||
LOG_I(RRC,"[SIB2] With ITTI. Basic config of paging cycle DRX: radio frame cycle length %x, paging occasion number %x\n",
|
||||
(uint32_t)configuration->pcch_defaultPagingCycle[CC_id],
|
||||
(uint32_t)configuration->pcch_nB[CC_id]);
|
||||
|
||||
// PRACH-Config
|
||||
(*sib2)->radioResourceConfigCommon.prach_Config.rootSequenceIndex
|
||||
|
||||
@@ -57,7 +57,7 @@ uint16_t get_adjacent_cell_id(uint8_t Mod_id,uint8_t index);
|
||||
uint8_t get_adjacent_cell_mod_id(uint16_t phyCellId);
|
||||
|
||||
/**
|
||||
\brief Generate configuration for SIB1 (eNB).
|
||||
\brief Generate configuration for MIB (eNB).
|
||||
@param carrier pointer to Carrier information
|
||||
@param N_RB_DL Number of downlink PRBs
|
||||
@param phich_Resource PHICH resoure parameter
|
||||
|
||||
@@ -735,7 +735,7 @@ Paging-v1130-IEs ::= SEQUENCE {
|
||||
}
|
||||
|
||||
Paging-v1310-IEs ::= SEQUENCE {
|
||||
redistributionIndication-r13 ENUMERATED {true} OPTIONAL, --Need ON
|
||||
redistributionIndication-r13 ENUMERATED {true} OPTIONAL, -- Need ON
|
||||
systemInfoModification-eDRX-r13 ENUMERATED {true} OPTIONAL, -- Need ON
|
||||
nonCriticalExtension SEQUENCE {} OPTIONAL
|
||||
}
|
||||
|
||||
@@ -387,10 +387,10 @@ typedef enum SL_TRIGGER_e {
|
||||
#define RRC_TRANSACTION_IDENTIFIER_NUMBER 3
|
||||
|
||||
typedef struct {
|
||||
unsigned short transport_block_size; /*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */
|
||||
unsigned short max_transport_blocks; /*!< \brief Maximum PDU size in bytes provided by RLC to MAC layer interface */
|
||||
unsigned long Guaranteed_bit_rate; /*!< \brief Guaranteed Bit Rate (average) to be offered by MAC layer scheduling*/
|
||||
unsigned long Max_bit_rate; /*!< \brief Maximum Bit Rate that can be offered by MAC layer scheduling*/
|
||||
unsigned short transport_block_size; /*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */
|
||||
unsigned short max_transport_blocks; /*!< \brief Maximum PDU size in bytes provided by RLC to MAC layer interface */
|
||||
unsigned long Guaranteed_bit_rate; /*!< \brief Guaranteed Bit Rate (average) to be offered by MAC layer scheduling*/
|
||||
unsigned long Max_bit_rate; /*!< \brief Maximum Bit Rate that can be offered by MAC layer scheduling*/
|
||||
uint8_t Delay_class; /*!< \brief Delay class offered by MAC layer scheduling*/
|
||||
uint8_t Target_bler; /*!< \brief Target Average Transport Block Error rate*/
|
||||
uint8_t Lchan_t; /*!< \brief Logical Channel Type (BCCH,CCCH,DCCH,DTCH_B,DTCH,MRBCH)*/
|
||||
@@ -552,7 +552,7 @@ typedef struct eNB_RRC_UE_s {
|
||||
LTE_CipheringAlgorithm_r12_t ciphering_algorithm;
|
||||
e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm;
|
||||
|
||||
uint8_t Status;
|
||||
uint8_t Status; // RRC status, type enum UE_STATE_t
|
||||
rnti_t rnti;
|
||||
uint64_t random_ue_identity;
|
||||
|
||||
@@ -573,7 +573,7 @@ typedef struct eNB_RRC_UE_s {
|
||||
security_capabilities_t security_capabilities;
|
||||
|
||||
/* Total number of e_rab already setup in the list */
|
||||
uint8_t setup_e_rabs;
|
||||
uint8_t setup_e_rabs;
|
||||
/* Number of e_rab to be setup in the list */
|
||||
uint8_t nb_of_e_rabs;
|
||||
/* Number of e_rab to be modified in the list */
|
||||
@@ -599,6 +599,9 @@ typedef struct eNB_RRC_UE_s {
|
||||
uint32_t ue_release_timer_thres_rrc;
|
||||
uint32_t ue_reestablishment_timer;
|
||||
uint32_t ue_reestablishment_timer_thres;
|
||||
/* RRC inactivity timer: on timeout, should release RRC connection for inactivity on all E-RABs */
|
||||
uint32_t ue_rrc_inactivity_timer;
|
||||
uint32_t ue_rrc_inactivity_timer_thres;
|
||||
uint8_t e_rab_release_command_flag;
|
||||
int8_t reestablishment_xid;
|
||||
} eNB_RRC_UE_t;
|
||||
|
||||
+311
-217
@@ -832,47 +832,66 @@ rrc_eNB_free_mem_UE_context(
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// should be called when UE is lost by eNB
|
||||
/*
|
||||
* Should be called when UE context in eNB should be released
|
||||
* or when S1 command UE_CONTEXT_RELEASE_REQ should be sent
|
||||
*/
|
||||
void
|
||||
rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s* const ue_context_pP)
|
||||
rrc_eNB_free_UE(
|
||||
const module_id_t enb_mod_idP,
|
||||
const struct rrc_eNB_ue_context_s *const ue_context_pP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
|
||||
|
||||
protocol_ctxt_t ctxt;
|
||||
rnti_t rnti = ue_context_pP->ue_context.rnti;
|
||||
|
||||
if (enb_mod_idP >= NB_eNB_INST) {
|
||||
LOG_I(RRC, "eNB inst invalid (%d/%d) for UE %x!\n",enb_mod_idP, NB_eNB_INST,rnti);
|
||||
return;
|
||||
LOG_E(RRC, "eNB instance invalid (%d/%d) for UE %x!\n",
|
||||
enb_mod_idP,
|
||||
NB_eNB_INST,
|
||||
rnti);
|
||||
|
||||
return;
|
||||
}
|
||||
/* ue_context_p = rrc_eNB_get_ue_context(
|
||||
&RC.rrc[enb_mod_idP],
|
||||
rntiP
|
||||
);
|
||||
*/
|
||||
if (NULL != ue_context_pP) {
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, rnti, 0, 0,enb_mod_idP);
|
||||
LOG_W(RRC, "[eNB %d] Removing UE RNTI %x\n", enb_mod_idP, rnti);
|
||||
|
||||
if(EPC_MODE_ENABLED) {
|
||||
|
||||
if((ue_context_pP->ue_context.ul_failure_timer >= 20000) &&
|
||||
(mac_eNB_get_rrc_status(enb_mod_idP,rnti) >= RRC_CONNECTED)) {
|
||||
LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ RNTI %x\n", enb_mod_idP, rnti);
|
||||
rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21); // send cause 21: connection with ue lost
|
||||
if (EPC_MODE_ENABLED) {
|
||||
if ((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) {
|
||||
LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 21, radio connection with ue lost\n",
|
||||
enb_mod_idP,
|
||||
rnti);
|
||||
|
||||
rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21);
|
||||
// send cause 21: radio connection with ue lost
|
||||
/* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered)
|
||||
* If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before
|
||||
* triggering the S1 UE Context Release Request procedure
|
||||
* in order to allow the UE to perform the NAS recovery
|
||||
* procedure, see TS 23.401 [17].
|
||||
*/
|
||||
return;
|
||||
* If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before
|
||||
* triggering the S1 UE Context Release Request procedure in order to allow the UE to perform the NAS recovery
|
||||
* procedure, see TS 23.401 [17].
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres) &&
|
||||
(mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) {
|
||||
LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n",
|
||||
enb_mod_idP,
|
||||
rnti);
|
||||
|
||||
rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 20);
|
||||
// send cause 20: user inactivity
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
// add UE info to freeList
|
||||
LOG_I(RRC, "put UE %x into freeList\n", rnti);
|
||||
put_UE_in_freelist(enb_mod_idP, rnti, 1);
|
||||
}
|
||||
|
||||
LOG_W(RRC, "[eNB %d] Removing UE RNTI %x\n",
|
||||
enb_mod_idP,
|
||||
rnti);
|
||||
|
||||
// add UE info to freeList
|
||||
LOG_I(RRC, "Put UE %x into freeList\n",
|
||||
rnti);
|
||||
|
||||
put_UE_in_freelist(enb_mod_idP, rnti, 1);
|
||||
}
|
||||
|
||||
void remove_UE_from_freelist(module_id_t mod_id, rnti_t rnti)
|
||||
@@ -999,11 +1018,14 @@ void release_UE_in_freeList(module_id_t mod_id)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* Process the rrc connection setup complete message from UE (SRB1 Active)
|
||||
*/
|
||||
void
|
||||
rrc_eNB_process_RRCConnectionSetupComplete(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
rrc_eNB_ue_context_t* ue_context_pP,
|
||||
LTE_RRCConnectionSetupComplete_r8_IEs_t * rrcConnectionSetupComplete
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_eNB_ue_context_t *ue_context_pP,
|
||||
LTE_RRCConnectionSetupComplete_r8_IEs_t *rrcConnectionSetupComplete
|
||||
)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
@@ -1011,22 +1033,20 @@ rrc_eNB_process_RRCConnectionSetupComplete(
|
||||
PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing LTE_RRCConnectionSetupComplete from UE (SRB1 Active)\n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
|
||||
|
||||
ue_context_pP->ue_context.Srb1.Active=1;
|
||||
ue_context_pP->ue_context.Srb1.Active = 1;
|
||||
ue_context_pP->ue_context.Status = RRC_CONNECTED;
|
||||
ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED
|
||||
ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres = 10000; // The value should come from config file
|
||||
|
||||
T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
|
||||
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
|
||||
|
||||
if (EPC_MODE_ENABLED == 1) {
|
||||
// Forward message to S1AP layer
|
||||
rrc_eNB_send_S1AP_NAS_FIRST_REQ(
|
||||
ctxt_pP,
|
||||
ue_context_pP,
|
||||
rrcConnectionSetupComplete);
|
||||
rrc_eNB_send_S1AP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcConnectionSetupComplete);
|
||||
} else {
|
||||
// RRC loop back (no S1AP), send SecurityModeCommand to UE
|
||||
rrc_eNB_generate_SecurityModeCommand(
|
||||
ctxt_pP,
|
||||
ue_context_pP);
|
||||
// rrc_eNB_generate_UECapabilityEnquiry(enb_mod_idP,frameP,ue_mod_idP);
|
||||
rrc_eNB_generate_SecurityModeCommand(ctxt_pP, ue_context_pP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1349,6 +1369,8 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete(
|
||||
uint8_t next_xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
|
||||
ue_context_pP->ue_context.Status = RRC_CONNECTED;
|
||||
ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED
|
||||
ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres = 10000; // The value should come from config file
|
||||
ue_context_pP->ue_context.reestablishment_xid = next_xid;
|
||||
|
||||
SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
|
||||
@@ -1979,44 +2001,41 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject(
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* Generate the RRC Connection Release to UE.
|
||||
* If received, UE should switch to RRC_IDLE mode.
|
||||
*/
|
||||
void
|
||||
rrc_eNB_generate_RRCConnectionRelease(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
rrc_eNB_ue_context_t* const ue_context_pP
|
||||
rrc_eNB_ue_context_t* const ue_context_pP
|
||||
)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
uint8_t buffer[RRC_BUF_SIZE];
|
||||
uint16_t size = 0;
|
||||
|
||||
uint8_t buffer[RRC_BUF_SIZE];
|
||||
uint16_t size;
|
||||
memset(buffer, 0, RRC_BUF_SIZE);
|
||||
|
||||
T(T_ENB_RRC_CONNECTION_RELEASE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
|
||||
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
|
||||
|
||||
memset(buffer, 0, RRC_BUF_SIZE);
|
||||
size = do_RRCConnectionRelease(ctxt_pP->module_id, buffer,rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id));
|
||||
// set release timer
|
||||
//ue_context_pP->ue_context.ue_release_timer=1;
|
||||
// remove UE after 10 frames after LTE_RRCConnectionRelease is triggered
|
||||
//ue_context_pP->ue_context.ue_release_timer_thres=100;
|
||||
// set release timer
|
||||
// ue_context_pP->ue_context.ue_release_timer_rrc = 1;
|
||||
// remove UE after 10 frames after LTE_RRCConnectionRelease is triggered
|
||||
// ue_context_pP->ue_context.ue_release_timer_thres_rrc = 100;
|
||||
ue_context_pP->ue_context.ue_reestablishment_timer = 0;
|
||||
ue_context_pP->ue_context.ue_release_timer = 0;
|
||||
//ue_context_pP->ue_context.ue_release_timer_s1 = 0;
|
||||
ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0;
|
||||
|
||||
LOG_I(RRC,
|
||||
PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate LTE_RRCConnectionRelease (bytes %d)\n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
size);
|
||||
PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCConnectionRelease (bytes %d)\n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
size);
|
||||
|
||||
LOG_D(RRC,
|
||||
PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (rrcConnectionRelease MUI %d) --->[PDCP][RB %u]\n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
size,
|
||||
rrc_eNB_mui,
|
||||
DCCH);
|
||||
PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (rrcConnectionRelease MUI %d) --->[PDCP][RB %u]\n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
size,
|
||||
rrc_eNB_mui,
|
||||
DCCH);
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_RRC_ENB,
|
||||
@@ -2028,31 +2047,39 @@ rrc_eNB_generate_RRCConnectionRelease(
|
||||
ue_context_pP->ue_context.rnti,
|
||||
rrc_eNB_mui,
|
||||
size);
|
||||
|
||||
pthread_mutex_lock(&rrc_release_freelist);
|
||||
for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){
|
||||
if(rrc_release_info.RRC_release_ctrl[release_num].flag == 0){
|
||||
if(ue_context_pP->ue_context.ue_release_timer_s1 > 0){
|
||||
for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
|
||||
if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) {
|
||||
|
||||
if (ue_context_pP->ue_context.ue_release_timer_s1 > 0) {
|
||||
rrc_release_info.RRC_release_ctrl[release_num].flag = 1;
|
||||
}else{
|
||||
} else {
|
||||
rrc_release_info.RRC_release_ctrl[release_num].flag = 2;
|
||||
}
|
||||
|
||||
rrc_release_info.RRC_release_ctrl[release_num].rnti = ctxt_pP->rnti;
|
||||
rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui = rrc_eNB_mui;
|
||||
rrc_release_info.num_UEs++;
|
||||
LOG_D(RRC,"Generate DLSCH Release send: index %d rnti %x mui %d flag %d \n",release_num,
|
||||
ctxt_pP->rnti, rrc_eNB_mui,rrc_release_info.RRC_release_ctrl[release_num].flag);
|
||||
|
||||
LOG_D(RRC, "Generate DLSCH Release send: index %d rnti %x mui %d flag %d \n",
|
||||
release_num,
|
||||
ctxt_pP->rnti,
|
||||
rrc_eNB_mui,
|
||||
rrc_release_info.RRC_release_ctrl[release_num].flag);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&rrc_release_freelist);
|
||||
rrc_data_req(
|
||||
ctxt_pP,
|
||||
DCCH,
|
||||
rrc_eNB_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
size,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
|
||||
rrc_data_req(ctxt_pP,
|
||||
DCCH,
|
||||
rrc_eNB_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
size,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
}
|
||||
|
||||
uint8_t qci_to_priority[9]={2,4,3,5,1,6,7,8,9};
|
||||
@@ -5346,6 +5373,11 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover(
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* TODO: * add function description
|
||||
* * add ue_rrc_inactivity_timer set
|
||||
* * format the function correctly
|
||||
*/
|
||||
void
|
||||
rrc_eNB_process_RRCConnectionReconfigurationComplete(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
@@ -6849,7 +6881,6 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) {
|
||||
ctxt_pP,
|
||||
ue_context_p,
|
||||
&ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8);
|
||||
ue_context_p->ue_context.Status = RRC_CONNECTED;
|
||||
LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_CONNECTED \n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
|
||||
|
||||
@@ -7715,217 +7746,280 @@ LTE_SL_DiscConfig_r12_t rrc_eNB_get_sidelink_discTXPool( const protocol_ctxt_t*
|
||||
//sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discTxConfig_r12;
|
||||
return sl_DiscConfig;
|
||||
}
|
||||
|
||||
RRC_status_t
|
||||
rrc_rx_tx(
|
||||
protocol_ctxt_t* const ctxt_pP,
|
||||
const int CC_id
|
||||
const int CC_id
|
||||
)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
//uint8_t UE_id;
|
||||
int32_t current_timestamp_ms, ref_timestamp_ms;
|
||||
int32_t current_timestamp_ms = 0;
|
||||
int32_t ref_timestamp_ms = 0;
|
||||
struct timeval ts;
|
||||
struct rrc_eNB_ue_context_s *ue_context_p = NULL,*ue_to_be_removed = NULL;
|
||||
struct rrc_eNB_ue_context_s *ue_context_p = NULL;
|
||||
struct rrc_eNB_ue_context_s *ue_to_be_removed = NULL;
|
||||
|
||||
#ifdef LOCALIZATION
|
||||
double estimated_distance;
|
||||
protocol_ctxt_t ctxt;
|
||||
|
||||
double estimated_distance = 0;
|
||||
protocol_ctxt_t ctxt;
|
||||
|
||||
#endif
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_IN);
|
||||
|
||||
check_handovers(ctxt_pP);
|
||||
// counetr, and get the value and aggregate
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_IN);
|
||||
|
||||
// check for UL failure
|
||||
check_handovers(ctxt_pP); // counter, get the value and aggregate
|
||||
|
||||
// check for UL failure or for UE to be released
|
||||
RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
|
||||
ctxt_pP->rnti = ue_context_p->ue_id_rnti;
|
||||
if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe==0)) {
|
||||
if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) {
|
||||
LOG_I(RRC,"UE rnti %x:S-TMSI %x failure timer %d/8\n",
|
||||
ue_context_p->ue_context.rnti,
|
||||
ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
|
||||
ue_context_p->ue_context.ul_failure_timer);
|
||||
}
|
||||
else {
|
||||
LOG_I(RRC,"UE rnti %x failure timer %d/8\n",
|
||||
ue_context_p->ue_context.rnti,
|
||||
ue_context_p->ue_context.ul_failure_timer);
|
||||
}
|
||||
|
||||
if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe == 0)) {
|
||||
if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) {
|
||||
LOG_I(RRC, "UE rnti %x: S-TMSI %x failure timer %d/8\n",
|
||||
ue_context_p->ue_context.rnti,
|
||||
ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
|
||||
ue_context_p->ue_context.ul_failure_timer);
|
||||
} else {
|
||||
LOG_I(RRC, "UE rnti %x failure timer %d/8\n",
|
||||
ue_context_p->ue_context.rnti,
|
||||
ue_context_p->ue_context.ul_failure_timer);
|
||||
}
|
||||
}
|
||||
if (ue_context_p->ue_context.ul_failure_timer>0) {
|
||||
ue_context_p->ue_context.ul_failure_timer++;
|
||||
if (ue_context_p->ue_context.ul_failure_timer >= 20000) {
|
||||
// remove UE after 20 seconds after MAC has indicated UL failure
|
||||
LOG_I(RRC,"Removing UE %x instance\n",ue_context_p->ue_context.rnti);
|
||||
ue_to_be_removed = ue_context_p;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ue_context_p->ue_context.ul_failure_timer > 0) {
|
||||
ue_context_p->ue_context.ul_failure_timer++;
|
||||
|
||||
if (ue_context_p->ue_context.ul_failure_timer >= 20000) {
|
||||
// remove UE after 20 seconds after MAC (or else) has indicated UL failure
|
||||
LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n",
|
||||
ue_context_p->ue_context.rnti);
|
||||
|
||||
ue_to_be_removed = ue_context_p;
|
||||
break; // break RB_FOREACH
|
||||
}
|
||||
}
|
||||
if (ue_context_p->ue_context.ue_release_timer_s1>0) {
|
||||
|
||||
if (ue_context_p->ue_context.ue_release_timer_s1 > 0) {
|
||||
ue_context_p->ue_context.ue_release_timer_s1++;
|
||||
if (ue_context_p->ue_context.ue_release_timer_s1 >=
|
||||
ue_context_p->ue_context.ue_release_timer_thres_s1) {
|
||||
LOG_I(RRC,"Removing UE %x instance Because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n",
|
||||
ue_context_p->ue_context.rnti, ue_context_p->ue_context.ue_release_timer_thres_s1);
|
||||
// ue_context_p->ue_context.ue_release_timer_s1 = 0;
|
||||
|
||||
if (ue_context_p->ue_context.ue_release_timer_s1 >= ue_context_p->ue_context.ue_release_timer_thres_s1) {
|
||||
LOG_I(RRC, "Removing UE %x instance, because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n",
|
||||
ue_context_p->ue_context.rnti,
|
||||
ue_context_p->ue_context.ue_release_timer_thres_s1);
|
||||
|
||||
#if defined(ENABLE_USE_MME)
|
||||
#if defined(ENABLE_ITTI)
|
||||
|
||||
rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p);
|
||||
|
||||
#endif
|
||||
#else
|
||||
|
||||
ue_to_be_removed = ue_context_p;
|
||||
|
||||
#endif
|
||||
ue_context_p->ue_context.ue_release_timer_s1 = 0;
|
||||
break;
|
||||
break; // break RB_FOREACH
|
||||
} // end if timer_s1 timeout
|
||||
} // end if timer_s1 > 0 (S1 UE_CONTEXT_RELEASE_REQ ongoing)
|
||||
|
||||
if (ue_context_p->ue_context.ue_release_timer_rrc > 0) {
|
||||
ue_context_p->ue_context.ue_release_timer_rrc++;
|
||||
|
||||
if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) {
|
||||
LOG_I(RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n",
|
||||
ue_context_p->ue_context.rnti);
|
||||
|
||||
ue_context_p->ue_context.ue_release_timer_rrc = 0;
|
||||
ue_to_be_removed = ue_context_p;
|
||||
break; // break RB_FOREACH
|
||||
}
|
||||
}
|
||||
|
||||
if (ue_context_p->ue_context.ue_release_timer_rrc>0) {
|
||||
ue_context_p->ue_context.ue_release_timer_rrc++;
|
||||
if (ue_context_p->ue_context.ue_release_timer_rrc >=
|
||||
ue_context_p->ue_context.ue_release_timer_thres_rrc) {
|
||||
LOG_I(RRC,"Removing UE %x instance After UE_CONTEXT_RELEASE_Complete\n", ue_context_p->ue_context.rnti);
|
||||
ue_context_p->ue_context.ue_release_timer_rrc = 0;
|
||||
ue_to_be_removed = ue_context_p;
|
||||
ue_context_p->ue_context.ue_release_timer_rrc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_lock(&rrc_release_freelist);
|
||||
if(rrc_release_info.num_UEs > 0){
|
||||
pthread_mutex_lock(&rrc_release_freelist);
|
||||
if (rrc_release_info.num_UEs > 0) {
|
||||
uint16_t release_total = 0;
|
||||
for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){
|
||||
if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0){
|
||||
|
||||
for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
|
||||
if (rrc_release_info.RRC_release_ctrl[release_num].flag > 0) {
|
||||
release_total++;
|
||||
}
|
||||
if( (rrc_release_info.RRC_release_ctrl[release_num].flag > 2) &&
|
||||
(rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)){
|
||||
ue_context_p->ue_context.ue_release_timer_rrc = 1;
|
||||
ue_context_p->ue_context.ue_release_timer_thres_rrc = 100;
|
||||
|
||||
if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) &&
|
||||
(rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)) {
|
||||
|
||||
ue_context_p->ue_context.ue_release_timer_rrc = 1;
|
||||
ue_context_p->ue_context.ue_release_timer_thres_rrc = 100;
|
||||
|
||||
#if defined(ENABLE_USE_MME)
|
||||
#if defined(ENABLE_ITTI)
|
||||
int e_rab;
|
||||
MessageDef *msg_complete_p = NULL;
|
||||
MessageDef *msg_delete_tunnels_p = NULL;
|
||||
uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id;
|
||||
if(rrc_release_info.RRC_release_ctrl[release_num].flag == 4){
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_RRC_ENB,
|
||||
MSC_S1AP_ENB,
|
||||
NULL,0,
|
||||
"0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ",
|
||||
eNB_ue_s1ap_id);
|
||||
msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE);
|
||||
S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id;
|
||||
itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p);
|
||||
}
|
||||
MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id);
|
||||
msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
|
||||
memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
|
||||
// do not wait response
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
|
||||
for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] =
|
||||
ue_context_p->ue_context.enb_gtp_ebi[e_rab];
|
||||
// erase data
|
||||
ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
|
||||
memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
|
||||
ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
|
||||
}
|
||||
itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p);
|
||||
struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
|
||||
rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(
|
||||
RC.rrc[ctxt_pP->module_id],
|
||||
0,
|
||||
eNB_ue_s1ap_id);
|
||||
if (NULL != rrc_ue_s1ap_ids) {
|
||||
rrc_eNB_S1AP_remove_ue_ids(
|
||||
RC.rrc[ctxt_pP->module_id],
|
||||
rrc_ue_s1ap_ids);
|
||||
}
|
||||
|
||||
int e_rab = 0;
|
||||
MessageDef *msg_complete_p = NULL;
|
||||
MessageDef *msg_delete_tunnels_p = NULL;
|
||||
uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id;
|
||||
|
||||
if (rrc_release_info.RRC_release_ctrl[release_num].flag == 4) { // if timer_s1 == 0
|
||||
MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_S1AP_ENB, NULL, 0,
|
||||
"0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ",
|
||||
eNB_ue_s1ap_id);
|
||||
|
||||
msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE);
|
||||
S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id;
|
||||
itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p);
|
||||
}
|
||||
|
||||
MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id);
|
||||
|
||||
msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
|
||||
memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
|
||||
|
||||
// do not wait response
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
|
||||
|
||||
for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] =
|
||||
ue_context_p->ue_context.enb_gtp_ebi[e_rab];
|
||||
|
||||
// erase data
|
||||
ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
|
||||
memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
|
||||
ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
|
||||
}
|
||||
|
||||
itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p);
|
||||
|
||||
struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
|
||||
|
||||
rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id);
|
||||
|
||||
if (rrc_ue_s1ap_ids != NULL) {
|
||||
rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
rrc_release_info.RRC_release_ctrl[release_num].flag = 0;
|
||||
rrc_release_info.num_UEs--;
|
||||
break;
|
||||
}
|
||||
if(release_total >= rrc_release_info.num_UEs)
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&rrc_release_freelist);
|
||||
break; // break for (release_num)
|
||||
} // end if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && ...
|
||||
|
||||
if (ue_context_p->ue_context.ue_reestablishment_timer>0) {
|
||||
ue_context_p->ue_context.ue_reestablishment_timer++;
|
||||
if (ue_context_p->ue_context.ue_reestablishment_timer >=
|
||||
ue_context_p->ue_context.ue_reestablishment_timer_thres) {
|
||||
LOG_I(RRC,"UE %d reestablishment_timer max\n",ue_context_p->ue_context.rnti);
|
||||
ue_context_p->ue_context.ul_failure_timer = 20000;
|
||||
if (release_total >= rrc_release_info.num_UEs) {
|
||||
break; // break for (release_num)
|
||||
}
|
||||
} // end for (release_num)
|
||||
} // end if (rrc_release_info.num_UEs > 0)
|
||||
pthread_mutex_unlock(&rrc_release_freelist);
|
||||
|
||||
if (ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) {
|
||||
ue_context_p->ue_context.ue_rrc_inactivity_timer++;
|
||||
|
||||
if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= ue_context_p->ue_context.ue_rrc_inactivity_timer_thres) {
|
||||
LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n",
|
||||
ue_context_p->ue_context.rnti);
|
||||
|
||||
ue_to_be_removed = ue_context_p;
|
||||
ue_context_p->ue_context.ue_reestablishment_timer = 0;
|
||||
break;
|
||||
break; // break RB_FOREACH
|
||||
}
|
||||
}
|
||||
|
||||
if (ue_context_p->ue_context.ue_release_timer>0) {
|
||||
ue_context_p->ue_context.ue_release_timer++;
|
||||
if (ue_context_p->ue_context.ue_release_timer >=
|
||||
ue_context_p->ue_context.ue_release_timer_thres) {
|
||||
LOG_I(RRC,"Removing UE %x instance\n",ue_context_p->ue_context.rnti);
|
||||
ue_to_be_removed = ue_context_p;
|
||||
if (ue_context_p->ue_context.ue_reestablishment_timer > 0) {
|
||||
ue_context_p->ue_context.ue_reestablishment_timer++;
|
||||
|
||||
if (ue_context_p->ue_context.ue_reestablishment_timer >= ue_context_p->ue_context.ue_reestablishment_timer_thres) {
|
||||
LOG_I(RRC, "Removing UE %x instance because of reestablishment_timer timeout\n",
|
||||
ue_context_p->ue_context.rnti);
|
||||
|
||||
ue_context_p->ue_context.ul_failure_timer = 20000; // lead to send S1 UE_CONTEXT_RELEASE_REQ
|
||||
ue_to_be_removed = ue_context_p;
|
||||
ue_context_p->ue_context.ue_reestablishment_timer = 0;
|
||||
break; // break RB_FOREACH
|
||||
}
|
||||
}
|
||||
|
||||
if (ue_context_p->ue_context.ue_release_timer > 0) {
|
||||
ue_context_p->ue_context.ue_release_timer++;
|
||||
|
||||
if (ue_context_p->ue_context.ue_release_timer >= ue_context_p->ue_context.ue_release_timer_thres) {
|
||||
LOG_I(RRC, "Removing UE %x instance because of RRC Connection Setup timer timeout\n",
|
||||
ue_context_p->ue_context.rnti);
|
||||
/*
|
||||
* TODO: Naming problem here: ue_release_timer seems to have been used when RRC Connection Release was sent.
|
||||
* It is no more the case.
|
||||
* The timer should be renamed.
|
||||
*/
|
||||
|
||||
ue_to_be_removed = ue_context_p;
|
||||
ue_context_p->ue_context.ue_release_timer = 0;
|
||||
break;
|
||||
}
|
||||
break; // break RB_FOREACH
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end RB_FOREACH
|
||||
|
||||
if (ue_to_be_removed) {
|
||||
if(ue_to_be_removed->ue_context.ul_failure_timer >= 20000) {
|
||||
ue_to_be_removed->ue_context.ue_release_timer_s1 = 1;
|
||||
ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100;
|
||||
ue_to_be_removed->ue_context.ue_release_timer = 0;
|
||||
ue_to_be_removed->ue_context.ue_reestablishment_timer = 0;
|
||||
if ((ue_to_be_removed->ue_context.ul_failure_timer >= 20000) ||
|
||||
(ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= ue_to_be_removed->ue_context.ue_rrc_inactivity_timer_thres)) {
|
||||
ue_to_be_removed->ue_context.ue_release_timer_s1 = 1;
|
||||
ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100;
|
||||
ue_to_be_removed->ue_context.ue_release_timer = 0;
|
||||
ue_to_be_removed->ue_context.ue_reestablishment_timer = 0;
|
||||
}
|
||||
rrc_eNB_free_UE(ctxt_pP->module_id,ue_to_be_removed);
|
||||
if(ue_to_be_removed->ue_context.ul_failure_timer >= 20000){
|
||||
|
||||
rrc_eNB_free_UE(ctxt_pP->module_id, ue_to_be_removed);
|
||||
|
||||
if (ue_to_be_removed->ue_context.ul_failure_timer >= 20000) {
|
||||
ue_to_be_removed->ue_context.ul_failure_timer = 0;
|
||||
}
|
||||
|
||||
if (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= ue_to_be_removed->ue_context.ue_rrc_inactivity_timer_thres) {
|
||||
ue_to_be_removed->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RRC_LOCALIZATION
|
||||
|
||||
/* for the localization, only primary CC_id might be relevant*/
|
||||
gettimeofday(&ts, NULL);
|
||||
|
||||
current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000;
|
||||
ref_timestamp_ms = RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms;
|
||||
|
||||
RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
|
||||
ctxt = *ctxt_pP;
|
||||
ctxt.rnti = ue_context_p->ue_context.rnti;
|
||||
estimated_distance = rrc_get_estimated_ue_distance(
|
||||
&ctxt,
|
||||
CC_id,
|
||||
RC.rrc[ctxt_pP->module_id]->loc_type);
|
||||
|
||||
estimated_distance = rrc_get_estimated_ue_distance(&ctxt, CC_id, RC.rrc[ctxt_pP->module_id]->loc_type);
|
||||
|
||||
if ((current_timestamp_ms - ref_timestamp_ms > RC.rrc[ctxt_pP->module_id]->aggregation_period_ms) &&
|
||||
estimated_distance != -1) {
|
||||
LOG_D(LOCALIZE, " RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n",
|
||||
|
||||
LOG_D(LOCALIZE, "RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n",
|
||||
ctxt.rnti,
|
||||
ctxt_pP->module_id,
|
||||
current_timestamp_ms,
|
||||
ctxt_pP->frame,
|
||||
estimated_distance);
|
||||
LOG_D(LOCALIZE, " RRC status %d\n", ue_context_p->ue_context.Status);
|
||||
push_front(&RC.rrc[ctxt_pP->module_id]->loc_list,
|
||||
estimated_distance);
|
||||
|
||||
LOG_D(LOCALIZE, "RRC status %d\n",
|
||||
ue_context_p->ue_context.Status);
|
||||
|
||||
push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, estimated_distance);
|
||||
|
||||
RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms;
|
||||
}
|
||||
}
|
||||
} // end if
|
||||
} // end RB_FOREACH
|
||||
|
||||
#endif
|
||||
|
||||
(void)ts; /* remove gcc warning "unused variable" */
|
||||
(void)ref_timestamp_ms; /* remove gcc warning "unused variable" */
|
||||
(void)current_timestamp_ms; /* remove gcc warning "unused variable" */
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT);
|
||||
return (RRC_OK);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_OUT);
|
||||
|
||||
return RRC_OK;
|
||||
}
|
||||
|
||||
|
||||
+243
-124
@@ -37,6 +37,10 @@
|
||||
# include "enb_config.h"
|
||||
# include "common/ran_context.h"
|
||||
|
||||
# include "s1ap_eNB_defs.h"
|
||||
# include "s1ap_eNB_management_procedures.h"
|
||||
# include "s1ap_eNB_ue_context.h"
|
||||
|
||||
# if defined(ENABLE_ITTI)
|
||||
# include "asn1_conversions.h"
|
||||
# include "intertask_interface.h"
|
||||
@@ -161,6 +165,10 @@ void extract_imsi(uint8_t *pdu_buf, uint32_t pdu_len, rrc_eNB_ue_context_t *ue_c
|
||||
|
||||
# if defined(ENABLE_ITTI)
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* Get the UE S1 struct containing hashtables S1_id/UE_id.
|
||||
* Is also used to set the S1_id of the UE, depending on inputs.
|
||||
*/
|
||||
struct rrc_ue_s1ap_ids_s*
|
||||
rrc_eNB_S1AP_get_ue_ids(
|
||||
eNB_RRC_INST* const rrc_instance_pP,
|
||||
@@ -171,48 +179,146 @@ rrc_eNB_S1AP_get_ue_ids(
|
||||
{
|
||||
rrc_ue_s1ap_ids_t *result = NULL;
|
||||
rrc_ue_s1ap_ids_t *result2 = NULL;
|
||||
/*****************************/
|
||||
instance_t instance = 0;
|
||||
s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL;
|
||||
s1ap_eNB_ue_context_t *ue_desc_p = NULL;
|
||||
rrc_eNB_ue_context_t *ue_context_p = NULL;
|
||||
/*****************************/
|
||||
hashtable_rc_t h_rc;
|
||||
|
||||
// we assume that a rrc_ue_s1ap_ids_s is initially inserted in initial_id2_s1ap_ids
|
||||
if (eNB_ue_s1ap_id > 0) {
|
||||
h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&result);
|
||||
}
|
||||
if (ue_initial_id != UE_INITIAL_ID_INVALID) {
|
||||
h_rc = hashtable_get(rrc_instance_pP->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void**)&result);
|
||||
if (h_rc == HASH_TABLE_OK) {
|
||||
if (eNB_ue_s1ap_id > 0) {
|
||||
h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&result2);
|
||||
if (h_rc != HASH_TABLE_OK) {
|
||||
result2 = malloc(sizeof(*result2));
|
||||
if (NULL != result2) {
|
||||
*result2 = *result;
|
||||
result2->eNB_ue_s1ap_id = eNB_ue_s1ap_id;
|
||||
result->eNB_ue_s1ap_id = eNB_ue_s1ap_id;
|
||||
h_rc = hashtable_insert(rrc_instance_pP->s1ap_id2_s1ap_ids,
|
||||
(hash_key_t)eNB_ue_s1ap_id,
|
||||
result2);
|
||||
|
||||
if (h_rc == HASH_TABLE_OK) {
|
||||
|
||||
if (eNB_ue_s1ap_id > 0) {
|
||||
h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&result2);
|
||||
|
||||
if (h_rc != HASH_TABLE_OK) { // this case is equivalent to associate eNB_ue_s1ap_id and ue_initial_id
|
||||
result2 = malloc(sizeof(*result2));
|
||||
|
||||
if (NULL != result2) {
|
||||
*result2 = *result;
|
||||
|
||||
result2->eNB_ue_s1ap_id = eNB_ue_s1ap_id;
|
||||
result->eNB_ue_s1ap_id = eNB_ue_s1ap_id;
|
||||
|
||||
h_rc = hashtable_insert(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, result2);
|
||||
|
||||
if (h_rc != HASH_TABLE_OK) {
|
||||
LOG_E(S1AP, "[eNB %ld] Error while hashtable_insert in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32"\n",
|
||||
rrc_instance_pP - RC.rrc[0], eNB_ue_s1ap_id);
|
||||
LOG_E(S1AP, "[eNB %ld] Error while hashtable_insert in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32"\n",
|
||||
rrc_instance_pP - RC.rrc[0],
|
||||
eNB_ue_s1ap_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else { // here we should check that the association was done correctly
|
||||
|
||||
if ((result->ue_initial_id != result2->ue_initial_id) || (result->eNB_ue_s1ap_id != result2->eNB_ue_s1ap_id)) {
|
||||
|
||||
LOG_E(S1AP, "[eNB %ld] Error while hashtable_get, two rrc_ue_s1ap_ids_t that should be equal, are not:\n \
|
||||
ue_initial_id 1 = %"PRIu16",\n \
|
||||
ue_initial_id 2 = %"PRIu16",\n \
|
||||
eNB_ue_s1ap_id 1 = %"PRIu32",\n \
|
||||
eNB_ue_s1ap_id 2 = %"PRIu32"\n",
|
||||
rrc_instance_pP - RC.rrc[0],
|
||||
result->ue_initial_id,
|
||||
result2->ue_initial_id,
|
||||
result->eNB_ue_s1ap_id,
|
||||
result2->eNB_ue_s1ap_id);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} // end if if (eNB_ue_s1ap_id > 0)
|
||||
|
||||
} else { // end if (h_rc == HASH_TABLE_OK)
|
||||
|
||||
LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in initial_id2_s1ap_ids ue_initial_id %"PRIu16"\n",
|
||||
rrc_instance_pP - RC.rrc[0],
|
||||
ue_initial_id);
|
||||
/*
|
||||
* At the moment this is written, this case shouldn't (cannot) happen and is equivalent to an error.
|
||||
* One could try to find the struct instance based on s1ap_id2_s1ap_ids and eNB_ue_s1ap_id (if > 0),
|
||||
* but this behavior is not expected at the moment.
|
||||
*/
|
||||
|
||||
} // end else (h_rc != HASH_TABLE_OK)
|
||||
|
||||
} else { // end if (ue_initial_id != UE_INITIAL_ID_INVALID)
|
||||
|
||||
if (eNB_ue_s1ap_id > 0) {
|
||||
h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&result);
|
||||
|
||||
if (h_rc != HASH_TABLE_OK) {
|
||||
/*
|
||||
* This case is uncommon, but can happen when:
|
||||
* -> if the first NAS message was a Detach Request (non exhaustiv), the UE RRC context exist
|
||||
* but is not associated with eNB_ue_s1ap_id
|
||||
* -> ... (?)
|
||||
*/
|
||||
LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", trying to find it through S1AP context\n",
|
||||
rrc_instance_pP - RC.rrc[0],
|
||||
eNB_ue_s1ap_id);
|
||||
|
||||
instance = ENB_MODULE_ID_TO_INSTANCE(rrc_instance_pP - RC.rrc[0]); // get eNB instance
|
||||
|
||||
s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); // get s1ap_eNB_instance
|
||||
|
||||
ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, eNB_ue_s1ap_id); // get s1ap_eNB_ue_context
|
||||
|
||||
if (ue_desc_p != NULL) {
|
||||
|
||||
result = rrc_eNB_S1AP_get_ue_ids(rrc_instance_pP, ue_desc_p->ue_initial_id, eNB_ue_s1ap_id);
|
||||
|
||||
ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ENB_INSTANCE_TO_MODULE_ID(instance)], result->ue_rnti);
|
||||
|
||||
if ((ue_context_p != NULL) && (ue_context_p->ue_context.eNB_ue_s1ap_id == 0)) {
|
||||
|
||||
ue_context_p->ue_context.eNB_ue_s1ap_id = eNB_ue_s1ap_id;
|
||||
|
||||
} else {
|
||||
|
||||
LOG_E(RRC, "[eNB %ld] Incoherence between RRC context and S1AP context (%d != %d) for UE RNTI %d or UE RRC context doesn't exist\n",
|
||||
rrc_instance_pP - RC.rrc[0],
|
||||
ue_context_p->ue_context.eNB_ue_s1ap_id,
|
||||
eNB_ue_s1ap_id,
|
||||
result->ue_rnti);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", even when looking at S1AP context\n",
|
||||
rrc_instance_pP - RC.rrc[0],
|
||||
eNB_ue_s1ap_id);
|
||||
|
||||
}
|
||||
|
||||
} // end if (h_rc != HASH_TABLE_OK)
|
||||
} // end if (eNB_ue_s1ap_id > 0)
|
||||
} // end else (ue_initial_id == UE_INITIAL_ID_INVALID)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* Remove UE ids (ue_initial_id and S1_id) from hashtables.
|
||||
*/
|
||||
void
|
||||
rrc_eNB_S1AP_remove_ue_ids(
|
||||
eNB_RRC_INST* const rrc_instance_pP,
|
||||
struct rrc_ue_s1ap_ids_s* const ue_ids_pP
|
||||
eNB_RRC_INST *const rrc_instance_pP,
|
||||
struct rrc_ue_s1ap_ids_s *const ue_ids_pP
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
const uint16_t ue_initial_id = ue_ids_pP->ue_initial_id;
|
||||
const uint32_t eNB_ue_s1ap_id = ue_ids_pP->eNB_ue_s1ap_id;
|
||||
|
||||
hashtable_rc_t h_rc;
|
||||
|
||||
if (rrc_instance_pP == NULL) {
|
||||
LOG_E(RRC, "Bad RRC instance\n");
|
||||
return;
|
||||
@@ -224,21 +330,23 @@ rrc_eNB_S1AP_remove_ue_ids(
|
||||
}
|
||||
|
||||
if (eNB_ue_s1ap_id > 0) {
|
||||
h_rc = hashtable_remove(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id);
|
||||
if (h_rc != HASH_TABLE_OK) {
|
||||
LOG_W(RRC, "S1AP Did not find entry in hashtable s1ap_id2_s1ap_ids for eNB_ue_s1ap_id %u\n", eNB_ue_s1ap_id);
|
||||
} else {
|
||||
LOG_W(RRC, "S1AP removed entry in hashtable s1ap_id2_s1ap_ids for eNB_ue_s1ap_id %u\n", eNB_ue_s1ap_id);
|
||||
}
|
||||
h_rc = hashtable_remove(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id);
|
||||
|
||||
if (h_rc != HASH_TABLE_OK) {
|
||||
LOG_W(RRC, "S1AP Did not find entry in hashtable s1ap_id2_s1ap_ids for eNB_ue_s1ap_id %u\n", eNB_ue_s1ap_id);
|
||||
} else {
|
||||
LOG_W(RRC, "S1AP removed entry in hashtable s1ap_id2_s1ap_ids for eNB_ue_s1ap_id %u\n", eNB_ue_s1ap_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (ue_initial_id != UE_INITIAL_ID_INVALID) {
|
||||
h_rc = hashtable_remove(rrc_instance_pP->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id);
|
||||
if (h_rc != HASH_TABLE_OK) {
|
||||
LOG_W(RRC, "S1AP Did not find entry in hashtable initial_id2_s1ap_ids for ue_initial_id %u\n", ue_initial_id);
|
||||
} else {
|
||||
LOG_W(RRC, "S1AP removed entry in hashtable initial_id2_s1ap_ids for ue_initial_id %u\n", ue_initial_id);
|
||||
}
|
||||
|
||||
if (h_rc != HASH_TABLE_OK) {
|
||||
LOG_W(RRC, "S1AP Did not find entry in hashtable initial_id2_s1ap_ids for ue_initial_id %u\n", ue_initial_id);
|
||||
} else {
|
||||
LOG_W(RRC, "S1AP removed entry in hashtable initial_id2_s1ap_ids for ue_initial_id %u\n", ue_initial_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,17 +392,11 @@ rrc_eNB_get_ue_context_from_s1ap_ids(
|
||||
)
|
||||
{
|
||||
rrc_ue_s1ap_ids_t* temp = NULL;
|
||||
temp =
|
||||
rrc_eNB_S1AP_get_ue_ids(
|
||||
RC.rrc[ENB_INSTANCE_TO_MODULE_ID(instanceP)],
|
||||
ue_initial_idP,
|
||||
eNB_ue_s1ap_idP);
|
||||
|
||||
if (temp) {
|
||||
temp = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ENB_INSTANCE_TO_MODULE_ID(instanceP)], ue_initial_idP, eNB_ue_s1ap_idP);
|
||||
|
||||
return rrc_eNB_get_ue_context(
|
||||
RC.rrc[ENB_INSTANCE_TO_MODULE_ID(instanceP)],
|
||||
temp->ue_rnti);
|
||||
if (temp != NULL) {
|
||||
return rrc_eNB_get_ue_context(RC.rrc[ENB_INSTANCE_TO_MODULE_ID(instanceP)], temp->ue_rnti);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -686,28 +788,31 @@ void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* Initial UE NAS message on S1AP.
|
||||
*/
|
||||
void
|
||||
rrc_eNB_send_S1AP_NAS_FIRST_REQ(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
rrc_eNB_ue_context_t* const ue_context_pP,
|
||||
rrc_eNB_ue_context_t* const ue_context_pP,
|
||||
LTE_RRCConnectionSetupComplete_r8_IEs_t* rrcConnectionSetupComplete
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
{
|
||||
eNB_RRC_INST *rrc=RC.rrc[ctxt_pP->module_id];
|
||||
eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id];
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
{
|
||||
MessageDef* message_p = NULL;
|
||||
rrc_ue_s1ap_ids_t* rrc_ue_s1ap_ids_p = NULL;
|
||||
hashtable_rc_t h_rc;
|
||||
|
||||
message_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_NAS_FIRST_REQ);
|
||||
message_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_NAS_FIRST_REQ);
|
||||
memset(&message_p->ittiMsg.s1ap_nas_first_req, 0, sizeof(s1ap_nas_first_req_t));
|
||||
|
||||
ue_context_pP->ue_context.ue_initial_id = get_next_ue_initial_id (ctxt_pP->module_id);
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_initial_id = ue_context_pP->ue_context.ue_initial_id;
|
||||
ue_context_pP->ue_context.ue_initial_id = get_next_ue_initial_id(ctxt_pP->module_id);
|
||||
|
||||
S1AP_NAS_FIRST_REQ(message_p).ue_initial_id = ue_context_pP->ue_context.ue_initial_id;
|
||||
|
||||
rrc_ue_s1ap_ids_p = malloc(sizeof(*rrc_ue_s1ap_ids_p));
|
||||
rrc_ue_s1ap_ids_p->ue_initial_id = ue_context_pP->ue_context.ue_initial_id;
|
||||
@@ -715,22 +820,26 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
|
||||
rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti;
|
||||
|
||||
h_rc = hashtable_insert(RC.rrc[ctxt_pP->module_id]->initial_id2_s1ap_ids,
|
||||
(hash_key_t)ue_context_pP->ue_context.ue_initial_id,
|
||||
rrc_ue_s1ap_ids_p);
|
||||
(hash_key_t)ue_context_pP->ue_context.ue_initial_id,
|
||||
rrc_ue_s1ap_ids_p);
|
||||
|
||||
if (h_rc != HASH_TABLE_OK) {
|
||||
LOG_E(S1AP, "[eNB %d] Error while hashtable_insert in initial_id2_s1ap_ids ue_initial_id %u\n",
|
||||
ctxt_pP->module_id, ue_context_pP->ue_context.ue_initial_id);
|
||||
ctxt_pP->module_id,
|
||||
ue_context_pP->ue_context.ue_initial_id);
|
||||
}
|
||||
|
||||
/* Assume that cause is coded in the same way in RRC and S1ap, just check that the value is in S1ap range */
|
||||
AssertFatal(ue_context_pP->ue_context.establishment_cause < RRC_CAUSE_LAST,
|
||||
"Establishment cause invalid (%jd/%d) for eNB %d!",
|
||||
ue_context_pP->ue_context.establishment_cause, RRC_CAUSE_LAST, ctxt_pP->module_id);
|
||||
"Establishment cause invalid (%jd/%d) for eNB %d!",
|
||||
ue_context_pP->ue_context.establishment_cause,
|
||||
RRC_CAUSE_LAST,
|
||||
ctxt_pP->module_id);
|
||||
|
||||
S1AP_NAS_FIRST_REQ (message_p).establishment_cause = ue_context_pP->ue_context.establishment_cause;
|
||||
|
||||
/* Forward NAS message */S1AP_NAS_FIRST_REQ (message_p).nas_pdu.buffer =
|
||||
rrcConnectionSetupComplete->dedicatedInfoNAS.buf;
|
||||
/* Forward NAS message */
|
||||
S1AP_NAS_FIRST_REQ (message_p).nas_pdu.buffer = rrcConnectionSetupComplete->dedicatedInfoNAS.buf;
|
||||
S1AP_NAS_FIRST_REQ (message_p).nas_pdu.length = rrcConnectionSetupComplete->dedicatedInfoNAS.size;
|
||||
|
||||
extract_imsi(S1AP_NAS_FIRST_REQ (message_p).nas_pdu.buffer,
|
||||
@@ -748,12 +857,13 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_s_tmsi;
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.mme_code = s_TMSI->mme_code;
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.m_tmsi = s_TMSI->m_tmsi;
|
||||
|
||||
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ with s_TMSI: MME code %u M-TMSI %u ue %x\n",
|
||||
ctxt_pP->module_id,
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.mme_code,
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.m_tmsi,
|
||||
ue_context_pP->ue_context.rnti);
|
||||
}
|
||||
} // end if S-TMSI presence
|
||||
|
||||
/* selected_plmn_identity: IE is 1-based, convert to 0-based (C array) */
|
||||
int selected_plmn_identity = rrcConnectionSetupComplete->selectedPLMN_Identity - 1;
|
||||
@@ -769,31 +879,33 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
|
||||
if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) {
|
||||
/* Use first indicated PLMN MCC if it is defined */
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[selected_plmn_identity];
|
||||
|
||||
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n",
|
||||
ctxt_pP->module_id,
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc,
|
||||
ue_context_pP->ue_context.rnti);
|
||||
ctxt_pP->module_id,
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc,
|
||||
ue_context_pP->ue_context.rnti);
|
||||
}
|
||||
|
||||
if (r_mme->plmn_Identity->mnc.list.count > 0) {
|
||||
/* Use first indicated PLMN MNC if it is defined */
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[selected_plmn_identity];
|
||||
|
||||
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n",
|
||||
ctxt_pP->module_id,
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc,
|
||||
ue_context_pP->ue_context.rnti);
|
||||
ctxt_pP->module_id,
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc,
|
||||
ue_context_pP->ue_context.rnti);
|
||||
}
|
||||
} else {
|
||||
|
||||
} else { // end if plmn_Identity != NULL
|
||||
S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mcc = rrc->configuration.mcc[selected_plmn_identity];
|
||||
S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mnc = rrc->configuration.mnc[selected_plmn_identity];
|
||||
S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mnc_len = rrc->configuration.mnc_digit_length[selected_plmn_identity];
|
||||
}
|
||||
} // end else (plmn_Identity == NULL)
|
||||
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code = BIT_STRING_to_uint8 (&r_mme->mmec);
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_group_id = BIT_STRING_to_uint16 (&r_mme->mmegi);
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_S1AP_ENB,
|
||||
MSC_LOG_TX_MESSAGE(MSC_S1AP_ENB,
|
||||
MSC_S1AP_MME,
|
||||
(const char *)&message_p->ittiMsg.s1ap_nas_first_req,
|
||||
sizeof(s1ap_nas_first_req_t),
|
||||
@@ -807,11 +919,15 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code,
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_group_id,
|
||||
ue_context_pP->ue_context.rnti);
|
||||
}
|
||||
}
|
||||
|
||||
} // end if MME info present
|
||||
} // end "Fill UE identities with available information" sub-part
|
||||
|
||||
itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, message_p);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
{
|
||||
s1ap_eNB_new_data_request (
|
||||
ctxt_pP->module_id,
|
||||
@@ -821,6 +937,7 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
|
||||
rrcConnectionSetupComplete->dedicatedInfoNAS.
|
||||
size);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -847,7 +964,6 @@ rrc_eNB_process_S1AP_DOWNLINK_NAS(
|
||||
eNB_ue_s1ap_id = S1AP_DOWNLINK_NAS (msg_p).eNB_ue_s1ap_id;
|
||||
ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id);
|
||||
|
||||
|
||||
LOG_I(RRC, "[eNB %d] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d\n",
|
||||
instance,
|
||||
msg_name,
|
||||
@@ -1172,95 +1288,98 @@ int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ (MessageDef *msg_p, const char *
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ (
|
||||
const module_id_t enb_mod_idP,
|
||||
const rrc_eNB_ue_context_t* const ue_context_pP,
|
||||
const s1ap_Cause_t causeP,
|
||||
const long cause_valueP
|
||||
)
|
||||
/*
|
||||
* Send the S1 command UE_CONTEXT_RELEASE_REQUEST to the MME.
|
||||
*/
|
||||
void
|
||||
rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(
|
||||
const module_id_t enb_mod_idP,
|
||||
const rrc_eNB_ue_context_t *const ue_context_pP,
|
||||
const s1ap_Cause_t causeP,
|
||||
const long cause_valueP)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
if (ue_context_pP == NULL) {
|
||||
LOG_W(RRC,
|
||||
"[eNB] In S1AP_UE_CONTEXT_RELEASE_COMMAND: invalid UE\n");
|
||||
LOG_E(RRC, "[eNB] In S1AP_UE_CONTEXT_RELEASE_REQ: invalid UE\n");
|
||||
} else {
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_RRC_ENB,
|
||||
MSC_S1AP_ENB,
|
||||
NULL,0,
|
||||
"0 S1AP_UE_CONTEXT_RELEASE_REQ eNB_ue_s1ap_id 0x%06"PRIX32" ",
|
||||
ue_context_pP->ue_context.eNB_ue_s1ap_id);
|
||||
MSC_LOG_TX_MESSAGE(MSC_RRC_ENB,
|
||||
MSC_S1AP_ENB,
|
||||
NULL,
|
||||
0,
|
||||
"0 S1AP_UE_CONTEXT_RELEASE_REQ eNB_ue_s1ap_id 0x%06"PRIX32" ",
|
||||
ue_context_pP->ue_context.eNB_ue_s1ap_id);
|
||||
|
||||
MessageDef *msg_context_release_req_p = NULL;
|
||||
msg_context_release_req_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_REQ);
|
||||
|
||||
S1AP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id;
|
||||
S1AP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause = causeP;
|
||||
S1AP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause_value = cause_valueP;
|
||||
|
||||
itti_send_msg_to_task(TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg_context_release_req_p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND (MessageDef *msg_p, const char *msg_name, instance_t instance)
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* Process the S1 command UE_CONTEXT_RELEASE_COMMAND, sent by MME.
|
||||
* The eNB should remove all e-rab, S1 context, and other context of the UE.
|
||||
*/
|
||||
int
|
||||
rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND(
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
instance_t instance)
|
||||
{
|
||||
uint32_t eNB_ue_s1ap_id;
|
||||
protocol_ctxt_t ctxt;
|
||||
//-----------------------------------------------------------------------------
|
||||
uint32_t eNB_ue_s1ap_id = 0;
|
||||
protocol_ctxt_t ctxt;
|
||||
struct rrc_eNB_ue_context_s *ue_context_p = NULL;
|
||||
struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
|
||||
struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
|
||||
|
||||
eNB_ue_s1ap_id = S1AP_UE_CONTEXT_RELEASE_COMMAND(msg_p).eNB_ue_s1ap_id;
|
||||
|
||||
|
||||
ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id);
|
||||
|
||||
ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id);
|
||||
|
||||
if (ue_context_p == NULL) {
|
||||
/* Can not associate this message to an UE index */
|
||||
MessageDef *msg_complete_p;
|
||||
MessageDef *msg_complete_p = NULL;
|
||||
|
||||
LOG_W(RRC,
|
||||
"[eNB %d] In S1AP_UE_CONTEXT_RELEASE_COMMAND: unknown UE from eNB_ue_s1ap_id (%d)\n",
|
||||
instance,
|
||||
eNB_ue_s1ap_id);
|
||||
LOG_W(RRC, "[eNB %d] In S1AP_UE_CONTEXT_RELEASE_COMMAND: unknown UE from eNB_ue_s1ap_id (%d)\n",
|
||||
instance,
|
||||
eNB_ue_s1ap_id);
|
||||
|
||||
MSC_LOG_EVENT(
|
||||
MSC_RRC_ENB,
|
||||
"0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" context not found",
|
||||
MSC_LOG_EVENT(MSC_RRC_ENB, "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" context not found",
|
||||
eNB_ue_s1ap_id);
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_RRC_ENB,
|
||||
MSC_S1AP_ENB,
|
||||
NULL,0,
|
||||
"0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ",
|
||||
MSC_LOG_TX_MESSAGE(MSC_RRC_ENB,
|
||||
MSC_S1AP_ENB,
|
||||
NULL,
|
||||
0,
|
||||
"0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ",
|
||||
eNB_ue_s1ap_id);
|
||||
|
||||
msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE);
|
||||
S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id;
|
||||
itti_send_msg_to_task(TASK_S1AP, instance, msg_complete_p);
|
||||
|
||||
rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(
|
||||
RC.rrc[instance],
|
||||
UE_INITIAL_ID_INVALID,
|
||||
eNB_ue_s1ap_id);
|
||||
rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id);
|
||||
|
||||
if (NULL != rrc_ue_s1ap_ids) {
|
||||
rrc_eNB_S1AP_remove_ue_ids(
|
||||
RC.rrc[instance],
|
||||
rrc_ue_s1ap_ids);
|
||||
if (rrc_ue_s1ap_ids != NULL) {
|
||||
rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids);
|
||||
}
|
||||
return (-1);
|
||||
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
ue_context_p->ue_context.ue_release_timer_s1 = 0;
|
||||
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
|
||||
|
||||
rrc_eNB_generate_RRCConnectionRelease(&ctxt, ue_context_p);
|
||||
/*
|
||||
LOG_W(RRC,
|
||||
"[eNB %d] In S1AP_UE_CONTEXT_RELEASE_COMMAND: TODO call rrc_eNB_connection_release for eNB %d\n",
|
||||
instance,
|
||||
eNB_ue_s1ap_id);
|
||||
*/
|
||||
return (0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -444,16 +444,22 @@ void *s1ap_eNB_task(void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* eNB generate a S1 setup request towards MME
|
||||
*/
|
||||
static int s1ap_eNB_generate_s1_setup_request(
|
||||
s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p)
|
||||
s1ap_eNB_instance_t *instance_p,
|
||||
s1ap_eNB_mme_data_t *s1ap_mme_data_p)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
S1AP_S1AP_PDU_t pdu;
|
||||
S1AP_S1SetupRequest_t *out;
|
||||
S1AP_S1SetupRequestIEs_t *ie;
|
||||
S1AP_SupportedTAs_Item_t *ta;
|
||||
S1AP_PLMNidentity_t *plmn;
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
S1AP_S1AP_PDU_t pdu;
|
||||
S1AP_S1SetupRequest_t *out = NULL;
|
||||
S1AP_S1SetupRequestIEs_t *ie = NULL;
|
||||
S1AP_SupportedTAs_Item_t *ta = NULL;
|
||||
S1AP_PLMNidentity_t *plmn = NULL;
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t len = 0;
|
||||
int ret = 0;
|
||||
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
@@ -863,11 +863,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
|
||||
"existing UE context 0x%06lx\n",
|
||||
assoc_id,
|
||||
enb_ue_s1ap_id);
|
||||
/*MessageDef *msg_complete_p;
|
||||
msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE);
|
||||
S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = enb_ue_s1ap_id;
|
||||
itti_send_msg_to_task(TASK_S1AP, ue_desc_p->eNB_instance->instance <=> 0, msg_complete_p);
|
||||
*/
|
||||
|
||||
return -1;
|
||||
} else {
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
@@ -877,6 +873,11 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
|
||||
"0 S1AP_UE_CONTEXT_RELEASE_COMMAND/%d eNB_ue_s1ap_id "S1AP_UE_ID_FMT" ",
|
||||
enb_ue_s1ap_id);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND);
|
||||
|
||||
if (ue_desc_p->mme_ue_s1ap_id == 0) { // case of Detach Request and switch off from RRC_IDLE mode
|
||||
ue_desc_p->mme_ue_s1ap_id = mme_ue_s1ap_id;
|
||||
}
|
||||
|
||||
S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id;
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
|
||||
return 0;
|
||||
|
||||
@@ -573,9 +573,6 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id,
|
||||
ie->value.choice.NAS_PDU.buf,
|
||||
ie->value.choice.NAS_PDU.size);
|
||||
|
||||
// LG: Why set to 0 ??
|
||||
//ue_desc_p->ue_initial_id = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user