mirror of
https://github.com/open5gs/open5gs.git
synced 2025-10-23 07:41:57 +00:00
[MME] SGsAP: Implement initial Rx of ALERT-REQUEST
Answer ALERT-REQUEST with either ALERT-ACK or ALERT-REJECT. This commit leaves unimplemented (to be implemented in the future) the part regarding setting of internal NEAF flag for UE inside MME and then triggering SGsAP-UE-ACTIVITY-INDICATION towards VLR. See 3GPP TS 23.272 and 3GPP TS 29.118 (grep for "Alert" and "Activity") for further information.
This commit is contained in:
committed by
Sukchan Lee
parent
a8eec6e9e6
commit
606877bf11
@@ -91,6 +91,7 @@ ogs_pkbuf_t *sgsap_build_location_update_request(mme_ue_t *mme_ue)
|
||||
|
||||
return pkbuf;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *sgsap_build_tmsi_reallocation_complete(mme_ue_t *mme_ue)
|
||||
{
|
||||
mme_csmap_t *csmap = NULL;
|
||||
@@ -124,6 +125,96 @@ ogs_pkbuf_t *sgsap_build_tmsi_reallocation_complete(mme_ue_t *mme_ue)
|
||||
return pkbuf;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *sgsap_build_ue_activity_indication(mme_ue_t *mme_ue)
|
||||
{
|
||||
ogs_tlv_t *root = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
|
||||
root = ogs_tlv_add(NULL, OGS_TLV_MODE_T1_L1, SGSAP_IE_IMSI_TYPE,
|
||||
SGSAP_IE_IMSI_LEN, 0, &mme_ue->nas_mobile_identity_imsi);
|
||||
|
||||
/* TODO: Maximum UE Availability Time */
|
||||
|
||||
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
|
||||
if (!pkbuf) {
|
||||
ogs_error("ogs_pkbuf_alloc() failed");
|
||||
ogs_tlv_free_all(root);
|
||||
return NULL;
|
||||
}
|
||||
ogs_pkbuf_put_u8(pkbuf, SGSAP_UE_ACTIVITY_INDICATION);
|
||||
ogs_pkbuf_put(pkbuf, OGS_MAX_SDU_LEN-1);
|
||||
|
||||
ogs_pkbuf_trim(pkbuf, 1+ogs_tlv_render(root,
|
||||
pkbuf->data+1, OGS_MAX_SDU_LEN-1));
|
||||
|
||||
ogs_tlv_free_all(root);
|
||||
|
||||
return pkbuf;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *sgsap_build_alert_ack(mme_ue_t *mme_ue)
|
||||
{
|
||||
ogs_tlv_t *root = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
|
||||
root = ogs_tlv_add(NULL, OGS_TLV_MODE_T1_L1, SGSAP_IE_IMSI_TYPE,
|
||||
SGSAP_IE_IMSI_LEN, 0, &mme_ue->nas_mobile_identity_imsi);
|
||||
|
||||
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
|
||||
if (!pkbuf) {
|
||||
ogs_error("ogs_pkbuf_alloc() failed");
|
||||
ogs_tlv_free_all(root);
|
||||
return NULL;
|
||||
}
|
||||
ogs_pkbuf_put_u8(pkbuf, SGSAP_ALERT_ACK);
|
||||
ogs_pkbuf_put(pkbuf, OGS_MAX_SDU_LEN-1);
|
||||
|
||||
ogs_pkbuf_trim(pkbuf, 1+ogs_tlv_render(root,
|
||||
pkbuf->data+1, OGS_MAX_SDU_LEN-1));
|
||||
|
||||
ogs_tlv_free_all(root);
|
||||
|
||||
return pkbuf;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *sgsap_build_alert_reject(
|
||||
ogs_nas_mobile_identity_imsi_t *nas_mobile_identity_imsi,
|
||||
int nas_mobile_identity_imsi_len, uint8_t sgs_cause)
|
||||
{
|
||||
ogs_tlv_t *root = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
ogs_assert(nas_mobile_identity_imsi);
|
||||
ogs_assert(nas_mobile_identity_imsi_len == SGSAP_IE_IMSI_LEN);
|
||||
|
||||
root = ogs_tlv_add(NULL, OGS_TLV_MODE_T1_L1,
|
||||
SGSAP_IE_IMSI_TYPE, SGSAP_IE_IMSI_LEN, 0, nas_mobile_identity_imsi);
|
||||
ogs_tlv_add(root, OGS_TLV_MODE_T1_L1,
|
||||
SGSAP_IE_SGS_CAUSE_TYPE, SGSAP_IE_SGS_CAUSE_LEN, 0, &sgs_cause);
|
||||
|
||||
ogs_debug(" CAUSE[%d]", sgs_cause);
|
||||
|
||||
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
|
||||
if (!pkbuf) {
|
||||
ogs_error("ogs_pkbuf_alloc() failed");
|
||||
ogs_tlv_free_all(root);
|
||||
return NULL;
|
||||
}
|
||||
ogs_pkbuf_put_u8(pkbuf, SGSAP_ALERT_REJECT);
|
||||
ogs_pkbuf_put(pkbuf, OGS_MAX_SDU_LEN-1);
|
||||
|
||||
ogs_pkbuf_trim(pkbuf, 1+ogs_tlv_render(root,
|
||||
pkbuf->data+1, OGS_MAX_SDU_LEN-1));
|
||||
|
||||
ogs_tlv_free_all(root);
|
||||
|
||||
return pkbuf;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *sgsap_build_detach_indication(mme_ue_t *mme_ue)
|
||||
{
|
||||
mme_csmap_t *csmap = NULL;
|
||||
|
@@ -30,6 +30,11 @@ extern "C" {
|
||||
|
||||
ogs_pkbuf_t *sgsap_build_location_update_request(mme_ue_t *mme_ue);
|
||||
ogs_pkbuf_t *sgsap_build_tmsi_reallocation_complete(mme_ue_t *mme_ue);
|
||||
ogs_pkbuf_t *sgsap_build_ue_activity_indication(mme_ue_t *mme_ue);
|
||||
ogs_pkbuf_t *sgsap_build_alert_ack(mme_ue_t *mme_ue);
|
||||
ogs_pkbuf_t *sgsap_build_alert_reject(
|
||||
ogs_nas_mobile_identity_imsi_t *nas_mobile_identity_imsi,
|
||||
int nas_mobile_identity_imsi_len, uint8_t sgs_cause);
|
||||
ogs_pkbuf_t *sgsap_build_detach_indication(mme_ue_t *mme_ue);
|
||||
ogs_pkbuf_t *sgsap_build_mo_csfb_indication(mme_ue_t *mme_ue);
|
||||
ogs_pkbuf_t *sgsap_build_paging_reject(
|
||||
|
@@ -405,6 +405,98 @@ error:
|
||||
return;
|
||||
}
|
||||
|
||||
void sgsap_handle_alert_request(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
|
||||
{
|
||||
ogs_tlv_t *root = NULL, *iter = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
uint8_t sgs_cause = SGSAP_SGS_CAUSE_IMSI_UNKNOWN;
|
||||
|
||||
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1] = {0, };
|
||||
|
||||
ogs_nas_mobile_identity_imsi_t *nas_mobile_identity_imsi = NULL;
|
||||
int nas_mobile_identity_imsi_len = 0;
|
||||
|
||||
ogs_assert(vlr);
|
||||
ogs_assert(pkbuf);
|
||||
|
||||
ogs_warn("[SGSAP] Rx ALERT-REQUEST");
|
||||
|
||||
ogs_pkbuf_pull(pkbuf, 1);
|
||||
|
||||
root = ogs_tlv_parse_block(pkbuf->len, pkbuf->data, OGS_TLV_MODE_T1_L1);
|
||||
if (!root) {
|
||||
ogs_error("ogs_tlv_parse_block() failed");
|
||||
sgs_cause = SGSAP_SGS_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE;
|
||||
goto alert_reject;
|
||||
}
|
||||
|
||||
iter = root;
|
||||
while (iter) {
|
||||
switch (iter->type) {
|
||||
case SGSAP_IE_IMSI_TYPE:
|
||||
nas_mobile_identity_imsi = iter->value;
|
||||
nas_mobile_identity_imsi_len = iter->length;
|
||||
break;
|
||||
default:
|
||||
ogs_warn("Invalid Type [%d]", iter->type);
|
||||
break;
|
||||
}
|
||||
iter = iter->next;
|
||||
}
|
||||
|
||||
ogs_tlv_free_all(root);
|
||||
|
||||
if (!nas_mobile_identity_imsi) {
|
||||
ogs_error("No IMSI");
|
||||
sgs_cause = SGSAP_SGS_CAUSE_MISSING_MANDATORY_IE;
|
||||
goto alert_reject;
|
||||
}
|
||||
if (nas_mobile_identity_imsi_len != SGSAP_IE_IMSI_LEN) {
|
||||
ogs_error("Invalid IMSI len [%d]", nas_mobile_identity_imsi_len);
|
||||
sgs_cause = SGSAP_SGS_CAUSE_INVALID_MANDATORY_IE;
|
||||
goto alert_reject;
|
||||
}
|
||||
|
||||
if (nas_mobile_identity_imsi->type != OGS_NAS_MOBILE_IDENTITY_IMSI) {
|
||||
ogs_error("nas_mobile_identity_imsi->type == "
|
||||
"OGS_NAS_MOBILE_IDENTITY_IMSI");
|
||||
sgs_cause = SGSAP_SGS_CAUSE_INVALID_MANDATORY_IE;
|
||||
goto alert_reject;
|
||||
}
|
||||
|
||||
ogs_nas_eps_imsi_to_bcd(nas_mobile_identity_imsi,
|
||||
nas_mobile_identity_imsi_len, imsi_bcd);
|
||||
mme_ue = mme_ue_find_by_imsi_bcd(imsi_bcd);
|
||||
|
||||
if (!mme_ue) {
|
||||
ogs_error("No UE(mme-ue) context");
|
||||
sgs_cause = SGSAP_SGS_CAUSE_IMSI_UNKNOWN;
|
||||
goto alert_reject;
|
||||
}
|
||||
|
||||
/* TODO: Set NEAF flag in UE */
|
||||
|
||||
ogs_warn("[SGSAP] Tx ALERT-ACK");
|
||||
|
||||
sgsap_send_to_vlr_with_sid(
|
||||
vlr,
|
||||
sgsap_build_alert_ack(mme_ue),
|
||||
0);
|
||||
return;
|
||||
|
||||
alert_reject:
|
||||
ogs_debug("[SGSAP] Tx ALERT-REJECT");
|
||||
ogs_debug(" IMSI[%s]", imsi_bcd);
|
||||
|
||||
sgsap_send_to_vlr_with_sid(
|
||||
vlr,
|
||||
sgsap_build_alert_reject(
|
||||
nas_mobile_identity_imsi, nas_mobile_identity_imsi_len,
|
||||
sgs_cause),
|
||||
0);
|
||||
return;
|
||||
}
|
||||
|
||||
void sgsap_handle_detach_ack(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
|
||||
{
|
||||
ogs_tlv_t *root = NULL, *iter = NULL;
|
||||
|
@@ -28,6 +28,7 @@ extern "C" {
|
||||
|
||||
void sgsap_handle_location_update_accept(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
|
||||
void sgsap_handle_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
|
||||
void sgsap_handle_alert_request(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
|
||||
void sgsap_handle_detach_ack(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
|
||||
void sgsap_handle_paging_request(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
|
||||
void sgsap_handle_downlink_unitdata(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
|
||||
|
@@ -150,6 +150,26 @@ int sgsap_send_tmsi_reallocation_complete(mme_ue_t *mme_ue)
|
||||
return rv;
|
||||
}
|
||||
|
||||
int sgsap_send_ue_activity_indication(mme_ue_t *mme_ue)
|
||||
{
|
||||
int rv;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
ogs_assert(mme_ue);
|
||||
|
||||
ogs_debug("[SGSAP] Tx UE-ACTIVITY-IND");
|
||||
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
|
||||
|
||||
pkbuf = sgsap_build_ue_activity_indication(mme_ue);
|
||||
if (!pkbuf) {
|
||||
ogs_error("sgsap_build_tmsi_reallocation_complete() failed");
|
||||
return OGS_ERROR;
|
||||
}
|
||||
rv = sgsap_send_to_vlr(mme_ue, pkbuf);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int sgsap_send_detach_indication(mme_ue_t *mme_ue)
|
||||
{
|
||||
int rv;
|
||||
|
@@ -44,6 +44,7 @@ int sgsap_send_to_vlr(mme_ue_t *mme_ue, ogs_pkbuf_t *pkbuf);
|
||||
|
||||
int sgsap_send_location_update_request(mme_ue_t *mme_ue);
|
||||
int sgsap_send_tmsi_reallocation_complete(mme_ue_t *mme_ue);
|
||||
int sgsap_send_ue_activity_indication(mme_ue_t *mme_ue);
|
||||
int sgsap_send_detach_indication(mme_ue_t *mme_ue);
|
||||
int sgsap_send_mo_csfb_indication(mme_ue_t *mme_ue);
|
||||
int sgsap_send_paging_reject(mme_ue_t *mme_ue, uint8_t sgs_cause);
|
||||
|
@@ -153,6 +153,9 @@ void sgsap_state_connected(ogs_fsm_t *s, mme_event_t *e)
|
||||
case SGSAP_LOCATION_UPDATE_REJECT:
|
||||
sgsap_handle_location_update_reject(vlr, pkbuf);
|
||||
break;
|
||||
case SGSAP_ALERT_REQUEST:
|
||||
sgsap_handle_alert_request(vlr, pkbuf);
|
||||
break;
|
||||
case SGSAP_EPS_DETACH_ACK:
|
||||
case SGSAP_IMSI_DETACH_ACK:
|
||||
sgsap_handle_detach_ack(vlr, pkbuf);
|
||||
|
@@ -33,6 +33,10 @@ extern "C" {
|
||||
#define SGSAP_LOCATION_UPDATE_ACCEPT 10
|
||||
#define SGSAP_LOCATION_UPDATE_REJECT 11
|
||||
#define SGSAP_TMSI_REALLOCATION_COMPLETE 12
|
||||
#define SGSAP_ALERT_REQUEST 13
|
||||
#define SGSAP_ALERT_ACK 14
|
||||
#define SGSAP_ALERT_REJECT 15
|
||||
#define SGSAP_UE_ACTIVITY_INDICATION 16
|
||||
#define SGSAP_EPS_DETACH_INDICATION 17
|
||||
#define SGSAP_EPS_DETACH_ACK 18
|
||||
#define SGSAP_IMSI_DETACH_INDICATION 19
|
||||
|
Reference in New Issue
Block a user