Commit 587cb422 authored by Jerome Peraldi's avatar Jerome Peraldi

Merge branch 'private/bugz129686' into 'private/sqn_w20_merged'

bug #129686: Merge sqn/3GPP_TTCN_System_Simulator:add support ip pdu through SDAP loopback(UE loop mode B) and ip packet through tun interface

See merge request sequans/system/ttcn/openairinterface5g!49
parents 498a0800 db59c468
...@@ -3,7 +3,7 @@ log_config = { ...@@ -3,7 +3,7 @@ log_config = {
hw_log_level ="error"; hw_log_level ="error";
phy_log_level ="error"; phy_log_level ="error";
mac_log_level ="error"; mac_log_level ="error";
nr_mac_log_level ="error"; nr_mac_log_level ="analysis";
rlc_log_level ="info"; rlc_log_level ="info";
pdcp_log_level ="info"; pdcp_log_level ="info";
rrc_log_level ="info"; rrc_log_level ="info";
......
...@@ -38,3 +38,4 @@ MESSAGE_DEF(RRC_DCCH_DATA_COPY_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataIn ...@@ -38,3 +38,4 @@ MESSAGE_DEF(RRC_DCCH_DATA_COPY_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataIn
MESSAGE_DEF(NR_RRC_DCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, NRRrcDcchDataReq, nr_rrc_dcch_data_req) MESSAGE_DEF(NR_RRC_DCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, NRRrcDcchDataReq, nr_rrc_dcch_data_req)
MESSAGE_DEF(NR_RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcDcchDataInd, nr_rrc_dcch_data_ind) MESSAGE_DEF(NR_RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcDcchDataInd, nr_rrc_dcch_data_ind)
MESSAGE_DEF(NR_DTCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, NRDtchDataReq, nr_dtch_data_req) MESSAGE_DEF(NR_DTCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, NRDtchDataReq, nr_dtch_data_req)
MESSAGE_DEF(NR_SDAP_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, NRSdapDataReq, nr_sdap_data_req)
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
#define NR_RRC_DCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_dcch_data_req #define NR_RRC_DCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_dcch_data_req
#define NR_RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_dcch_data_ind #define NR_RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_dcch_data_ind
#define NR_DTCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nr_dtch_data_req #define NR_DTCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nr_dtch_data_req
#define NR_SDAP_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nr_sdap_data_req
//-------------------------------------------------------------------------------------------// //-------------------------------------------------------------------------------------------//
// Messages between RRC and PDCP layers // Messages between RRC and PDCP layers
...@@ -122,4 +124,20 @@ typedef struct NRDtchDataReq_s { ...@@ -122,4 +124,20 @@ typedef struct NRDtchDataReq_s {
uint8_t gNB_index; uint8_t gNB_index;
} NRDtchDataReq; } NRDtchDataReq;
typedef struct NRSdapDataReq_s {
uint8_t gnb_flag;
rb_id_t rb_id;
uint32_t muip;
uint32_t confirmp;
uint32_t sdu_size;
uint8_t *sdu_p;
uint8_t mode;
uint16_t rnti;
uint8_t module_id;
uint8_t gNB_index;
uint8_t qfi;
bool rqi;
int pdu_sessionId;
}NRSdapDataReq;
#endif /* PDCP_MESSAGES_TYPES_H_ */ #endif /* PDCP_MESSAGES_TYPES_H_ */
...@@ -240,18 +240,24 @@ typedef struct ss_vng_proxy_resp_s { ...@@ -240,18 +240,24 @@ typedef struct ss_vng_proxy_resp_s {
/** DRB **/ /** DRB **/
typedef struct ss_drb_pdu_req_s { typedef struct ss_drb_pdu_req_s {
uint8_t drb_id; uint8_t drb_id;
uint8_t data_type;
uint32_t sdu_size; uint32_t sdu_size;
uint8_t sdu[SDU_SIZE]; uint8_t sdu[SDU_SIZE];
uint16_t rnti; uint16_t rnti;
int32_t pdu_sessionId; /* for data_type=DRB_SdapSdu */
int32_t qfi; /* for data_type=DRB_SdapSdu */
} ss_drb_pdu_req_t; } ss_drb_pdu_req_t;
typedef struct ss_drb_pdu_ind_s { typedef struct ss_drb_pdu_ind_s {
uint8_t drb_id; uint8_t drb_id;
uint8_t data_type;
uint32_t sdu_size; uint32_t sdu_size;
uint8_t sdu[SDU_SIZE]; uint8_t sdu[SDU_SIZE];
frame_t frame; /*!< \brief LTE frame number.*/ frame_t frame; /*!< \brief LTE frame number.*/
sub_frame_t subframe; /*!< \brief LTE sub frame number.*/ sub_frame_t subframe; /*!< \brief LTE sub frame number.*/
int physCellId; int physCellId;
int32_t pdu_sessionId; /* for data_type=DRB_SdapSdu */
int32_t qfi; /* for data_type=DRB_SdapSdu */
} ss_drb_pdu_ind_t; } ss_drb_pdu_ind_t;
typedef enum carrierBandwidthEUTRA_dl_Bandwidth_e { typedef enum carrierBandwidthEUTRA_dl_Bandwidth_e {
......
...@@ -545,6 +545,87 @@ static void start_pdcp_tun_ue(void) ...@@ -545,6 +545,87 @@ static void start_pdcp_tun_ue(void)
} }
} }
void enqueue_sdap_data_req(
const uint8_t gnb_flag,
const ue_id_t ue_id,
const srb_flag_t srb_flag,
const rb_id_t rb_id,
const mui_t mui,
const confirm_t confirm,
const sdu_size_t sdu_buffer_size,
unsigned char *const sdu_buffer,
const pdcp_transmission_mode_t pt_mode,
const uint8_t qfi,
const bool rqi,
const int pdu_sessionId,
const uint8_t delaySeconds)
{
int result=0;
protocol_ctxt_t ctxt;
PROTOCOL_CTXT_SET_BY_MODULE_ID(
&ctxt,
0,
gnb_flag,
ue_id,
nr_pdcp_current_time_last_frame,
nr_pdcp_current_time_last_subframe,
0);
if(gnb_flag){
if(RC.nr_drb_data_type == DRB_SdapSdu){
LOG_I(SDAP, "Sending SDAP SDU to SS DBR task\n");
MessageDef *message_p = itti_alloc_new_message(TASK_SS_DRB, 0, SS_DRB_PDU_IND);
AssertFatal(message_p != NULL, "Failed to allocate msg\n");
SS_DRB_PDU_IND(message_p).frame = nr_pdcp_current_time_last_frame;
SS_DRB_PDU_IND(message_p).subframe = nr_pdcp_current_time_last_subframe;
SS_DRB_PDU_IND(message_p).data_type = DRB_SdapSdu;
/*TODO: physCellId shall be filled if multicell through ue_id(rnti) */
//SS_DRB_PDU_IND(message_p).physCellId =
SS_DRB_PDU_IND(message_p).sdu_size = sdu_buffer_size;
memcpy(SS_DRB_PDU_IND(message_p).sdu, sdu_buffer, sdu_buffer_size);
SS_DRB_PDU_IND(message_p).pdu_sessionId = pdu_sessionId;
SS_DRB_PDU_IND(message_p).qfi = qfi;
itti_send_msg_to_task(TASK_SS_DRB, 0, message_p);
result = itti_send_msg_to_task(TASK_SS_DRB, ctxt.module_id, message_p);
if (result < 0) {
LOG_E(SDAP, "Error in itti_send_msg_to_task!\n");
}
}
}else {
LOG_I(SDAP, "Sending NR_SDAP_DATA_REQ to RRC NRUE, ue 0x%lx drb id %ld len %u\n",
ctxt.rntiMaybeUEid, rb_id, sdu_buffer_size);
MessageDef *message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_SDAP_DATA_REQ);
AssertFatal(message_p != NULL, "Failed to allocate msg\n");
uint8_t *message_buffer = itti_malloc(TASK_PDCP_UE, TASK_RRC_NRUE, sdu_buffer_size);
AssertFatal(message_buffer != NULL, "Failed to allocate msg\n");
memcpy(message_buffer, sdu_buffer, sdu_buffer_size);
NR_SDAP_DATA_REQ (message_p).gnb_flag = ctxt.enb_flag;
NR_SDAP_DATA_REQ (message_p).rb_id = rb_id;
NR_SDAP_DATA_REQ (message_p).muip = mui;
NR_SDAP_DATA_REQ (message_p).confirmp = confirm;
NR_SDAP_DATA_REQ (message_p).sdu_size = sdu_buffer_size;
NR_SDAP_DATA_REQ (message_p).sdu_p = message_buffer;
NR_SDAP_DATA_REQ (message_p).mode = pt_mode;
NR_SDAP_DATA_REQ (message_p).module_id = ctxt.module_id;
NR_SDAP_DATA_REQ (message_p).rnti = ctxt.rntiMaybeUEid;
NR_SDAP_DATA_REQ (message_p).gNB_index = 0;
NR_SDAP_DATA_REQ (message_p).qfi = qfi;
NR_SDAP_DATA_REQ (message_p).rqi = rqi;
NR_SDAP_DATA_REQ (message_p).pdu_sessionId = pdu_sessionId;
result = itti_send_msg_to_task(TASK_RRC_NRUE, ctxt.module_id, message_p);
if (result < 0) {
LOG_E(SDAP, "Error in itti_send_msg_to_task!\n");
}
}
}
/****************************************************************************/ /****************************************************************************/
/* hacks to be cleaned up at some point - end */ /* hacks to be cleaned up at some point - end */
/****************************************************************************/ /****************************************************************************/
...@@ -689,13 +770,6 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id) ...@@ -689,13 +770,6 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id)
if (PDCP_USE_NETLINK) { if (PDCP_USE_NETLINK) {
nas_getparams(); nas_getparams();
/* TODO: TTCN support, disable TUN device.
* TTCN doesn't send correct IP packet, but random data for DATA loopback,
* need to choose correct flag in 'if' statement to identify that fact. */
if (IS_SOFTMODEM_NOS1 || (ENB_NAS_USE_TUN || UE_NAS_USE_TUN)) {
return pdcp_optmask;
}
if(UE_NAS_USE_TUN) { if(UE_NAS_USE_TUN) {
char *ifsuffix_ue = get_softmodem_params()->nsa ? "nrue" : "ue"; char *ifsuffix_ue = get_softmodem_params()->nsa ? "nrue" : "ue";
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1; int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1;
...@@ -722,6 +796,12 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id) ...@@ -722,6 +796,12 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id)
return pdcp_optmask ; return pdcp_optmask ;
} }
bool pdcp_test_loop = false;/*TODO: should have multiple DRB list and corresponding scalling configuration from nas CLOSE UE LOOP (mode A)*/
void set_pdcp_loopback(bool enable)
{
pdcp_test_loop = enable;
}
static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
char *buf, int size) char *buf, int size)
{ {
...@@ -729,10 +809,10 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, ...@@ -729,10 +809,10 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
int rb_id; int rb_id;
int i; int i;
/* TODO: TTCN support. /*This should use test loop mode instead of the tun flag */
* Also TTCN doesn't send correct IP packet, but random data for DATA loopback, /* For UE, TS38.509 5.3.4.1 UE test loop mode A operation
* need to choose correct flag in 'if' statement to identify that fact. */ For gNB: report the data to SS */
if (IS_SOFTMODEM_NOS1 || (ENB_NAS_USE_TUN || UE_NAS_USE_TUN)) { if ((entity->is_gnb== GNB_FLAG_NO && pdcp_test_loop) || (entity->is_gnb== GNB_FLAG_YES && RC.ss.mode >= SS_SOFTMODEM && RC.nr_drb_data_type == DRB_PdcpSdu) ){
protocol_ctxt_t ctxt; protocol_ctxt_t ctxt;
PROTOCOL_CTXT_SET_BY_MODULE_ID( PROTOCOL_CTXT_SET_BY_MODULE_ID(
&ctxt, &ctxt,
......
...@@ -773,16 +773,19 @@ static void fill_dci_from_dl_config(nr_downlink_indication_t*dl_ind, fapi_nr_dl_ ...@@ -773,16 +773,19 @@ static void fill_dci_from_dl_config(nr_downlink_indication_t*dl_ind, fapi_nr_dl_
AssertFatal(dl_config->number_pdus < sizeof(dl_config->dl_config_list) / sizeof(dl_config->dl_config_list[0]), AssertFatal(dl_config->number_pdus < sizeof(dl_config->dl_config_list) / sizeof(dl_config->dl_config_list[0]),
"Too many dl_config pdus %d", dl_config->number_pdus); "Too many dl_config pdus %d", dl_config->number_pdus);
for (int i = 0; i < dl_config->number_pdus; i++) { for (int i = 0; i < dl_config->number_pdus; i++) {
LOG_D(PHY, "In %s: filling DCI with a total of %d total DL PDUs (dl_config %p) \n", LOG_D(PHY, "In %s: filling DCI with a total of %d total DL PDUs (dl_config %p), current dl_config->dl_config_list[%d].pdu_type=%d\n",
__FUNCTION__, dl_config->number_pdus, dl_config); __FUNCTION__, dl_config->number_pdus, dl_config,i, dl_config->dl_config_list[i].pdu_type);
if(dl_config->dl_config_list[i].pdu_type != FAPI_NR_DL_CONFIG_TYPE_DCI &&
dl_config->dl_config_list[i].pdu_type!=FAPI_NR_DL_CONFIG_TYPE_DLSCH){
/* Why consider fapi_nr_dl_config_dlsch_pdu same as fapi_nr_dl_config_dci_pdu ?? */
continue;
}
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15_dci = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15; fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15_dci = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15;
int num_dci_options = rel15_dci->num_dci_options; int num_dci_options = rel15_dci->num_dci_options;
if (num_dci_options <= 0) if (num_dci_options <= 0)
LOG_D(NR_MAC, "num_dci_opts = %d for pdu[%d] in dl_config_list\n", rel15_dci->num_dci_options, i); LOG_D(NR_MAC, "num_dci_opts = %d for pdu[%d] in dl_config_list\n", rel15_dci->num_dci_options, i);
AssertFatal(num_dci_options <= sizeof(rel15_dci->dci_length_options) / sizeof(rel15_dci->dci_length_options[0]), AssertFatal(num_dci_options <= sizeof(rel15_dci->dci_length_options) / sizeof(rel15_dci->dci_length_options[0]),
"num_dci_options %d > dci_length_options array\n", num_dci_options); "num_dci_options %d > dci_length_options array\n", num_dci_options);
AssertFatal(num_dci_options <= sizeof(rel15_dci->dci_format_options) / sizeof(rel15_dci->dci_format_options[0]),
"num_dci_options %d > dci_format_options array\n", num_dci_options);
for (int j = 0; j < num_dci_options; j++) { for (int j = 0; j < num_dci_options; j++) {
int num_dcis = dl_ind->dci_ind->number_of_dcis; int num_dcis = dl_ind->dci_ind->number_of_dcis;
......
...@@ -723,6 +723,8 @@ static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_p ...@@ -723,6 +723,8 @@ static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_p
ue_context_pP->ue_context.Srb[2].Active = 0; ue_context_pP->ue_context.Srb[2].Active = 0;
ue_context_pP->ue_context.StatusRrc = NR_RRC_CONNECTED; ue_context_pP->ue_context.StatusRrc = NR_RRC_CONNECTED;
if (RC.ss.mode >= SS_SOFTMODEM) return;
if (get_softmodem_params()->sa) { if (get_softmodem_params()->sa) {
rrc_gNB_send_NGAP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcSetupComplete); rrc_gNB_send_NGAP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcSetupComplete);
} else { } else {
...@@ -3779,7 +3781,7 @@ void *rrc_gnb_task(void *args_p) { ...@@ -3779,7 +3781,7 @@ void *rrc_gnb_task(void *args_p) {
msg_p->ittiMsgHeader.lte_time.frame, msg_p->ittiMsgHeader.lte_time.frame,
msg_p->ittiMsgHeader.lte_time.slot); msg_p->ittiMsgHeader.lte_time.slot);
if (RC.nr_drb_data_type == DRB_RlcPdu || RC.nr_drb_data_type == DRB_RlcSdu) { if (SS_DRB_PDU_REQ(msg_p).data_type == DRB_RlcPdu || SS_DRB_PDU_REQ(msg_p).data_type == DRB_RlcSdu) {
mem_block_t *sdu = get_free_mem_block(SS_DRB_PDU_REQ(msg_p).sdu_size, __func__); mem_block_t *sdu = get_free_mem_block(SS_DRB_PDU_REQ(msg_p).sdu_size, __func__);
memcpy(sdu->data, SS_DRB_PDU_REQ(msg_p).sdu, SS_DRB_PDU_REQ(msg_p).sdu_size); memcpy(sdu->data, SS_DRB_PDU_REQ(msg_p).sdu, SS_DRB_PDU_REQ(msg_p).sdu_size);
enqueue_mac_rlc_data_req(&ctxt, enqueue_mac_rlc_data_req(&ctxt,
...@@ -3792,7 +3794,7 @@ void *rrc_gnb_task(void *args_p) { ...@@ -3792,7 +3794,7 @@ void *rrc_gnb_task(void *args_p) {
sdu, sdu,
NULL, NULL,
NULL); NULL);
} else if (RC.nr_drb_data_type == DRB_PdcpSdu) { } else if (SS_DRB_PDU_REQ(msg_p).data_type == DRB_PdcpSdu) {
nr_pdcp_data_req_drb(&ctxt, nr_pdcp_data_req_drb(&ctxt,
SRB_FLAG_NO, SRB_FLAG_NO,
SS_DRB_PDU_REQ(msg_p).drb_id, SS_DRB_PDU_REQ(msg_p).drb_id,
...@@ -3803,6 +3805,19 @@ void *rrc_gnb_task(void *args_p) { ...@@ -3803,6 +3805,19 @@ void *rrc_gnb_task(void *args_p) {
PDCP_TRANSMISSION_MODE_UNKNOWN, PDCP_TRANSMISSION_MODE_UNKNOWN,
NULL, NULL,
NULL); NULL);
} else if (SS_DRB_PDU_REQ(msg_p).data_type == DRB_SdapSdu){
sdap_data_req(&ctxt,
SS_DRB_PDU_REQ(msg_p).rnti,
SRB_FLAG_NO,
SS_DRB_PDU_REQ(msg_p).drb_id,
RLC_MUI_UNDEFINED,
RLC_SDU_CONFIRM_NO,
SS_DRB_PDU_REQ(msg_p).sdu_size,
SS_DRB_PDU_REQ(msg_p).sdu,
PDCP_TRANSMISSION_MODE_DATA, NULL, NULL,
SS_DRB_PDU_REQ(msg_p).qfi,
0,
SS_DRB_PDU_REQ(msg_p).pdu_sessionId);
} else { } else {
AssertFatal(RC.nr_drb_data_type != RC.nr_drb_data_type, "Invalid DRB data type (%d)!\n", RC.nr_drb_data_type); AssertFatal(RC.nr_drb_data_type != RC.nr_drb_data_type, "Invalid DRB data type (%d)!\n", RC.nr_drb_data_type);
} }
......
...@@ -2179,15 +2179,14 @@ nr_rrc_ue_establish_srb2( ...@@ -2179,15 +2179,14 @@ nr_rrc_ue_establish_srb2(
uint8_t *pdu_buffer; uint8_t *pdu_buffer;
MessageDef *msg_p; MessageDef *msg_p;
for (list_count = 0; list_count < ie->nonCriticalExtension->dedicatedNAS_MessageList->list.count; list_count++) { for (list_count = 0; list_count < ie->nonCriticalExtension->dedicatedNAS_MessageList->list.count; list_count++) {
pdu_length = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->size; pdu_length = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->size;
pdu_buffer = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->buf; pdu_buffer = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->buf;
msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_ESTABLI_CNF); msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_DOWNLINK_DATA_IND);
NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS; NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length = pdu_length;
NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = pdu_length; NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = pdu_buffer;
NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = pdu_buffer; itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p);
itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p); }
}
free (ie->nonCriticalExtension->dedicatedNAS_MessageList); free (ie->nonCriticalExtension->dedicatedNAS_MessageList);
} }
...@@ -2350,12 +2349,15 @@ nr_rrc_ue_establish_srb2( ...@@ -2350,12 +2349,15 @@ nr_rrc_ue_establish_srb2(
NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = dedicatedNAS_Message->buf; NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = dedicatedNAS_Message->buf;
itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p); itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p);
/*Send NAS_CONN_ESTABLI_CNF for handling Registration Accept in DL-Info transfer*/ /*Send NAS_CONN_ESTABLI_CNF for handling Registration Accept in DL-Info transfer.*/
msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_ESTABLI_CNF); /*It is not necessary to process the NAS message request with two request */
NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS; /*
NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = dedicatedNAS_Message->size; message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_ESTABLI_CNF);
NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = dedicatedNAS_Message->buf; NAS_CONN_ESTABLI_CNF(message_p).errCode = AS_SUCCESS;
itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p); NAS_CONN_ESTABLI_CNF(message_p).nasMsg.length = dedicatedNAS_Message->size;
NAS_CONN_ESTABLI_CNF(message_p).nasMsg.data = dedicatedNAS_Message->buf;
itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, message_p);
*/
} }
} }
break; break;
...@@ -2540,6 +2542,31 @@ nr_rrc_ue_establish_srb2( ...@@ -2540,6 +2542,31 @@ nr_rrc_ue_establish_srb2(
break; break;
} }
case NR_SDAP_DATA_REQ:
{
result = sdap_data_req(&ctxt,
NR_SDAP_DATA_REQ(msg_p).rnti,
SRB_FLAG_NO,
NR_SDAP_DATA_REQ(msg_p).rb_id,
NR_SDAP_DATA_REQ(msg_p).muip,
NR_SDAP_DATA_REQ(msg_p).confirmp,
NR_SDAP_DATA_REQ(msg_p).sdu_size,
(unsigned char *)NR_SDAP_DATA_REQ(msg_p).sdu_p,
NR_SDAP_DATA_REQ(msg_p).mode,
NULL,
NULL,
NR_SDAP_DATA_REQ(msg_p).qfi,
NR_SDAP_DATA_REQ(msg_p).rqi,
NR_SDAP_DATA_REQ(msg_p).pdu_sessionId);
if (result != true) {
LOG_E(NR_RRC, "NR_SDAP_DATA_REQ data request failed!\n");
}
result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), NR_SDAP_DATA_REQ(msg_p).sdu_p);
AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
break;
}
default: default:
LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
break; break;
......
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
uint8_t nas_qfi; uint8_t nas_qfi;
uint8_t nas_pduid; uint8_t nas_pduid;
bool sdap_test_loop = false;
uint8_t sdap_testLoopDelayTimeSeconds = 0;
bool sdap_data_req(protocol_ctxt_t *ctxt_p, bool sdap_data_req(protocol_ctxt_t *ctxt_p,
const ue_id_t ue_id, const ue_id_t ue_id,
const srb_flag_t srb_flag, const srb_flag_t srb_flag,
...@@ -92,3 +95,9 @@ void set_qfi_pduid(uint8_t qfi, uint8_t pduid){ ...@@ -92,3 +95,9 @@ void set_qfi_pduid(uint8_t qfi, uint8_t pduid){
nas_pduid = pduid; nas_pduid = pduid;
return; return;
} }
void set_sdap_loopback(bool enable, uint8_t testLoopDelayTimeSeconds){
sdap_test_loop = enable;
sdap_testLoopDelayTimeSeconds = testLoopDelayTimeSeconds;
return;
}
\ No newline at end of file
...@@ -63,4 +63,6 @@ void sdap_data_ind(rb_id_t pdcp_entity, ...@@ -63,4 +63,6 @@ void sdap_data_ind(rb_id_t pdcp_entity,
void set_qfi_pduid(uint8_t qfi, uint8_t pduid); void set_qfi_pduid(uint8_t qfi, uint8_t pduid);
void set_sdap_loopback(bool enable, uint8_t testLoopDelayTimeSeconds);
#endif #endif
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
#include <string.h> #include <string.h>
#include <pthread.h> #include <pthread.h>
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
typedef struct { typedef struct {
nr_sdap_entity_t *sdap_entity_llist; nr_sdap_entity_t *sdap_entity_llist;
} nr_sdap_entity_info; } nr_sdap_entity_info;
...@@ -177,6 +180,21 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity, ...@@ -177,6 +180,21 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity,
return ret; return ret;
} }
extern void enqueue_sdap_data_req(
const uint8_t gnb_flag,
const ue_id_t ue_id,
const srb_flag_t srb_flag,
const rb_id_t rb_id,
const mui_t mui,
const confirm_t confirm,
const sdu_size_t sdu_buffer_size,
unsigned char *const sdu_buffer,
const pdcp_transmission_mode_t pt_mode,
const uint8_t qfi,
const bool rqi,
const int pdu_sessionId,
const uint8_t delaySeconds);
static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
rb_id_t pdcp_entity, rb_id_t pdcp_entity,
int is_gnb, int is_gnb,
...@@ -189,9 +207,12 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, ...@@ -189,9 +207,12 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
int offset=0; int offset=0;
if (is_gnb) { // gNB if (is_gnb) { // gNB
uint8_t qfi =1;
bool rqi = false;
if (has_sdap_rx) { // Handling the SDAP Header if (has_sdap_rx) { // Handling the SDAP Header
offset = SDAP_HDR_LENGTH; offset = SDAP_HDR_LENGTH;
nr_sdap_ul_hdr_t *sdap_hdr = (nr_sdap_ul_hdr_t *)buf; nr_sdap_ul_hdr_t *sdap_hdr = (nr_sdap_ul_hdr_t *)buf;
qfi = sdap_hdr->QFI;
LOG_D(SDAP, "RX Entity Received QFI: %u\n", sdap_hdr->QFI); LOG_D(SDAP, "RX Entity Received QFI: %u\n", sdap_hdr->QFI);
LOG_D(SDAP, "RX Entity Received R bit: %u\n", sdap_hdr->R); LOG_D(SDAP, "RX Entity Received R bit: %u\n", sdap_hdr->R);
LOG_D(SDAP, "RX Entity Received DC bit: %u\n", sdap_hdr->DC); LOG_D(SDAP, "RX Entity Received DC bit: %u\n", sdap_hdr->DC);
...@@ -207,6 +228,22 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, ...@@ -207,6 +228,22 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
} }
} }
if(RC.ss.mode >= SS_SOFTMODEM){
enqueue_sdap_data_req(GNB_FLAG_YES,
ue_id,
SRB_FLAG_NO,
pdcp_entity,
RLC_MUI_UNDEFINED,
RLC_SDU_CONFIRM_NO,
size - offset,
(unsigned char *)(buf+offset),
PDCP_TRANSMISSION_MODE_DATA,
qfi,
rqi,
pdusession_id,
0);
return;
}
// Pushing SDAP SDU to GTP-U Layer // Pushing SDAP SDU to GTP-U Layer
MessageDef *message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, MessageDef *message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB,
0, 0,
...@@ -226,6 +263,8 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, ...@@ -226,6 +263,8 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
// very very dirty hack gloabl var N3GTPUInst // very very dirty hack gloabl var N3GTPUInst
itti_send_msg_to_task(TASK_GTPV1_U, *N3GTPUInst, message_p); itti_send_msg_to_task(TASK_GTPV1_U, *N3GTPUInst, message_p);
} else { //nrUE } else { //nrUE
extern uint8_t nas_qfi;
uint8_t qfi = nas_qfi;
/* /*
* TS 37.324 5.2 Data transfer * TS 37.324 5.2 Data transfer
* 5.2.2 Downlink * 5.2.2 Downlink
...@@ -242,7 +281,7 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, ...@@ -242,7 +281,7 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
LOG_D(SDAP, "RX Entity Received QFI : %u\n", sdap_hdr->QFI); LOG_D(SDAP, "RX Entity Received QFI : %u\n", sdap_hdr->QFI);
LOG_D(SDAP, "RX Entity Received RQI : %u\n", sdap_hdr->RQI); LOG_D(SDAP, "RX Entity Received RQI : %u\n", sdap_hdr->RQI);
LOG_D(SDAP, "RX Entity Received RDI : %u\n", sdap_hdr->RDI); LOG_D(SDAP, "RX Entity Received RDI : %u\n", sdap_hdr->RDI);
qfi = sdap_hdr->QFI;
/* /*
* TS 37.324 5.2 Data transfer * TS 37.324 5.2 Data transfer
* 5.2.2 Downlink * 5.2.2 Downlink
...@@ -294,6 +333,28 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, ...@@ -294,6 +333,28 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
} }
} /* else - retrieve the SDAP SDU from the DL SDAP data PDU as specified in the subclause 6.2.2.1 */ } /* else - retrieve the SDAP SDU from the DL SDAP data PDU as specified in the subclause 6.2.2.1 */
/* TS38.509 5.3.4.2 UE test loop mode B operation */
extern bool sdap_test_loop;
extern uint8_t sdap_testLoopDelayTimeSeconds;
if(sdap_test_loop){
LOG_D(SDAP, "SDAP loop back SDU\n");
bool dc = SDAP_HDR_UL_DATA_PDU;
enqueue_sdap_data_req(GNB_FLAG_NO,
ue_id,
SRB_FLAG_NO,
pdcp_entity,
RLC_MUI_UNDEFINED,
RLC_SDU_CONFIRM_NO,
size - offset,
(unsigned char *)(buf+offset),
PDCP_TRANSMISSION_MODE_DATA,
qfi,
dc,
pdusession_id,
sdap_testLoopDelayTimeSeconds);
return;
}
/* /*
* TS 37.324 5.2 Data transfer * TS 37.324 5.2 Data transfer
* 5.2.2 Downlink * 5.2.2 Downlink
......
This diff is collapsed.
...@@ -87,9 +87,15 @@ static void ss_send_drb_data(ss_drb_pdu_ind_t *pdu_ind) ...@@ -87,9 +87,15 @@ static void ss_send_drb_data(ss_drb_pdu_ind_t *pdu_ind)
ind.Common.CellId = nr_Cell1; ind.Common.CellId = nr_Cell1;
// Populated the Routing Info // Populated the Routing Info
ind.Common.RoutingInfo.d = NR_RoutingInfo_Type_RadioBearerId; if(_drb_data_type == DRB_SdapSdu){
ind.Common.RoutingInfo.v.RadioBearerId.d = NR_RadioBearerId_Type_Drb; ind.Common.RoutingInfo.d = NR_RoutingInfo_Type_QosFlow;
ind.Common.RoutingInfo.v.RadioBearerId.v.Drb = pdu_ind->drb_id; ind.Common.RoutingInfo.v.QosFlow.PDU_SessionId = pdu_ind->pdu_sessionId;
ind.Common.RoutingInfo.v.QosFlow.QFI = pdu_ind->qfi;
} else {
ind.Common.RoutingInfo.d = NR_RoutingInfo_Type_RadioBearerId;
ind.Common.RoutingInfo.v.RadioBearerId.d = NR_RadioBearerId_Type_Drb;
ind.Common.RoutingInfo.v.RadioBearerId.v.Drb = pdu_ind->drb_id;
}
// Populated the Timing Info // Populated the Timing Info
ind.Common.TimingInfo.d = TimingInfo_Type_SubFrame; ind.Common.TimingInfo.d = TimingInfo_Type_SubFrame;
...@@ -229,6 +235,26 @@ static void ss_send_drb_data(ss_drb_pdu_ind_t *pdu_ind) ...@@ -229,6 +235,26 @@ static void ss_send_drb_data(ss_drb_pdu_ind_t *pdu_ind)
} }
break; break;
case DRB_SdapSdu:
{
LOG_A(GNB_APP, "[SS_DRB] SDAP SDU received in NR_DRB_COMMON_IND\n");
// Populating the SDU
ind.U_Plane.SlotData.NoOfTTIs = 1;
ind.U_Plane.SlotData.PduSduList.d = NR_L2DataList_Type_SdapSdu;
ind.U_Plane.SlotData.PduSduList.v.SdapSdu.d = 1;
ind.U_Plane.SlotData.PduSduList.v.SdapSdu.v = CALLOC(1, ind.U_Plane.SlotData.PduSduList.v.SdapSdu.d * sizeof(SDAP_SDU_Type));
DevAssert(ind.U_Plane.SlotData.PduSduList.v.SdapSdu.v != NULL);
for (int i = 0; i < ind.U_Plane.SlotData.PduSduList.v.SdapSdu.d; i++) {
SDAP_SDU_Type *sdapSdu = &ind.U_Plane.SlotData.PduSduList.v.SdapSdu.v[i];
sdapSdu->d = pdu_ind->sdu_size;
sdapSdu->v = CALLOC(1, sdapSdu->d);
DevAssert(sdapSdu->v != NULL);
memcpy(sdapSdu->v, pdu_ind->sdu, sdapSdu->d);
}
}
break;
default: default:
LOG_E(GNB_APP, "[SS_DRB] %s requested NR_L2DataList_Type %d that is not yet implemented\n", _drb_data_type); LOG_E(GNB_APP, "[SS_DRB] %s requested NR_L2DataList_Type %d that is not yet implemented\n", _drb_data_type);
} }
...@@ -278,7 +304,7 @@ static void ss_task_handle_drb_pdu_req(struct NR_DRB_COMMON_REQ *req) ...@@ -278,7 +304,7 @@ static void ss_task_handle_drb_pdu_req(struct NR_DRB_COMMON_REQ *req)
message_p = itti_alloc_new_message(task_id, 0, SS_DRB_PDU_REQ); message_p = itti_alloc_new_message(task_id, 0, SS_DRB_PDU_REQ);
assert(message_p); assert(message_p);
memset(SS_DRB_PDU_REQ(message_p).sdu, 0, SDU_SIZE); memset(SS_DRB_PDU_REQ(message_p).sdu, 0, SDU_SIZE);
SS_DRB_PDU_REQ(message_p).data_type = (uint8_t)DRB_RlcPdu;
if (rlcPdu->d == NR_RLC_PDU_Type_UMD && rlcPdu->v.UMD.d == NR_RLC_UMD_PDU_Type_NoSN) if (rlcPdu->d == NR_RLC_PDU_Type_UMD && rlcPdu->v.UMD.d == NR_RLC_UMD_PDU_Type_NoSN)
{ {
struct NR_RLC_UMD_HeaderNoSN_Type *header = &rlcPdu->v.UMD.v.NoSN.Header; struct NR_RLC_UMD_HeaderNoSN_Type *header = &rlcPdu->v.UMD.v.NoSN.Header;
...@@ -297,12 +323,14 @@ static void ss_task_handle_drb_pdu_req(struct NR_DRB_COMMON_REQ *req) ...@@ -297,12 +323,14 @@ static void ss_task_handle_drb_pdu_req(struct NR_DRB_COMMON_REQ *req)
int pdu_header_size = 1; int pdu_header_size = 1;
bits_copy_from_array(SS_DRB_PDU_REQ(message_p).sdu, 0, header->SegmentationInfo, 2); bits_copy_from_array(SS_DRB_PDU_REQ(message_p).sdu, 0, header->SegmentationInfo, 2);
bits_copy_from_array(SS_DRB_PDU_REQ(message_p).sdu, 2, header->SequenceNumber, 6); bits_copy_from_array(SS_DRB_PDU_REQ(message_p).sdu, 2, header->SequenceNumber, 6);
SS_DRB_PDU_REQ(message_p).data_type = (uint8_t)DRB_RlcPdu;
if (header->SegmentOffset.d) if (header->SegmentOffset.d)
{ {
pdu_header_size += 2; pdu_header_size += 2;
bits_copy_from_array(SS_DRB_PDU_REQ(message_p).sdu, 8, header->SegmentOffset.v, 16); bits_copy_from_array(SS_DRB_PDU_REQ(message_p).sdu, 8, header->SegmentOffset.v, 16);
//we consider only RLC payload is there meaning that RLC packet is segmented //we consider only RLC payload is there meaning that RLC packet is segmented
RC.nr_drb_data_type = DRB_RlcSdu; RC.nr_drb_data_type = DRB_RlcSdu;
SS_DRB_PDU_REQ(message_p).data_type = (uint8_t)DRB_RlcSdu;
} }
SS_DRB_PDU_REQ(message_p).sdu_size = pdu_header_size + data->d; SS_DRB_PDU_REQ(message_p).sdu_size = pdu_header_size + data->d;
LOG_A(GNB_APP, "[SS_DRB] Length of RLC PDU received in NR_DRB_COMMON_REQ (SN6Bit): %lu\n", pdu_header_size + data->d); LOG_A(GNB_APP, "[SS_DRB] Length of RLC PDU received in NR_DRB_COMMON_REQ (SN6Bit): %lu\n", pdu_header_size + data->d);
...@@ -321,6 +349,7 @@ static void ss_task_handle_drb_pdu_req(struct NR_DRB_COMMON_REQ *req) ...@@ -321,6 +349,7 @@ static void ss_task_handle_drb_pdu_req(struct NR_DRB_COMMON_REQ *req)
bits_copy_from_array(SS_DRB_PDU_REQ(message_p).sdu, 16, header->SegmentOffset.v, 16); bits_copy_from_array(SS_DRB_PDU_REQ(message_p).sdu, 16, header->SegmentOffset.v, 16);
//we consider only RLC payload is there meaning that RLC packet is segmented //we consider only RLC payload is there meaning that RLC packet is segmented
RC.nr_drb_data_type = DRB_RlcSdu; RC.nr_drb_data_type = DRB_RlcSdu;
SS_DRB_PDU_REQ(message_p).data_type = (uint8_t)DRB_RlcSdu;
} }
SS_DRB_PDU_REQ(message_p).sdu_size = pdu_header_size + data->d; SS_DRB_PDU_REQ(message_p).sdu_size = pdu_header_size + data->d;
LOG_A(GNB_APP, "[SS_DRB] Length of RLC PDU received in NR_DRB_COMMON_REQ: %lu\n", pdu_header_size + data->d); LOG_A(GNB_APP, "[SS_DRB] Length of RLC PDU received in NR_DRB_COMMON_REQ: %lu\n", pdu_header_size + data->d);
...@@ -363,6 +392,43 @@ static void ss_task_handle_drb_pdu_req(struct NR_DRB_COMMON_REQ *req) ...@@ -363,6 +392,43 @@ static void ss_task_handle_drb_pdu_req(struct NR_DRB_COMMON_REQ *req)
SS_DRB_PDU_REQ(message_p).drb_id = req->Common.RoutingInfo.v.RadioBearerId.v.Drb; SS_DRB_PDU_REQ(message_p).drb_id = req->Common.RoutingInfo.v.RadioBearerId.v.Drb;
SS_DRB_PDU_REQ(message_p).rnti = SS_context.ss_rnti_g; SS_DRB_PDU_REQ(message_p).rnti = SS_context.ss_rnti_g;
SS_DRB_PDU_REQ(message_p).data_type = (uint8_t)DRB_PdcpSdu;
if (!nr_vt_timer_push_msg(&req->Common.TimingInfo, req->U_Plane.SlotDataList.v[i].SlotOffset, task_id, instance_g, message_p))
{
int send_res = itti_send_msg_to_task(task_id, instance_g, message_p);
if (send_res < 0)
{
LOG_E(GNB_APP, "[SS_DRB] Error in itti_send_msg_to_task\n");
}
LOG_A(GNB_APP, "[SS_DRB] Send res: %d\n", send_res);
}
}
}
else if (req->U_Plane.SlotDataList.v[i].PduSduList.d == NR_L2DataList_Type_SdapSdu)
{
LOG_A(GNB_APP, "[SS_DRB] Sdap SDU Received in NR_DRB_COMMON_REQ\n");
_drb_data_type = DRB_SdapSdu;
RC.nr_drb_data_type = DRB_SdapSdu;
for (int j = 0; j < req->U_Plane.SlotDataList.v[i].PduSduList.v.SdapSdu.d; j++)
{
message_p = itti_alloc_new_message(task_id, 0, SS_DRB_PDU_REQ);
assert(message_p);
memset(SS_DRB_PDU_REQ(message_p).sdu, 0, SDU_SIZE);
SDAP_SDU_Type *sdapSdu = &req->U_Plane.SlotDataList.v[i].PduSduList.v.SdapSdu.v[j];
SS_DRB_PDU_REQ(message_p).sdu_size = sdapSdu->d;
memcpy(SS_DRB_PDU_REQ(message_p).sdu, sdapSdu->v, sdapSdu->d);
LOG_A(GNB_APP, "[SS_DRB] Length of SDAP SDU received in NR_DRB_COMMON_REQ: %lu\n", sdapSdu->d);
SS_DRB_PDU_REQ(message_p).drb_id = 1; /* This parameter is not actually used in SDAP entity */
SS_DRB_PDU_REQ(message_p).rnti = SS_context.ss_rnti_g;
SS_DRB_PDU_REQ(message_p).data_type = (uint8_t)DRB_SdapSdu;
if(req->Common.RoutingInfo.d == NR_RoutingInfo_Type_QosFlow){
SS_DRB_PDU_REQ(message_p).pdu_sessionId = req->Common.RoutingInfo.v.QosFlow.PDU_SessionId;
SS_DRB_PDU_REQ(message_p).qfi = req->Common.RoutingInfo.v.QosFlow.QFI;
}
if (!nr_vt_timer_push_msg(&req->Common.TimingInfo, req->U_Plane.SlotDataList.v[i].SlotOffset, task_id, instance_g, message_p)) if (!nr_vt_timer_push_msg(&req->Common.TimingInfo, req->U_Plane.SlotDataList.v[i].SlotOffset, task_id, instance_g, message_p))
{ {
......
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