Commit c66d3d14 authored by Anton Kozhemiachenko's avatar Anton Kozhemiachenko Committed by Jerome PERALDI

NR Paging support

parent 6e98229d
......@@ -130,11 +130,11 @@ extern "C" {
int message_id = message->ittiMsgHeader.messageId;
size_t s=t->message_queue.size();
if ( s > t->admin.queue_size )
LOG_E(TMR,"Queue for %s task contains %ld messages\n", itti_get_task_name(destination_task_id), s );
// if ( s > t->admin.queue_size )
// LOG_E(TMR,"Queue for %s task contains %ld messages\n", itti_get_task_name(destination_task_id), s );
if ( s > 50 )
LOG_I(ITTI,"Queue for %s task size: %ld (last message %s)\n",itti_get_task_name(destination_task_id), s+1,ITTI_MSG_NAME(message));
// if ( s > 50 )
// LOG_I(ITTI,"Queue for %s task size: %ld (last message %s)\n",itti_get_task_name(destination_task_id), s+1,ITTI_MSG_NAME(message));
t->message_queue.insert(t->message_queue.begin(), message);
eventfd_t sem_counter = 1;
......
......@@ -303,8 +303,8 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
if (slot_ind) {
frame_t frame = NFAPI_SFNSLOT2SFN(*slot_ind);
int slot = NFAPI_SFNSLOT2SLOT(*slot_ind);
LOG_A(NR_MAC, "The received sfn/slot [%d %d] from proxy\n",
frame, slot);
/* LOG_A(NR_MAC, "The received sfn/slot [%d %d] from proxy\n", */
/* frame, slot); */
sfn_slot = *slot_ind;
free_and_zero(slot_ind);
}
......
......@@ -73,6 +73,8 @@
#define S1AP_MAX_NB_MME_IP_ADDRESS 10
#define S1AP_IMSI_LENGTH 16
#define NG_5G_S_TMSI_LENGTH 48
#define I_RNTI_VALUE_LENGTH 40
/* Security key length used within eNB
* Even if only 16 bytes will be effectively used,
......@@ -111,6 +113,10 @@ typedef enum cn_domain_s {
CN_DOMAIN_CS = 2
} cn_domain_t;
typedef enum access_type_s {
ACCESS_TYPE_NON3GPP = 1
} access_type_t;
typedef struct net_ip_address_s {
unsigned ipv4:1;
unsigned ipv6:1;
......@@ -221,6 +227,30 @@ typedef struct ue_identity_s {
s1ap_gummei_t gummei;
} ue_identity_t;
typedef enum nr_ue_paging_identity_presenceMask_e {
NR_UE_PAGING_IDENTITY_NONE = 0,
NR_UE_PAGING_IDENTITY_NG_5G_S_TMSI = (1 << 1),
NR_UE_PAGING_IDENTITY_FULL_I_RNTI = (1 << 2),
} nr_ue_paging_identity_presenceMask_t;
typedef struct ng_5g_s_tmsi_s {
uint8_t buffer[NG_5G_S_TMSI_LENGTH];
uint8_t length;
} ng_5g_s_tmsi_t;
typedef struct i_rnti_value_s {
uint8_t buffer[I_RNTI_VALUE_LENGTH];
uint8_t length;
} i_rnti_value_t;
typedef struct nr_ue_paging_identity_s {
nr_ue_paging_identity_presenceMask_t presenceMask;
union {
ng_5g_s_tmsi_t ng_5g_s_tmsi;
i_rnti_value_t full_i_rnti;
} choice;
} nr_ue_paging_identity_t;
typedef struct nas_pdu_s {
/* Octet string data */
uint8_t *buffer;
......
......@@ -43,6 +43,7 @@ MESSAGE_DEF(SS_VNG_PROXY_REQ, MESSAGE_PRIORITY_MED, ss_vng_proxy
MESSAGE_DEF(SS_VNG_PROXY_RESP, MESSAGE_PRIORITY_MED, ss_vng_proxy_resp_t , ss_vng_proxy_resp)
MESSAGE_DEF(SS_SS_PAGING_IND, MESSAGE_PRIORITY_MED, ss_paging_ind_t , ss_paging_ind)
MESSAGE_DEF(SS_SS_NR_PAGING_IND, MESSAGE_PRIORITY_MED, ss_nr_paging_ind_t , ss_nr_paging_ind)
MESSAGE_DEF(SS_NRRRC_PDU_REQ, MESSAGE_PRIORITY_MED, ss_nrrrc_pdu_req_t , ss_nrrrc_pdu_req)
MESSAGE_DEF(SS_NRRRC_PDU_IND, MESSAGE_PRIORITY_MED, ss_nrrrc_pdu_ind_t , ss_nrrrc_pdu_ind)
......
......@@ -47,6 +47,7 @@
#define SS_NRRRC_PDU_IND(mSGpTR) (mSGpTR)->ittiMsg.ss_nrrrc_pdu_ind
#define SS_SYS_PROXY_MSG_CNF(mSGpTR) (mSGpTR)->ittiMsg.udp_data_ind
#define SS_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.ss_paging_ind
#define SS_NR_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.ss_nr_paging_ind
#define SS_L1MACIND_CTRL(mSGpTR) (mSGpTR)->ittiMsg.ss_l1macind_ctrl
/** VNG */
......@@ -291,11 +292,23 @@ typedef struct ss_paging_identity_s {
cn_domain_t cn_domain;
}ss_paging_identity_t;
typedef struct ss_nr_paging_identity_s {
nr_ue_paging_identity_t ue_paging_identity;
bool bAccessTypePresent;
access_type_t access_type;
}ss_nr_paging_identity_t;
typedef struct subframe_offset_list_s {
uint16_t num;
sub_frame_t subframe_offset[1000];
}subframe_offset_list_t;
typedef struct slot_offset_list_s {
uint16_t num;
slot_t slot_offset[1000];
}slot_offset_list_t;
typedef struct ss_paging_ind_s {
uint16_t sfn;
uint8_t sf;
......@@ -313,6 +326,19 @@ typedef struct ss_paging_ind_s {
subframe_offset_list_t subframeOffsetList;
} ss_paging_ind_t;
typedef struct ss_nr_paging_ind_s {
uint16_t sfn;
uint32_t slot;
int cell_index;
unsigned ue_index_value:10;
uint8_t num_paging_record;
ss_nr_paging_identity_t *paging_recordList;
bool bSlotOffsetListPresent;
slot_offset_list_t slotOffsetList;
} ss_nr_paging_ind_t;
typedef enum VtpCmd_e {
VTP_DISABLE = 0,
VTP_ENABLE = 1
......
......@@ -232,9 +232,12 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
// This schedules the DCI for Downlink and PDSCH
start_meas(&gNB->schedule_dlsch);
nr_schedule_ue_spec(module_idP, frame, slot);
nr_schedule_ue_spec(module_idP, frame, slot);
stop_meas(&gNB->schedule_dlsch);
// This schedules Paging in slot
schedule_nr_PCH(module_idP, frame, slot);
nr_sr_reporting(RC.nrmac[module_idP], frame, slot);
nr_schedule_pucch(RC.nrmac[module_idP], frame, slot);
......
......@@ -109,6 +109,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot);
/* \brief default FR1 UL preprocessor init routine, returns preprocessor to call */
nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(module_id_t module_id, int CC_id);
void schedule_nr_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
/////// Random Access MAC-PHY interface functions and primitives ///////
void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
......
......@@ -973,6 +973,15 @@ void pdcp_run(const protocol_ctxt_t *const ctxt_pP)
result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), NR_DTCH_DATA_REQ(msg_p).sdu_p);
AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
break;
case RRC_PCCH_DATA_REQ:
LOG_D(PDCP, "PDCP Received RRC_PCCH_DATA_REQ CC_id %d length %d \n", RRC_PCCH_DATA_REQ(msg_p).CC_id, RRC_PCCH_DATA_REQ(msg_p).sdu_size);
LOG_E(PDCP, ">>> BLABLABLA PDCP Received RRC_PCCH_DATA_REQ CC_id %d length %d \n", RRC_PCCH_DATA_REQ(msg_p).CC_id, RRC_PCCH_DATA_REQ(msg_p).sdu_size); //TODO:BLA
RC.nrrrc[ctxt_pP->module_id]->carrier.sizeof_paging = RRC_PCCH_DATA_REQ(msg_p).sdu_size;
memcpy(RC.nrrrc[ctxt_pP->module_id]->carrier.paging, RRC_PCCH_DATA_REQ(msg_p).sdu_p, RRC_PCCH_DATA_REQ(msg_p).sdu_size);
result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), RRC_PCCH_DATA_REQ(msg_p).sdu_p);
AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
break;
default:
LOG_E(PDCP, "Received unexpected message %s\n", ITTI_MSG_NAME(msg_p));
break;
......
......@@ -405,6 +405,7 @@ static void copy_dl_tti_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_
{
LOG_D(NR_PHY, "[%d, %d] PDSCH PDU for rnti %x\n",
dl_tti_request->SFN, dl_tti_request->Slot, pdu_list->pdsch_pdu.pdsch_pdu_rel15.rnti);
LOG_E(NR_PHY, ">>> BLABLABLA [%d, %d] PDSCH PDU for rnti %x\n", dl_tti_request->SFN, dl_tti_request->Slot, pdu_list->pdsch_pdu.pdsch_pdu_rel15.rnti); //TODO:BLA
}
if (pdu_list->PDUType == NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE)
......@@ -736,6 +737,7 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
frame = dl_tti_request->SFN;
slot = dl_tti_request->Slot;
LOG_D(NR_PHY, "[%d, %d] dl_tti_request\n", frame, slot);
LOG_E(NR_PHY, ">>>> BLABLA [%d, %d] dl_tti_request\n", frame, slot); //TODO:BLA
copy_dl_tti_req_to_dl_info(&mac->dl_info, dl_tti_request);
free_and_zero(dl_tti_request);
}
......@@ -751,6 +753,7 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
frame = tx_data_request->SFN;
slot = tx_data_request->Slot;
LOG_D(NR_PHY, "[%d, %d] PDSCH in tx_request\n", frame, slot);
LOG_E(NR_PHY, ">>> BLABLABLA [%d, %d] PDSCH in tx_request\n", frame, slot); //TODO:BLA
copy_tx_data_req_to_dl_info(&mac->dl_info, tx_data_request);
}
else {
......@@ -774,6 +777,7 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
else {
if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort();
LOG_T(NR_MAC, "All indications were NULL in %s\n", __FUNCTION__);
LOG_E(NR_MAC, ">>> BLABLA All indications were NULL in %s\n", __FUNCTION__); //TODO:BLA
return;
}
......@@ -884,6 +888,7 @@ static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_hea
}
LOG_D(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST message in SFN/slot %d %d. \n",
tx_data_request->SFN, tx_data_request->Slot);
LOG_E(NR_PHY, ">>> BLABLA Received an NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST message in SFN/slot %d %d. \n", tx_data_request->SFN, tx_data_request->Slot); //TODO:BLA
if (!put_queue(&nr_tx_req_queue, tx_data_request))
{
LOG_E(NR_PHY, "put_queue failed for tx_request.\n");
......@@ -1016,6 +1021,7 @@ void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request)
count_sent++;
LOG_T(NR_MAC, "pdsch_pdu->rnti %x mac->crnti %x mac->ra.ra_state %d count_sent %d\n",
pdsch_pdu->rnti, mac->crnti, mac->ra.ra_state, count_sent);
LOG_E(NR_MAC, ">>>> BLABLABLA pdsch_pdu->rnti %x mac->crnti %x mac->ra.ra_state %d count_sent %d\n", pdsch_pdu->rnti, mac->crnti, mac->ra.ra_state, count_sent); //TODO:BLA
}
}
}
......@@ -1283,6 +1289,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
__FUNCTION__,
dl_info->rx_ind->rx_indication_body[i].pdu_type,
dl_info->rx_ind->number_pdus);
LOG_E(NR_MAC, ">>BLABLABLA In %s sending DL indication to MAC. 1 PDU type %d of %d total number of PDUs \n", __FUNCTION__, dl_info->rx_ind->rx_indication_body[i].pdu_type, dl_info->rx_ind->number_pdus); //TODO:BLA
switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){
case FAPI_NR_RX_PDU_TYPE_SSB:
......
......@@ -115,6 +115,7 @@ uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
const uint8_t Nb_tb,
uint8_t *const buffer_pP)
{
uint8_t Sdu_size = 0;
#ifdef DEBUG_RRC
LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id);
......@@ -160,6 +161,22 @@ uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
AssertFatal(0, "CCCH is managed by rlc of srb 0, not anymore by mac_rrc_nr_data_req\n");
}
// PCCH
if ((Srb_id & RAB_OFFSET) == PCCH) {
LOG_T(NR_RRC, "[eNB %d] Frame %d PCCH request (Srb_id %ld)\n", Mod_idP, frameP, Srb_id);
LOG_E(NR_RRC, ">>> BLABLABLA [eNB %d] Frame %d PCCH request (Srb_id %ld)\n", Mod_idP, frameP, Srb_id); //TODO:BLA
if (RC.nrrrc[Mod_idP]->carrier.sizeof_paging > 0) {
LOG_D(NR_RRC, "[eNB %d] PCCH has %d bytes\n", Mod_idP, RC.nrrrc[Mod_idP]->carrier.sizeof_paging);
LOG_E(NR_RRC, ">>>> BLABLABLA [eNB %d] PCCH has %d bytes\n", Mod_idP, RC.nrrrc[Mod_idP]->carrier.sizeof_paging); //TODO:BLA
memcpy(buffer_pP, RC.nrrrc[Mod_idP]->carrier.paging, RC.nrrrc[Mod_idP]->carrier.sizeof_paging);
Sdu_size = RC.nrrrc[Mod_idP]->carrier.sizeof_paging;
RC.nrrrc[Mod_idP]->carrier.sizeof_paging = 0;
}
return (Sdu_size);
}
return 0;
}
......
......@@ -2491,41 +2491,74 @@ NR_MeasConfig_t *get_defaultMeasConfig(const gNB_RrcConfigurationReq *conf)
return mc;
}
uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi) {
uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t *tmsi, size_t num_paging_record, ss_nr_paging_identity_t *paging_recordList) {
LOG_D(NR_RRC, "[gNB %d] do_NR_Paging start\n", Mod_id);
LOG_E(NR_RRC, ">>> BLABLA [gNB %d] do_NR_Paging start\n", Mod_id); //TODO:BLA
NR_PCCH_Message_t pcch_msg;
pcch_msg.message.present = NR_PCCH_MessageType_PR_c1;
memset((void *)&pcch_msg, 0, sizeof(NR_PCCH_Message_t));
pcch_msg.message.present = NR_PCCH_MessageType_PR_c1;
asn1cCalloc(pcch_msg.message.choice.c1, c1);
c1->present = NR_PCCH_MessageType__c1_PR_paging;
c1->choice.paging = CALLOC(1, sizeof(NR_Paging_t));
c1->choice.paging->pagingRecordList = CALLOC(
1, sizeof(*pcch_msg.message.choice.c1->choice.paging->pagingRecordList));
c1->choice.paging->pagingRecordList = CALLOC(1, sizeof(*pcch_msg.message.choice.c1->choice.paging->pagingRecordList));
c1->choice.paging->nonCriticalExtension = NULL;
asn_set_empty(&c1->choice.paging->pagingRecordList->list);
c1->choice.paging->pagingRecordList->list.count = 0;
asn1cSequenceAdd(c1->choice.paging->pagingRecordList->list, NR_PagingRecord_t,
paging_record_p);
/* convert ue_paging_identity_t to PagingUE_Identity_t */
paging_record_p->ue_Identity.present = NR_PagingUE_Identity_PR_ng_5G_S_TMSI;
// set ng_5G_S_TMSI
INT32_TO_BIT_STRING(tmsi, &paging_record_p->ue_Identity.choice.ng_5G_S_TMSI);
if (num_paging_record) {
DevAssert(paging_recordList != NULL);
for (size_t i = 0; i < num_paging_record; i++) {
asn1cSequenceAdd(c1->choice.paging->pagingRecordList->list, NR_PagingRecord_t, paging_record_p);
if (paging_recordList[i].ue_paging_identity.presenceMask == NR_UE_PAGING_IDENTITY_NG_5G_S_TMSI) {
paging_record_p->ue_Identity.present = NR_PagingUE_Identity_PR_ng_5G_S_TMSI;
paging_record_p->ue_Identity.choice.ng_5G_S_TMSI.size = (paging_recordList[i].ue_paging_identity.choice.ng_5g_s_tmsi.length + 7) / 8;
paging_record_p->ue_Identity.choice.ng_5G_S_TMSI.bits_unused = 0;
paging_record_p->ue_Identity.choice.ng_5G_S_TMSI.buf = CALLOC(1, paging_record_p->ue_Identity.choice.ng_5G_S_TMSI.size);
OCTET_STRING_TO_BIT_STRING((char *)paging_record_p->ue_Identity.choice.ng_5G_S_TMSI.buf, (char *)paging_recordList[i].ue_paging_identity.choice.ng_5g_s_tmsi.buffer, paging_recordList[i].ue_paging_identity.choice.ng_5g_s_tmsi.length);
} else if (paging_recordList[i].ue_paging_identity.presenceMask == NR_UE_PAGING_IDENTITY_FULL_I_RNTI) {
paging_record_p->ue_Identity.present = NR_PagingUE_Identity_PR_fullI_RNTI;
paging_record_p->ue_Identity.choice.fullI_RNTI.size = (paging_recordList[i].ue_paging_identity.choice.full_i_rnti.length + 7) / 8;
paging_record_p->ue_Identity.choice.fullI_RNTI.bits_unused = 0;
paging_record_p->ue_Identity.choice.fullI_RNTI.buf = CALLOC(1, paging_record_p->ue_Identity.choice.fullI_RNTI.size);
OCTET_STRING_TO_BIT_STRING((char *)paging_record_p->ue_Identity.choice.fullI_RNTI.buf, (char *)paging_recordList[i].ue_paging_identity.choice.full_i_rnti.buffer, paging_recordList[i].ue_paging_identity.choice.full_i_rnti.length);
} else {
LOG_E(NR_RRC, "[gNB %d] in do_NR_Paging: invalid ue_paging_identity.presenceMask\n", Mod_id);
abort();
}
if (paging_recordList[i].bAccessTypePresent) {
paging_record_p->accessType = CALLOC(1, sizeof(*paging_record_p->accessType));
*paging_record_p->accessType = paging_recordList[i].access_type;
} else {
paging_record_p->accessType = NULL;
}
}
} else {
DevAssert(tmsi != NULL);
asn1cSequenceAdd(c1->choice.paging->pagingRecordList->list, NR_PagingRecord_t, paging_record_p);
/* convert ue_paging_identity_t to PagingUE_Identity_t */
paging_record_p->ue_Identity.present = NR_PagingUE_Identity_PR_ng_5G_S_TMSI;
// set ng_5G_S_TMSI
INT32_TO_BIT_STRING(*tmsi, &paging_record_p->ue_Identity.choice.ng_5G_S_TMSI);
}
/* add to list */
LOG_D(NR_RRC, "[gNB %d] do_Paging paging_record: PagingRecordList.count %d\n",
Mod_id, c1->choice.paging->pagingRecordList->list.count);
asn_enc_rval_t enc_rval = uper_encode_to_buffer(
&asn_DEF_NR_PCCH_Message, NULL, (void *)&pcch_msg, buffer, RRC_BUF_SIZE);
LOG_D(NR_RRC, "[gNB %d] do_NR_Paging paging_record: PagingRecordList.count %d\n", Mod_id, c1->choice.paging->pagingRecordList->list.count);
LOG_E(NR_RRC, ">>> BLABLABLA [gNB %d] do_NR_Paging paging_record: PagingRecordList.count %d\n", Mod_id, c1->choice.paging->pagingRecordList->list.count); //TODO:BLA
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_PCCH_Message, NULL, (void *)&pcch_msg, buffer, RRC_BUF_SIZE);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
if (enc_rval.encoded != -1) {
xer_fprint(stdout, &asn_DEF_NR_PCCH_Message, (void *)&pcch_msg);
}
}
xer_fprint(stdout, &asn_DEF_NR_PCCH_Message, (void *)&pcch_msg); fflush(stdout); //TODO:BLA
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_PCCH_Message, &pcch_msg);
if(enc_rval.encoded == -1) {
LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
if (enc_rval.encoded == -1) {
LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
return -1;
}
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_PCCH_Message, (void *)&pcch_msg);
}
return((enc_rval.encoded+7)/8);
}
......@@ -198,4 +198,7 @@ do_RRCReestablishmentComplete(
uint8_t *buffer, size_t buffer_size,
int64_t rrc_TransactionIdentifier);
uint8_t
do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t *tmsi, size_t num_paging_record, ss_nr_paging_identity_t *paging_recordList);
#endif /* __RRC_NR_MESSAGES_ASN1_MSG__H__ */
......@@ -519,6 +519,8 @@ typedef struct {
NR_SRB_INFO Srb0;
int p_gNB;
uint8_t *paging;
uint32_t sizeof_paging;
} rrc_gNB_carrier_data_t;
//---------------------------------------------------
......
......@@ -230,6 +230,7 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu
LOG_I(NR_RRC,
PROTOCOL_NR_RRC_CTXT_FMT" Init...\n",
PROTOCOL_NR_RRC_CTXT_ARGS(&ctxt));
LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" >>> BLABLABLA Init...\n", PROTOCOL_NR_RRC_CTXT_ARGS(&ctxt)); //TODO:BLA
AssertFatal(rrc != NULL, "RC.nrrrc not initialized!");
AssertFatal(NUMBER_OF_UE_MAX < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow");
......@@ -258,6 +259,9 @@ if(!rrc->cell_info_configured) {
if(init_config_flag){
rrc_init_nr_global_param();
openair_nr_rrc_on(&ctxt);
rrc->carrier.sizeof_paging = 0;
rrc->carrier.paging = (uint8_t *) malloc16(256);
}
return 0;
}//END openair_rrc_gNB_configuration
......@@ -378,6 +382,166 @@ void apply_macrlc_config(gNB_RRC_INST *rrc,
}
int rrc_gNB_process_SS_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance_t instance)
{
const unsigned int Ttab[4] = {32,64,128,256};
uint8_t Tc;
/* uint8_t Tue; */
uint32_t pfoffset;
uint32_t N; /* N: min(T,nB). total count of PF in one DRX cycle */
uint32_t Ns = 0; /* Ns: max(1,nB/T) */
uint8_t i_s; /* i_s = floor(UE_ID/N) mod Ns */
uint32_t T; /* DRX cycle */
uint8_t CC_id = SS_NR_PAGING_IND(msg_p).cell_index;
frame_type_t frame_type = RC.gNB[instance]->frame_parms.frame_type;
uint32_t length;
uint8_t buffer[RRC_BUF_SIZE];
uint8_t *message_buffer;
MessageDef *message_p;
struct NR_SIB1 *sib1 = RC.nrrrc[instance]->carrier.siblock1->message.choice.c1->choice.systemInformationBlockType1;
// TODO: set configuration from TTCN SYS message
/* get default DRX cycle from configuration */
Tc = sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.defaultPagingCycle;
/* set T = min(Tc,Tue) */
T = Ttab[Tc];
/* set N = PCCH-Config->nAndPagingFrameOffset */
switch (sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.present) {
case NR_PCCH_Config__nAndPagingFrameOffset_PR_oneT:
N = T;
pfoffset = 0;
break;
case NR_PCCH_Config__nAndPagingFrameOffset_PR_halfT:
N = T/2;
pfoffset = 1;
break;
case NR_PCCH_Config__nAndPagingFrameOffset_PR_quarterT:
N = T/4;
pfoffset = 3;
break;
case NR_PCCH_Config__nAndPagingFrameOffset_PR_oneEighthT:
N = T/8;
pfoffset = 7;
break;
case NR_PCCH_Config__nAndPagingFrameOffset_PR_oneSixteenthT:
N = T/16;
pfoffset = 15;
break;
default:
LOG_E(NR_RRC, "[gNB %ld] In rrc_gNB_process_SS_PAGING_IND: pfoffset error (pfoffset %d)\n",
instance, sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.present);
return (-1);
}
switch (sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.ns) {
case NR_PCCH_Config__ns_four:
if(*sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->pagingSearchSpace == 0){
LOG_E(NR_RRC, "[gNB %ld] In rrc_gNB_process_SS_PAGING_IND: ns error only 1 or 2 is allowed when pagingSearchSpace is 0\n",
instance);
return (-1);
} else {
Ns = 4;
}
break;
case NR_PCCH_Config__ns_two:
Ns = 2;
break;
case NR_PCCH_Config__ns_one:
Ns = 1;
break;
default:
LOG_E(NR_RRC, "[gNB %ld] In rrc_gNB_process_SS_PAGING_IND: ns error (ns %ld)\n",
instance, sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.ns);
return (-1);
}
/* insert data to UE_PF_PO or update data in UE_PF_PO */
pthread_mutex_lock(&ue_pf_po_mutex);
uint8_t i = 0;
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
if ((UE_PF_PO[CC_id][i].enable_flag == true && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(SS_NR_PAGING_IND(msg_p).ue_index_value)) || (UE_PF_PO[CC_id][i].enable_flag != true)) {
/* set T = min(Tc,Tue) */
UE_PF_PO[CC_id][i].T = T;
/* set UE_ID */
UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)SS_NR_PAGING_IND(msg_p).ue_index_value;
/* calculate PF and PO */
/* set PF_min and PF_offset: (SFN + PF_offset) mod T = (T div N)*(UE_ID mod N) */
/* UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N); */
UE_PF_PO[CC_id][i].PF_min = (SS_NR_PAGING_IND(msg_p).sfn % T) + (UE_PF_PO[CC_id][i].ue_index_value % N);
/* UE_PF_PO[CC_id][i].PF_min = SS_NR_PAGING_IND(msg_p).sfn % T; */
UE_PF_PO[CC_id][i].PF_offset = pfoffset;
/* set i_s */
/* i_s = floor(UE_ID/N) mod Ns */
i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns);
UE_PF_PO[CC_id][i].i_s = i_s;
if (Ns == 1)
{
UE_PF_PO[CC_id][i].PO = (frame_type == FDD) ? 9 : 0;
}
else if (Ns == 2)
{
UE_PF_PO[CC_id][i].PO = (frame_type == FDD) ? (4 + (5 * i_s)) : (5 * i_s);
}
else if (Ns == 4)
{
UE_PF_PO[CC_id][i].PO = (frame_type == FDD) ? (4 * (i_s & 1) + (5 * (i_s >> 1))) : ((i_s & 1) + (5 * (i_s >> 1)));
}
/* UE_PF_PO[CC_id][i].PO = SS_NR_PAGING_IND(msg_p).slot; */
if (UE_PF_PO[CC_id][i].enable_flag == true) {
//paging exist UE log
LOG_D(NR_RRC,"[gNB %ld] CC_id %d In rrc_gNB_process_SS_PAGING_IND: Update exist UE %d, T %d, N %d, PF %d, i_s %d, PF_offset %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value,
T, N, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].i_s, UE_PF_PO[CC_id][i].PF_offset);
} else {
/* set enable_flag */
UE_PF_PO[CC_id][i].enable_flag = true;
//paging new UE log
LOG_D(NR_RRC,"[gNB %ld] CC_id %d In rrc_gNB_process_SS_PAGING_IND: Insert a new UE %d, T %d, N %d, PF %d, i_s %d, PF_offset %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value,
T, N, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].i_s, UE_PF_PO[CC_id][i].PF_offset);
}
break;
}
}
pthread_mutex_unlock(&ue_pf_po_mutex);
LOG_E(NR_RRC, ">>> BLABLA: rrc_gNB_process_SS_PAGING_IND Tc=%d T=%d N=%d poffset=%d Ns=%d, instance=%d CC_id=%d frame_type=%d\n", Tc, T, N, pfoffset, Ns, (int)instance, CC_id, frame_type); //TODO:BLA
LOG_E(NR_RRC, ">>> BLABLA: rrc_gNB_process_SS_PAGING_IND ue_index_value=%d T=%d PF_min=%d PF_offset=%d i_s=%d PO=%d enable_flag=%d\n", UE_PF_PO[CC_id][i].ue_index_value, UE_PF_PO[CC_id][i].T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PF_offset, UE_PF_PO[CC_id][i].i_s, UE_PF_PO[CC_id][i].PO, UE_PF_PO[CC_id][i].enable_flag); //TODO:BLA
/* Create message for PDCP (DLInformationTransfer_t) */
length = do_NR_Paging(instance, buffer, NULL, SS_NR_PAGING_IND(msg_p).num_paging_record, SS_NR_PAGING_IND(msg_p).paging_recordList);
if (SS_NR_PAGING_IND(msg_p).paging_recordList) {
free(SS_NR_PAGING_IND(msg_p).paging_recordList);
SS_NR_PAGING_IND(msg_p).paging_recordList = NULL;
}
if (length == -1) {
LOG_I(NR_RRC, "do_NR_Paging error\n");
return -1;
}
message_p = itti_alloc_new_message(TASK_RRC_GNB, instance, RRC_PCCH_DATA_REQ);
message_buffer = itti_malloc(TASK_RRC_GNB, TASK_PDCP_ENB, length);
/* Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). */
memcpy(message_buffer, buffer, length);
RRC_PCCH_DATA_REQ(message_p).sdu_size = length;
RRC_PCCH_DATA_REQ(message_p).sdu_p = message_buffer;
RRC_PCCH_DATA_REQ(message_p).mode = PDCP_TRANSMISSION_MODE_TRANSPARENT; /* not used */
RRC_PCCH_DATA_REQ(message_p).rnti = P_RNTI;
RRC_PCCH_DATA_REQ(message_p).ue_index = 0;
RRC_PCCH_DATA_REQ(message_p).CC_id = CC_id;
LOG_A(NR_RRC, "[gNB %ld] CC_id %d In do_NR_Paging: send encoded buffer to PDCP buffer_size %d\n", instance, CC_id, length);
LOG_E(NR_RRC, ">>> BLABLABLA [gNB %ld] CC_id %d In do_NR_Paging: send encoded buffer to PDCP buffer_size %d\n", instance, CC_id, length); //TODO:BLA
itti_send_msg_to_task(TASK_PDCP_ENB, instance, message_p);
return 0;
}
//-----------------------------------------------------------------------------
void
rrc_gNB_generate_RRCSetup(
......@@ -4275,6 +4439,12 @@ void *rrc_gnb_task(void *args_p) {
rrc_gNB_process_PAGING_IND(msg_p, msg_name_p, instance);
break;
case SS_SS_NR_PAGING_IND:
LOG_A(NR_RRC, "Received Paging message from SS: %s\n", msg_name_p);
LOG_E(NR_RRC, ">> BLABLABLA Received Paging message from SS: %s\n", msg_name_p); //TODO:BLA
rrc_gNB_process_SS_PAGING_IND(msg_p, msg_name_p, instance);
break;
case SS_NRRRC_PDU_REQ:
LOG_A(NR_RRC,"NR RRC received SS_NRRRC_PDU_REQ SRB_ID:%d SDU_SIZE:%d\n", SS_NRRRC_PDU_REQ (msg_p).srb_id, SS_NRRRC_PDU_REQ (msg_p).sdu_size);
......@@ -4718,12 +4888,10 @@ int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t inst
pthread_mutex_unlock(&ue_pf_po_mutex);
/* Create message for PDCP (DLInformationTransfer_t) */
length = do_NR_Paging (instance,
buffer,
tmsi);
length = do_NR_Paging(instance, buffer, &tmsi, 0, NULL);
if (length == -1) {
LOG_I(NR_RRC, "do_Paging error\n");
LOG_I(NR_RRC, "do_NR_Paging error\n");
return -1;
}
// TODO, send message to pdcp
......
......@@ -109,6 +109,7 @@ nr_mac_rrc_data_ind_ue(
break;
default:
LOG_E(NR_RRC, "^^^^ BLABLABLA invalid CHANNEL %x rnti %x pdu_len=%d!!!!!", channel, rnti, pdu_len); //TODO:BLA
break;
}
......
......@@ -2283,6 +2283,7 @@ nr_rrc_ue_establish_srb2(
}
itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p);
break; //TODO: BLA
/* simulate power OFF, to be able to send RRCSetupRequest to TTCN again */
LOG_W(NR_RRC, "todo, sleep before removing UE\n");
......
......@@ -53,6 +53,8 @@ static int sys_send_udp_msg(uint8_t *buffer, uint32_t buffer_len, uint32_t buffe
char *local_5G_address = "127.0.0.1" ;
extern softmodem_params_t *get_softmodem_params(void);
static uint16_t paging_ue_index_g = 0;
typedef enum
{
UndefinedMsg = 0,
......@@ -247,6 +249,122 @@ static void sys_handle_nr_cell_attn_req(struct NR_CellAttenuationConfig_Type_NR_
}
}
/*
* Function : sys_handle_nr_paging_req
* Description: Handles the attenuation updates received from TTCN
*/
static void sys_handle_nr_paging_req(struct NR_PagingTrigger_Type *pagingRequest, ss_nrset_timinfo_t tinfo)
{
LOG_A(GNB_APP, "[SYS-GNB] Enter sys_handle_nr_paging_req Paging_IND for processing\n");
/** TODO: Considering only one cell for now */
uint8_t cellId = 0; //(uint8_t)pagingRequst->CellId;
static uint8_t oneTimeProcessingFlag = 0;
MessageDef *message_p = itti_alloc_new_message(TASK_SYS_GNB, 0, SS_SS_NR_PAGING_IND);
if (message_p == NULL)
{
return;
}
SS_NR_PAGING_IND(message_p).cell_index = 0; // TODO: change to multicell index later
SS_NR_PAGING_IND(message_p).sfn = tinfo.sfn;
SS_NR_PAGING_IND(message_p).slot = tinfo.slot;
SS_NR_PAGING_IND(message_p).paging_recordList = NULL;
SS_NR_PAGING_IND(message_p).bSlotOffsetListPresent = false;
switch (pagingRequest->Paging.message.d)
{
case SQN_NR_PCCH_MessageType_c1:
if (pagingRequest->Paging.message.v.c1.d)
{
if (pagingRequest->Paging.message.v.c1.v.paging.pagingRecordList.d)
{
struct SQN_NR_PagingRecord *p_sdl_msg = NULL;
p_sdl_msg = pagingRequest->Paging.message.v.c1.v.paging.pagingRecordList.v.v;
uint8_t numPagingRecord = pagingRequest->Paging.message.v.c1.v.paging.pagingRecordList.v.d;
size_t pgSize = pagingRequest->Paging.message.v.c1.v.paging.pagingRecordList.v.d * sizeof(ss_nr_paging_identity_t);
SS_NR_PAGING_IND(message_p).paging_recordList = CALLOC(1, pgSize);
ss_nr_paging_identity_t *p_record_msg = SS_NR_PAGING_IND(message_p).paging_recordList;
SS_NR_PAGING_IND(message_p).num_paging_record = numPagingRecord;
for (int count = 0; count < numPagingRecord; count++)
{
p_record_msg->bAccessTypePresent = false;
if (p_sdl_msg->accessType.d)
{
if (p_sdl_msg->accessType.v == SQN_NR_PagingRecord_accessType_e_non3GPP)
{
p_record_msg->bAccessTypePresent = true;
p_record_msg->access_type = ACCESS_TYPE_NON3GPP;
}
}
switch (p_sdl_msg->ue_Identity.d)
{
case SQN_NR_PagingUE_Identity_ng_5G_S_TMSI:
p_record_msg->ue_paging_identity.presenceMask = NR_UE_PAGING_IDENTITY_NG_5G_S_TMSI;
p_record_msg->ue_paging_identity.choice.ng_5g_s_tmsi.length = sizeof(p_sdl_msg->ue_Identity.v.ng_5G_S_TMSI);
memcpy((char *)p_record_msg->ue_paging_identity.choice.ng_5g_s_tmsi.buffer,
(const char *)p_sdl_msg->ue_Identity.v.ng_5G_S_TMSI, sizeof(p_sdl_msg->ue_Identity.v.ng_5G_S_TMSI));
if (oneTimeProcessingFlag == 0)
{
SS_NR_PAGING_IND(message_p).ue_index_value = paging_ue_index_g;
paging_ue_index_g = ((paging_ue_index_g + 4) % MAX_MOBILES_PER_GNB);
oneTimeProcessingFlag = 1;
}
break;
case SQN_NR_PagingUE_Identity_fullI_RNTI:
p_record_msg->ue_paging_identity.presenceMask = NR_UE_PAGING_IDENTITY_FULL_I_RNTI;
p_record_msg->ue_paging_identity.choice.full_i_rnti.length = sizeof(p_sdl_msg->ue_Identity.v.fullI_RNTI);
memcpy((char *)p_record_msg->ue_paging_identity.choice.full_i_rnti.buffer,
(const char *)p_sdl_msg->ue_Identity.v.fullI_RNTI, sizeof(p_sdl_msg->ue_Identity.v.fullI_RNTI));
break;
case SQN_PagingUE_Identity_UNBOUND_VALUE:
LOG_A(GNB_APP, "[SYS-GNB] Error Unhandled Paging request\n");
break;
default :
LOG_A(GNB_APP, "[SYS-GNB] Invalid Paging request received\n");
break;
}
p_sdl_msg++;
p_record_msg++;
}
}
}
if (pagingRequest->SlotOffsetList.d)
{
LOG_A(GNB_APP, "[SYS-GNB] Slot Offset List present in Paging request\n");
SS_NR_PAGING_IND(message_p).bSlotOffsetListPresent = true;
SS_NR_PAGING_IND(message_p).slotOffsetList.num = 0;
for (int i=0; i < pagingRequest->SlotOffsetList.v.d; i++)
{
SS_NR_PAGING_IND(message_p).slotOffsetList.slot_offset[i] = pagingRequest->SlotOffsetList.v.v[i];
SS_NR_PAGING_IND(message_p).slotOffsetList.num++;
}
}
int send_res = itti_send_msg_to_task(TASK_RRC_GNB, 0, message_p);
if (send_res < 0)
{
LOG_A(GNB_APP, "[SYS-GNB] Error sending Paging to RRC_GNB");
}
oneTimeProcessingFlag = 0;
LOG_A(GNB_APP, "[SYS-GNB] Paging_IND for Cell_id %d sent to RRC\n", cellId);
break;
case SQN_NR_PCCH_MessageType_messageClassExtension:
LOG_A(GNB_APP, "[SYS-GNB] NR_PCCH_MessageType_messageClassExtension for Cell_id %d received\n", cellId);
break;
case SQN_NR_PCCH_MessageType_UNBOUND_VALUE:
LOG_A(GNB_APP, "[SYS-GNB] Invalid Pging request received Type_UNBOUND_VALUE received\n");
break;
default:
LOG_A(GNB_APP, "[SYS-GNB] Invalid Pging request received\n");
break;
}
LOG_A(GNB_APP, "[SYS-GNB] Exit sys_handle_nr_paging_req Paging_IND processing for Cell_id %d \n", cellId);
}
/*
* ===========================================================================================================
* Function Name: ss_task_sys_nr_handle_req
......@@ -399,6 +517,16 @@ static void ss_task_sys_nr_handle_req(struct NR_SYSTEM_CTRL_REQ *req, ss_nrset_t
LOG_A(GNB_APP, "[SYS-GNB] Sent SYS CNF for NR_SystemRequest_Type_DeltaValues\n");
}
break;
case NR_SystemRequest_Type_Paging:
{
LOG_A(GNB_APP, "[SYS-GNB] NR_SystemRequest_Type_Paging: received\n");
LOG_E(GNB_APP, "BLABLABLA [SYS-GNB] NR_SystemRequest_Type_Paging: received\n"); //TODO:BLA
ss_nrset_timinfo_t pg_timinfo;
pg_timinfo.sfn = req->Common.TimingInfo.v.SubFrame.SFN.v.Number;
pg_timinfo.slot = req->Common.TimingInfo.v.SubFrame.Subframe.v.Number; //TODO
sys_handle_nr_paging_req(&(req->Request.v.Paging), pg_timinfo);
}
break;
default:
{
LOG_E(GNB_APP, "[SYS-GNB] Error ! SS_STATE %d Invalid SystemRequest_Type %d received\n", RC.ss.State, req->Request.d);
......
......@@ -581,4 +581,30 @@ do { \
#define GTP_TEID_TO_ASN1 INT32_TO_OCTET_STRING
#define OCTET_STRING_TO_TAC OCTET_STRING_TO_INT16
#define OCTET_STRING_TO_BIT_STRING(dST, sRC, lEN) \
do { \
const char *src = (sRC); \
char *dst = (dST); \
int len = (lEN); \
int off = 0; \
while (len-- > 0) { \
int bit = *src++ ? 1 : 0; \
dst[off / 8] |= bit << (7 - off % 8); \
off++; \
} \
} while(0)
#define BIT_STRING_TO_OCTET_STRING(dST, sRC, lEN) \
do { \
const char *src = (sRC); \
char *dst = (dST); \
int len = (lEN); \
int off = 0; \
while (len-- > 0) { \
int bit = src[off / 8] & (1 << (7 - off % 8)); \
*dst++ = bit ? 0x01 : 0x00; \
off++; \
} \
} while(0)
#endif /* CONVERSIONS_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment