Commit 950becb4 authored by Sakthivel Velumani's avatar Sakthivel Velumani

Store allowed NSSAIs from NAS message

Request default PDU session with first NSSAI from the list
parent 82597e7e
......@@ -100,6 +100,7 @@ pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
int config_sync_var=-1;
nr_nas_msg_snssai_t nas_allowed_nssai[8];
// not used in UE
instance_t CUuniqInstance=0;
......
......@@ -464,6 +464,13 @@ typedef ul_info_transfer_cnf_t dl_info_transfer_cnf_t;
*/
typedef ul_info_transfer_ind_t dl_info_transfer_ind_t;
typedef struct nas_pdu_session_req_s {
int pdusession_id;
int pdusession_type;
int sst;
int sd;
} nas_pdu_session_req_t;
/*
* --------------------------------------------------------------------------
* Radio Access Bearer establishment
......
......@@ -82,3 +82,4 @@ MESSAGE_DEF(NRRRC_FRAME_PROCESS, MESSAGE_PRIORITY_MED, NRRrcFramePr
// eNB: RLC -> RRC messages
MESSAGE_DEF(RLC_SDU_INDICATION, MESSAGE_PRIORITY_MED, RlcSduIndication, rlc_sdu_indication)
MESSAGE_DEF(NAS_PDU_SESSION_REQ, MESSAGE_PRIORITY_MED, NasPduSessionReq, nas_pdu_session_req)
......@@ -92,6 +92,7 @@
#define NRDuDlReq(mSGpTR) (mSGpTR)->ittiMsg.nr_du_dl_req
#define NAS_OAI_TUN_NSA(mSGpTR) (mSGpTR)->ittiMsg.nas_oai_tun_nsa
#define NAS_PDU_SESSION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_pdu_session_req
//-------------------------------------------------------------------------------------------//
typedef struct RrcStateInd_s {
......@@ -440,6 +441,7 @@ typedef nas_release_ind_t NasConnReleaseInd;
typedef ul_info_transfer_cnf_t NasUlDataCnf;
typedef dl_info_transfer_ind_t NasDlDataInd;
typedef nas_pdu_session_req_t NasPduSessionReq;
// eNB: realtime -> RRC messages
typedef struct rrc_subframe_process_s {
protocol_ctxt_t ctxt;
......
......@@ -58,6 +58,8 @@ uint32_t registration_request_len;
extern char *baseNetAddress;
extern uint16_t NB_UE_INST;
static nr_ue_nas_t nr_ue_nas = {0};
static nr_ue_nas_t nr_ue_nas;
extern nr_nas_msg_snssai_t nas_allowed_nssai[8];
static int nas_protected_security_header_encode(
char *buffer,
......@@ -778,7 +780,7 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi
initialNasMsg->data[2 + i] = mac[i];
}
static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg)
static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, nas_pdu_session_req_t *pdu_req)
{
//wait send RegistrationComplete
usleep(100*150);
......@@ -790,11 +792,11 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
uint8_t *req_buffer = malloc(req_length);
pdu_session_establishment_request_msg pdu_session_establish;
pdu_session_establish.protocoldiscriminator = FGS_SESSION_MANAGEMENT_MESSAGE;
pdu_session_establish.pdusessionid = 10;
pdu_session_establish.pdusessionid = pdu_req->pdusession_id;
pdu_session_establish.pti = 1;
pdu_session_establish.pdusessionestblishmsgtype = FGS_PDU_SESSION_ESTABLISHMENT_REQ;
pdu_session_establish.maxdatarate = 0xffff;
pdu_session_establish.pdusessiontype = 0x91;
pdu_session_establish.pdusessiontype = pdu_req->pdusession_type;
encode_pdu_session_establishment_request(&pdu_session_establish, req_buffer);
......@@ -827,21 +829,21 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.length = req_length;
mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.value = req_buffer;
size += (2+req_length);
mm_msg->uplink_nas_transport.pdusessionid = 10;
mm_msg->uplink_nas_transport.pdusessionid = pdu_req->pdusession_id;
mm_msg->uplink_nas_transport.requesttype = 1;
size += 3;
const bool has_nssai_sd = nas->uicc->nssai_sd != 0xffffff; // 0xffffff means "no SD", TS 23.003
const bool has_nssai_sd = pdu_req->sd != 0xffffff; // 0xffffff means "no SD", TS 23.003
const size_t nssai_len = has_nssai_sd ? 4 : 1;
mm_msg->uplink_nas_transport.snssai.length = nssai_len;
//Fixme: it seems there are a lot of memory errors in this: this value was on the stack,
// but pushed in a itti message to another thread
// this kind of error seems in many places in 5G NAS
mm_msg->uplink_nas_transport.snssai.value = calloc(1, nssai_len);
mm_msg->uplink_nas_transport.snssai.value[0] = nas->uicc->nssai_sst;
mm_msg->uplink_nas_transport.snssai.value[0] = pdu_req->sst;
if (has_nssai_sd) {
mm_msg->uplink_nas_transport.snssai.value[1] = (nas->uicc->nssai_sd >> 16) & 0xFF;
mm_msg->uplink_nas_transport.snssai.value[2] = (nas->uicc->nssai_sd >> 8) & 0xFF;
mm_msg->uplink_nas_transport.snssai.value[3] = (nas->uicc->nssai_sd) & 0xFF;
mm_msg->uplink_nas_transport.snssai.value[1] = (pdu_req->sd >> 16) & 0xFF;
mm_msg->uplink_nas_transport.snssai.value[2] = (pdu_req->sd >> 8) & 0xFF;
mm_msg->uplink_nas_transport.snssai.value[3] = (pdu_req->sd) & 0xFF;
}
size += 1 + 1 + nssai_len;
int dnnSize=strlen(nas->uicc->dnnStr);
......@@ -912,6 +914,116 @@ static void send_nas_uplink_data_req(instance_t instance, const as_nas_info_t *i
itti_send_msg_to_task(TASK_RRC_NRUE, instance, msg);
}
static void parse_allowed_nssai(nr_nas_msg_snssai_t nssaiList[8], const uint8_t *buf, const uint32_t len)
{
int offset = 0;
int nssai_cnt = 0;
while (offset < len) {
int length = *(buf + offset);
nr_nas_msg_snssai_t *nssai = nssaiList + nssai_cnt;
nssai->sd = 0xFFFFFF;
switch (length) {
case 1:
nssai->sst = *(buf + offset + 1);
offset += 2;
nssai_cnt++;
break;
case 2:
nssai->sst = *(buf + offset + 1);
nssai->hplmn_sst = *(buf + offset + 2);
offset += 3;
nssai_cnt++;
break;
case 4:
nssai->sst = *(buf + offset + 1);
nssai->sd = 0xFFFFFF & (*(buf + offset + 4) | (*(buf + offset + 3) << 8) | (*(buf + offset + 2) << 16));
offset += 5;
nssai_cnt++;
break;
case 5:
nssai->sst = *(buf + offset + 1);
nssai->sd = 0xFFFFFF & (*(buf + offset + 4) | (*(buf + offset + 3) << 8) | (*(buf + offset + 2) << 16));
nssai->hplmn_sst = *(buf + offset + 5);
offset += 6;
nssai_cnt++;
break;
case 8:
nssai->sst = *(buf + offset + 1);
nssai->sd = 0xFFFFFF & (*(buf + offset + 4) | (*(buf + offset + 3) << 8) | (*(buf + offset + 2) << 16));
nssai->hplmn_sst = *(buf + offset + 5);
nssai->hplmn_sd = 0xFFFFFF & (*(buf + offset + 8) | (*(buf + offset + 7) << 8) | (*(buf + offset + 6) << 16));
offset += 9;
nssai_cnt++;
break;
default:
LOG_E(NAS, "UE received unknown length in an allowed S-NSSAI\n");
break;
}
}
}
/* Extract Allowed NSSAI from Regestration Accept according to
3GPP TS 24.501 Table 8.2.7.1.1
*/
static void get_allowed_nssai(nr_nas_msg_snssai_t nssai[8], const uint8_t *pdu_buffer, const uint32_t pdu_length)
{
if ((pdu_buffer == NULL) || (pdu_length <= 0))
return;
int offset = 1 + 1 + 1 + 2; // Mandatory fields offset
if (((nas_msg_header_t *)(pdu_buffer))->choice.security_protected_nas_msg_header_t.security_header_type > 0) {
offset += SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH;
}
bool unknown_IEI_found = false;
/* optional fields */
int length = 0;
while ((offset < pdu_length) && !unknown_IEI_found) {
int type = *(pdu_buffer + offset);
switch (type) {
case 0x77: // 5GS mobile identity
length = (*(pdu_buffer + offset + 1) << 8) | *(pdu_buffer + offset + 2);
offset += (length + 1 + 2); // 1: type, 2: length
break;
case 0x4A: // PLMN list
case 0x54: // 5GS tracking area identity
length = *((uint8_t *)(pdu_buffer + offset + 1));
offset += (length + 1 + 1); // 1: type, 2: length
break;
case 0x15: // allowed NSSAI
length = *((uint8_t *)(pdu_buffer + offset + 1));
parse_allowed_nssai(nssai, pdu_buffer + offset + 2, length);
offset += (length + 1 + 1); // 1: type, 2: length
break;
default:
LOG_E(NAS, "This NAS IEI is not handled when extracting list of allowed NSSAI\n");
unknown_IEI_found = true;
break;
}
}
}
static void request_default_pdusession(int instance)
{
MessageDef *message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_PDU_SESSION_REQ);
NAS_PDU_SESSION_REQ(message_p).pdusession_id = 10; /* first or default pdu session */
NAS_PDU_SESSION_REQ(message_p).pdusession_type = 0x91;
/* take the first allowed S-NSSAI for default PDU session */
NAS_PDU_SESSION_REQ(message_p).sst = nas_allowed_nssai[0].sst;
NAS_PDU_SESSION_REQ(message_p).sd = nas_allowed_nssai[0].sd;
itti_send_msg_to_task(TASK_NAS_NRUE, instance, message_p);
}
void *nas_nrue_task(void *args_p)
{
nr_ue_nas.uicc = checkUicc(0);
......@@ -975,6 +1087,18 @@ void *nas_nrue(void *args_p)
/* TODO not processed by NAS currently */
break;
case NAS_PDU_SESSION_REQ: {
as_nas_info_t pduEstablishMsg = {0};
nas_pdu_session_req_t *pduReq = &NAS_PDU_SESSION_REQ(msg_p);
nr_ue_nas_t *nas = get_ue_nas_info(0);
generatePduSessionEstablishRequest(nas, &pduEstablishMsg, pduReq);
if (pduEstablishMsg.length > 0) {
send_nas_uplink_data_req(instance, &pduEstablishMsg);
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
}
break;
}
case NAS_CONN_ESTABLI_CNF: {
LOG_I(NAS,
"[UE %ld] Received %s: errCode %u, length %u\n",
......@@ -990,6 +1114,7 @@ void *nas_nrue(void *args_p)
LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n");
nr_ue_nas_t *nas = get_ue_nas_info(0);
decodeRegistrationAccept(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length, nas);
get_allowed_nssai(nas_allowed_nssai, pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length);
as_nas_info_t initialNasMsg = {0};
generateRegistrationComplete(nas, &initialNasMsg, NULL);
......@@ -998,12 +1123,7 @@ void *nas_nrue(void *args_p)
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
}
as_nas_info_t pduEstablishMsg = {0};
generatePduSessionEstablishRequest(nas, &pduEstablishMsg);
if (pduEstablishMsg.length > 0) {
send_nas_uplink_data_req(instance, &pduEstablishMsg);
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
}
request_default_pdusession(instance);
} else if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) {
capture_pdu_session_establishment_accept_msg(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length);
}
......@@ -1081,13 +1201,7 @@ void *nas_nrue(void *args_p)
send_nas_uplink_data_req(instance, &initialNasMsg);
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
}
as_nas_info_t pduEstablishMsg = {0};
generatePduSessionEstablishRequest(nas, &pduEstablishMsg);
if (pduEstablishMsg.length > 0) {
send_nas_uplink_data_req(instance, &pduEstablishMsg);
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
}
request_default_pdusession(instance);
break;
case FGS_DEREGISTRATION_ACCEPT:
LOG_I(NAS, "received deregistration accept\n");
......
......@@ -171,6 +171,13 @@ typedef struct {
fgs_sm_nas_msg_header_t sm_nas_msg_header;
} dl_nas_transport_t;
typedef struct {
int sst;
int hplmn_sst;
int sd;
int hplmn_sd;
} nr_nas_msg_snssai_t;
nr_ue_nas_t *get_ue_nas_info(module_id_t module_id);
void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas);
void *nas_nrue_task(void *args_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