Commit d0a4dde9 authored by Cedric Roux's avatar Cedric Roux

attempt at synchronous PDCP RRC communication in the nr UE

When the UE receives several PDCP packets in one MAC PDU, if the
first is SecurityModeCommand, the following will be ciphered/integrity
protected. The RRC has to process SecurityModeCommand before PDCP
processes the following packets. Before this commit, PDCP will
not wait for RRC to finish and process the following messages, which
won't make any sense since they are ciphered but ciphering is not
configured yet.

So let's introduce some synchronous commmunication between PDCP
and RRC for SRBs in the UE. PDCP sends the data to RRC and waits
for a return message from RRC to continue its job.

The code is not super satisfying. nr_pdcp_entity_recv_pdu() may queue
the message and not send it to RRC immediately, so do_pdcp_data_ind()
may wait for a long time and maybe forever, I did  not analyze things
properly here. (The queuing is easy to detect, we could AssertFatal()
if that happens. Then find a proper solution if the case happens for
real and turns out being super annoying.)

Just an attempt, let's see.
parent 8a3c329e
...@@ -37,3 +37,4 @@ MESSAGE_DEF(RRC_DCCH_DATA_COPY_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataIn ...@@ -37,3 +37,4 @@ MESSAGE_DEF(RRC_DCCH_DATA_COPY_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataIn
// gNB // gNB
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_RRC_DCCH_DATA_RESP, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataResp, nr_rrc_dcch_data_resp)
...@@ -67,6 +67,10 @@ typedef struct RrcDcchDataInd_s { ...@@ -67,6 +67,10 @@ typedef struct RrcDcchDataInd_s {
uint8_t eNB_index; // LG: needed in UE uint8_t eNB_index; // LG: needed in UE
} RrcDcchDataInd; } RrcDcchDataInd;
typedef struct RrcDcchDataResp_s {
/* nothing */
} RrcDcchDataResp;
typedef struct RrcDcchDataCopyInd_s { typedef struct RrcDcchDataCopyInd_s {
uint8_t dcch_index; uint8_t dcch_index;
uint32_t sdu_size; uint32_t sdu_size;
......
...@@ -42,8 +42,8 @@ int nr_max_pdcp_pdu_size(sdu_size_t sdu_size) ...@@ -42,8 +42,8 @@ int nr_max_pdcp_pdu_size(sdu_size_t sdu_size)
return (sdu_size + LONG_PDCP_HEADER_SIZE + PDCP_INTEGRITY_SIZE); return (sdu_size + LONG_PDCP_HEADER_SIZE + PDCP_INTEGRITY_SIZE);
} }
static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, static int nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
char *_buffer, int size) char *_buffer, int size)
{ {
unsigned char *buffer = (unsigned char *)_buffer; unsigned char *buffer = (unsigned char *)_buffer;
nr_pdcp_sdu_t *sdu; nr_pdcp_sdu_t *sdu;
...@@ -58,12 +58,12 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, ...@@ -58,12 +58,12 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
if (entity->entity_suspended) { if (entity->entity_suspended) {
LOG_W(PDCP, "PDCP entity %d is suspended. Quit RX procedure.\n", entity->rb_id); LOG_W(PDCP, "PDCP entity %d is suspended. Quit RX procedure.\n", entity->rb_id);
return; return -1;
} }
if (size < 1) { if (size < 1) {
LOG_E(PDCP, "bad PDU received (size = %d)\n", size); LOG_E(PDCP, "bad PDU received (size = %d)\n", size);
return; return -1;
} }
if (entity->type != NR_PDCP_SRB && !(buffer[0] & 0x80)) { if (entity->type != NR_PDCP_SRB && !(buffer[0] & 0x80)) {
...@@ -105,7 +105,7 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, ...@@ -105,7 +105,7 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
entity->stats.rxpdu_dd_pkts++; entity->stats.rxpdu_dd_pkts++;
entity->stats.rxpdu_dd_bytes += size; entity->stats.rxpdu_dd_bytes += size;
return; return -1;
} }
rx_deliv_sn = entity->rx_deliv & entity->sn_max; rx_deliv_sn = entity->rx_deliv & entity->sn_max;
...@@ -147,7 +147,7 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, ...@@ -147,7 +147,7 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
entity->stats.rxpdu_dd_pkts++; entity->stats.rxpdu_dd_pkts++;
entity->stats.rxpdu_dd_bytes += size; entity->stats.rxpdu_dd_bytes += size;
return; return -1;
} }
} }
...@@ -157,7 +157,7 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, ...@@ -157,7 +157,7 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
entity->stats.rxpdu_dd_pkts++; entity->stats.rxpdu_dd_pkts++;
entity->stats.rxpdu_dd_bytes += size; entity->stats.rxpdu_dd_bytes += size;
return; return -1;
} }
sdu = nr_pdcp_new_sdu(rcvd_count, sdu = nr_pdcp_new_sdu(rcvd_count,
...@@ -201,6 +201,8 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, ...@@ -201,6 +201,8 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
entity->rx_reord = entity->rx_next; entity->rx_reord = entity->rx_next;
entity->t_reordering_start = entity->t_current; entity->t_reordering_start = entity->t_current;
} }
return 0;
} }
static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity, static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity,
......
...@@ -84,7 +84,7 @@ typedef struct nr_pdcp_entity_t { ...@@ -84,7 +84,7 @@ typedef struct nr_pdcp_entity_t {
nr_pdcp_entity_type_t type; nr_pdcp_entity_type_t type;
/* functions provided by the PDCP module */ /* functions provided by the PDCP module */
void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size); int (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size);
int (*process_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size, int (*process_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
int sdu_id, char *pdu_buffer, int pdu_max_size); int sdu_id, char *pdu_buffer, int pdu_max_size);
void (*delete_entity)(struct nr_pdcp_entity_t *entity); void (*delete_entity)(struct nr_pdcp_entity_t *entity);
......
...@@ -284,8 +284,10 @@ static void do_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, ...@@ -284,8 +284,10 @@ static void do_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, UEid); ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, UEid);
rb = nr_pdcp_get_rb(ue, rb_id, srb_flagP); rb = nr_pdcp_get_rb(ue, rb_id, srb_flagP);
int ret = -1;
if (rb != NULL) { if (rb != NULL) {
rb->recv_pdu(rb, (char *)sdu_buffer, sdu_buffer_size); ret = rb->recv_pdu(rb, (char *)sdu_buffer, sdu_buffer_size);
} else { } else {
LOG_E(PDCP, "pdcp_data_ind: no RB found (rb_id %ld, srb_flag %d)\n", rb_id, srb_flagP); LOG_E(PDCP, "pdcp_data_ind: no RB found (rb_id %ld, srb_flag %d)\n", rb_id, srb_flagP);
} }
...@@ -293,6 +295,14 @@ static void do_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, ...@@ -293,6 +295,14 @@ static void do_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
nr_pdcp_manager_unlock(nr_pdcp_ue_manager); nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
free(sdu_buffer); free(sdu_buffer);
/* UE: wait for RRC to indicate the processing of the message */
if (ctxt_pP->enb_flag == 0 && srb_flagP && ret == 0) {
MessageDef *Resp;
itti_receive_msg(TASK_PDCP_UE, &Resp);
AssertFatal(ITTI_MSG_ID(Resp) == NR_RRC_DCCH_DATA_RESP, "bad response from NR RRC\n");
itti_free(ITTI_MSG_ORIGIN_ID(Resp), Resp);
}
} }
static void *pdcp_data_ind_thread(void *_) static void *pdcp_data_ind_thread(void *_)
......
...@@ -1782,6 +1782,8 @@ void *rrc_nrue(void *notUsed) ...@@ -1782,6 +1782,8 @@ void *rrc_nrue(void *notUsed)
NR_RRC_DCCH_DATA_IND(msg_p).sdu_size, NR_RRC_DCCH_DATA_IND(msg_p).sdu_size,
NR_RRC_DCCH_DATA_IND(msg_p).gNB_index, NR_RRC_DCCH_DATA_IND(msg_p).gNB_index,
&NR_RRC_DCCH_DATA_IND(msg_p).msg_integrity); &NR_RRC_DCCH_DATA_IND(msg_p).msg_integrity);
MessageDef *msg = itti_alloc_new_message(TASK_PDCP_UE, 0, NR_RRC_DCCH_DATA_RESP);
itti_send_msg_to_task(TASK_PDCP_UE, rrc->ue_id, msg);
break; break;
case NAS_KENB_REFRESH_REQ: case NAS_KENB_REFRESH_REQ:
......
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