Remove harcoded Slice Differentiator (SD) in NAS decode_nssai_ie and update the processing logic
The SD stored in the allowed S-NSSAI list was hardcoded in the decoding function, however this IE is not mandatory but optional, therefore the check of the decoded message contents should take into account this and check the stored value against the one from the UICC only when the field is present. If no SD was received, consider the UICC SD a valid one. Also, add free function to Registration Accept library and adopt in stack to free NAS Registration Accept after use: heap memory is allocated for this message during decoding and shall be free after processing.
This commit is contained in:
@@ -79,7 +79,6 @@ static int decode_nssai_ie(nr_nas_msg_snssai_t *nssai, uint8_t *num_slices, uint
|
||||
const uint8_t *end = buf + length;
|
||||
while (buf < end) {
|
||||
nr_nas_msg_snssai_t *item = nssai + nssai_cnt;
|
||||
item->sd = 0xffffff;
|
||||
const int item_len = *buf++; // Length of S-NSSAI IE item
|
||||
switch (item_len) {
|
||||
case 1:
|
||||
@@ -89,31 +88,38 @@ static int decode_nssai_ie(nr_nas_msg_snssai_t *nssai, uint8_t *num_slices, uint
|
||||
|
||||
case 2:
|
||||
item->sst = *buf++;
|
||||
item->hplmn_sst = *buf++;
|
||||
item->hplmn_sst = malloc_or_fail(sizeof(*item->hplmn_sst));
|
||||
*item->hplmn_sst = *buf++;
|
||||
nssai_cnt++;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
item->sst = *buf++;
|
||||
item->sd = 0xffffff & ntoh_int24_buf(buf);
|
||||
item->sd = malloc_or_fail(sizeof(*item->sd));
|
||||
*item->sd = 0xffffff & ntoh_int24_buf(buf);
|
||||
buf += 3;
|
||||
nssai_cnt++;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
item->sst = *buf++;
|
||||
item->sd = 0xffffff & ntoh_int24_buf(buf);
|
||||
item->sd = malloc_or_fail(sizeof(*item->sd));
|
||||
*item->sd = 0xffffff & ntoh_int24_buf(buf);
|
||||
buf += 3;
|
||||
item->hplmn_sst = *buf++;
|
||||
item->hplmn_sst = malloc_or_fail(sizeof(*item->hplmn_sst));
|
||||
*item->hplmn_sst = *buf++;
|
||||
nssai_cnt++;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
item->sst = *buf++;
|
||||
item->sd = 0xffffff & ntoh_int24_buf(buf);
|
||||
item->sd = malloc_or_fail(sizeof(*item->sd));
|
||||
*item->sd = 0xffffff & ntoh_int24_buf(buf);
|
||||
buf += 3;
|
||||
item->hplmn_sst = *buf++;
|
||||
item->hplmn_sd = 0xffffff & ntoh_int24_buf(buf);
|
||||
item->hplmn_sst = malloc_or_fail(sizeof(*item->hplmn_sst));
|
||||
*item->hplmn_sst = *buf++;
|
||||
item->hplmn_sd = malloc_or_fail(sizeof(*item->hplmn_sd));
|
||||
*item->hplmn_sd = 0xffffff & ntoh_int24_buf(buf);
|
||||
buf += 3;
|
||||
nssai_cnt++;
|
||||
break;
|
||||
@@ -198,3 +204,21 @@ int encode_registration_accept(const registration_accept_msg *registration_accep
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
/** Memory management of NAS Registration Accept */
|
||||
|
||||
static void free_nssai(nr_nas_msg_snssai_t *msg)
|
||||
{
|
||||
free(msg->hplmn_sd);
|
||||
free(msg->hplmn_sst);
|
||||
free(msg->sd);
|
||||
}
|
||||
|
||||
void free_fgmm_registration_accept(registration_accept_msg *msg)
|
||||
{
|
||||
free(msg->guti);
|
||||
for (int i = 0; i < NAS_MAX_NUMBER_SLICES; i++) {
|
||||
free_nssai(&msg->nas_allowed_nssai[i]);
|
||||
free_nssai(&msg->config_nssai[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,9 +51,9 @@ typedef enum {
|
||||
// 9.11.3.37 of 3GPP TS 24.501
|
||||
typedef struct {
|
||||
int sst;
|
||||
int hplmn_sst;
|
||||
int sd;
|
||||
int hplmn_sd;
|
||||
int *hplmn_sst;
|
||||
int *sd;
|
||||
int *hplmn_sd;
|
||||
} nr_nas_msg_snssai_t;
|
||||
|
||||
/*
|
||||
@@ -81,4 +81,6 @@ size_t decode_registration_accept(registration_accept_msg *registrationaccept, c
|
||||
|
||||
int encode_registration_accept(const registration_accept_msg *registrationaccept, uint8_t *buffer, uint32_t len);
|
||||
|
||||
void free_fgmm_registration_accept(registration_accept_msg *msg);
|
||||
|
||||
#endif /* ! defined(REGISTRATION_ACCEPT_H_) */
|
||||
|
||||
@@ -1410,11 +1410,14 @@ static void request_default_pdusession(nr_ue_nas_t *nas)
|
||||
itti_send_msg_to_task(TASK_NAS_NRUE, nas->UE_id, message_p);
|
||||
}
|
||||
|
||||
static int get_user_nssai_idx(const nr_nas_msg_snssai_t allowed_nssai[8], const nr_ue_nas_t *nas)
|
||||
static int get_user_nssai_idx(const nr_nas_msg_snssai_t allowed_nssai[NAS_MAX_NUMBER_SLICES], const nr_ue_nas_t *nas)
|
||||
{
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int i = 0; i < NAS_MAX_NUMBER_SLICES; i++) {
|
||||
const nr_nas_msg_snssai_t *nssai = allowed_nssai + i;
|
||||
if ((nas->uicc->nssai_sst == nssai->sst) && (nas->uicc->nssai_sd == nssai->sd))
|
||||
/* If it was received in Registration Accept, check the SD
|
||||
in the stored Allowed N-SSAI, else, consider the SD valid */
|
||||
bool sd_match = !nssai->sd || (nas->uicc->nssai_sd == *nssai->sd);
|
||||
if ((nas->uicc->nssai_sst == nssai->sst) && sd_match)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
@@ -1476,7 +1479,6 @@ static void handle_registration_accept(nr_ue_nas_t *nas, const uint8_t *pdu_buff
|
||||
// process GUTI
|
||||
if (msg.guti) {
|
||||
process_guti(&msg.guti->guti, nas);
|
||||
free(msg.guti);
|
||||
} else {
|
||||
LOG_W(NAS, "no GUTI in registration accept\n");
|
||||
}
|
||||
@@ -1495,6 +1497,8 @@ static void handle_registration_accept(nr_ue_nas_t *nas, const uint8_t *pdu_buff
|
||||
} else {
|
||||
request_default_pdusession(nas);
|
||||
}
|
||||
// Free local message after processing
|
||||
free_fgmm_registration_accept(&msg);
|
||||
}
|
||||
|
||||
/* 3GPP TS 24.008 10.5.7.3 GPRS Timer */
|
||||
|
||||
Reference in New Issue
Block a user