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; ...@@ -100,6 +100,7 @@ pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex; pthread_mutex_t sync_mutex;
int sync_var=-1; //!< protected by mutex \ref sync_mutex. int sync_var=-1; //!< protected by mutex \ref sync_mutex.
int config_sync_var=-1; int config_sync_var=-1;
nr_nas_msg_snssai_t nas_allowed_nssai[8];
// not used in UE // not used in UE
instance_t CUuniqInstance=0; instance_t CUuniqInstance=0;
......
...@@ -464,6 +464,13 @@ typedef ul_info_transfer_cnf_t dl_info_transfer_cnf_t; ...@@ -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 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 * Radio Access Bearer establishment
......
...@@ -82,3 +82,4 @@ MESSAGE_DEF(NRRRC_FRAME_PROCESS, MESSAGE_PRIORITY_MED, NRRrcFramePr ...@@ -82,3 +82,4 @@ MESSAGE_DEF(NRRRC_FRAME_PROCESS, MESSAGE_PRIORITY_MED, NRRrcFramePr
// eNB: RLC -> RRC messages // eNB: RLC -> RRC messages
MESSAGE_DEF(RLC_SDU_INDICATION, MESSAGE_PRIORITY_MED, RlcSduIndication, rlc_sdu_indication) 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 @@ ...@@ -92,6 +92,7 @@
#define NRDuDlReq(mSGpTR) (mSGpTR)->ittiMsg.nr_du_dl_req #define NRDuDlReq(mSGpTR) (mSGpTR)->ittiMsg.nr_du_dl_req
#define NAS_OAI_TUN_NSA(mSGpTR) (mSGpTR)->ittiMsg.nas_oai_tun_nsa #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 { typedef struct RrcStateInd_s {
...@@ -440,6 +441,7 @@ typedef nas_release_ind_t NasConnReleaseInd; ...@@ -440,6 +441,7 @@ typedef nas_release_ind_t NasConnReleaseInd;
typedef ul_info_transfer_cnf_t NasUlDataCnf; typedef ul_info_transfer_cnf_t NasUlDataCnf;
typedef dl_info_transfer_ind_t NasDlDataInd; typedef dl_info_transfer_ind_t NasDlDataInd;
typedef nas_pdu_session_req_t NasPduSessionReq;
// eNB: realtime -> RRC messages // eNB: realtime -> RRC messages
typedef struct rrc_subframe_process_s { typedef struct rrc_subframe_process_s {
protocol_ctxt_t ctxt; protocol_ctxt_t ctxt;
......
...@@ -58,6 +58,8 @@ uint32_t registration_request_len; ...@@ -58,6 +58,8 @@ uint32_t registration_request_len;
extern char *baseNetAddress; extern char *baseNetAddress;
extern uint16_t NB_UE_INST; extern uint16_t NB_UE_INST;
static nr_ue_nas_t nr_ue_nas = {0}; 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( static int nas_protected_security_header_encode(
char *buffer, char *buffer,
...@@ -778,7 +780,7 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi ...@@ -778,7 +780,7 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi
initialNasMsg->data[2 + i] = mac[i]; 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 //wait send RegistrationComplete
usleep(100*150); usleep(100*150);
...@@ -790,11 +792,11 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t * ...@@ -790,11 +792,11 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
uint8_t *req_buffer = malloc(req_length); uint8_t *req_buffer = malloc(req_length);
pdu_session_establishment_request_msg pdu_session_establish; pdu_session_establishment_request_msg pdu_session_establish;
pdu_session_establish.protocoldiscriminator = FGS_SESSION_MANAGEMENT_MESSAGE; 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.pti = 1;
pdu_session_establish.pdusessionestblishmsgtype = FGS_PDU_SESSION_ESTABLISHMENT_REQ; pdu_session_establish.pdusessionestblishmsgtype = FGS_PDU_SESSION_ESTABLISHMENT_REQ;
pdu_session_establish.maxdatarate = 0xffff; 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); 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 * ...@@ -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.length = req_length;
mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.value = req_buffer; mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.value = req_buffer;
size += (2+req_length); 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; mm_msg->uplink_nas_transport.requesttype = 1;
size += 3; 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; const size_t nssai_len = has_nssai_sd ? 4 : 1;
mm_msg->uplink_nas_transport.snssai.length = nssai_len; 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, //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 // but pushed in a itti message to another thread
// this kind of error seems in many places in 5G NAS // 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 = 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) { 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[1] = (pdu_req->sd >> 16) & 0xFF;
mm_msg->uplink_nas_transport.snssai.value[2] = (nas->uicc->nssai_sd >> 8) & 0xFF; mm_msg->uplink_nas_transport.snssai.value[2] = (pdu_req->sd >> 8) & 0xFF;
mm_msg->uplink_nas_transport.snssai.value[3] = (nas->uicc->nssai_sd) & 0xFF; mm_msg->uplink_nas_transport.snssai.value[3] = (pdu_req->sd) & 0xFF;
} }
size += 1 + 1 + nssai_len; size += 1 + 1 + nssai_len;
int dnnSize=strlen(nas->uicc->dnnStr); 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 ...@@ -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); 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) void *nas_nrue_task(void *args_p)
{ {
nr_ue_nas.uicc = checkUicc(0); nr_ue_nas.uicc = checkUicc(0);
...@@ -975,6 +1087,18 @@ void *nas_nrue(void *args_p) ...@@ -975,6 +1087,18 @@ void *nas_nrue(void *args_p)
/* TODO not processed by NAS currently */ /* TODO not processed by NAS currently */
break; 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: { case NAS_CONN_ESTABLI_CNF: {
LOG_I(NAS, LOG_I(NAS,
"[UE %ld] Received %s: errCode %u, length %u\n", "[UE %ld] Received %s: errCode %u, length %u\n",
...@@ -990,6 +1114,7 @@ void *nas_nrue(void *args_p) ...@@ -990,6 +1114,7 @@ void *nas_nrue(void *args_p)
LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n"); LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n");
nr_ue_nas_t *nas = get_ue_nas_info(0); nr_ue_nas_t *nas = get_ue_nas_info(0);
decodeRegistrationAccept(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length, nas); 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}; as_nas_info_t initialNasMsg = {0};
generateRegistrationComplete(nas, &initialNasMsg, NULL); generateRegistrationComplete(nas, &initialNasMsg, NULL);
...@@ -998,12 +1123,7 @@ void *nas_nrue(void *args_p) ...@@ -998,12 +1123,7 @@ void *nas_nrue(void *args_p)
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
} }
as_nas_info_t pduEstablishMsg = {0}; request_default_pdusession(instance);
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");
}
} else if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) { } 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); 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) ...@@ -1081,13 +1201,7 @@ void *nas_nrue(void *args_p)
send_nas_uplink_data_req(instance, &initialNasMsg); send_nas_uplink_data_req(instance, &initialNasMsg);
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
} }
request_default_pdusession(instance);
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");
}
break; break;
case FGS_DEREGISTRATION_ACCEPT: case FGS_DEREGISTRATION_ACCEPT:
LOG_I(NAS, "received deregistration accept\n"); LOG_I(NAS, "received deregistration accept\n");
......
...@@ -171,6 +171,13 @@ typedef struct { ...@@ -171,6 +171,13 @@ typedef struct {
fgs_sm_nas_msg_header_t sm_nas_msg_header; fgs_sm_nas_msg_header_t sm_nas_msg_header;
} dl_nas_transport_t; } 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); 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 generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas);
void *nas_nrue_task(void *args_p); 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