pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/32583 )
Change subject: sm: Implement rx Act PDP Ctx Rej ......................................................................
sm: Implement rx Act PDP Ctx Rej
Change-Id: Ib534ebc2a3a0674675621da2f8bd0de218a08ef0 --- M src/sm/sm.c 1 file changed, 64 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-gprs refs/changes/83/32583/1
diff --git a/src/sm/sm.c b/src/sm/sm.c index 4fa35df..4e07f94 100644 --- a/src/sm/sm.c +++ b/src/sm/sm.c @@ -329,7 +329,8 @@ if (TLVP_PRESENT(&tp, GSM48_IE_GSM_PROTO_CONF_OPT)) { if (TLVP_LEN(&tp, GSM48_IE_GSM_PROTO_CONF_OPT) > ARRAY_SIZE(sme->pco)) { LOGSME(sme, LOGL_ERROR, - "Rx SM Activate PDP Context Accept: PCO size too big! %u\n", qos_len); + "Rx SM Activate PDP Context Accept: PCO size too big! %u\n", + TLVP_LEN(&tp, GSM48_IE_GSM_PROTO_CONF_OPT)); goto rejected; } sme->pco_len = TLVP_LEN(&tp, GSM48_IE_GSM_PROTO_CONF_OPT); @@ -349,6 +350,56 @@ return -EINVAL; /* TODO: what to do on error? */ }
+/* 3GPP TS 24.008 § 9.5.3: Activate PDP Context rej */ +static int gprs_sm_rx_act_pdp_rej(struct gprs_sm_entity *sme, + struct gsm48_hdr *gh, + unsigned int len) +{ + struct tlv_parsed tp; + int rc; + enum gsm48_gsm_cause cause; + uint8_t *ofs = (uint8_t *)gh; + + ofs += sizeof(*gh); + //uint8_t transaction_id = gsm48_hdr_trans_id(gh); + + LOGSME(sme, LOGL_INFO, "Rx SM Activate PDP Context Reject\n"); + + if (len < (ofs + 1) - (uint8_t *)gh) + goto tooshort; + cause = *ofs++; + + if (len > ofs - (uint8_t *)gh) { + rc = gprs_sm_tlv_parse(&tp, ofs, len - (ofs - (uint8_t *)gh)); + if (rc < 0) { + LOGSME(sme, LOGL_ERROR, "Rx SM Activate PDP Context Reject: failed to parse TLVs %d\n", rc); + goto rejected; + } + + if (TLVP_PRESENT(&tp, GSM48_IE_GSM_PROTO_CONF_OPT)) { + if (TLVP_LEN(&tp, GSM48_IE_GSM_PROTO_CONF_OPT) > ARRAY_SIZE(sme->pco)) { + LOGSME(sme, LOGL_ERROR, + "Rx SM Activate PDP Context Reject: PCO size too big! %u\n", + TLVP_LEN(&tp, GSM48_IE_GSM_PROTO_CONF_OPT)); + goto rejected; + } + sme->pco_len = TLVP_LEN(&tp, GSM48_IE_GSM_PROTO_CONF_OPT); + if (sme->pco_len) + memcpy(sme->pco, TLVP_VAL(&tp, GSM48_IE_GSM_PROTO_CONF_OPT), sme->pco_len); + } + } + + rc = osmo_fsm_inst_dispatch(sme->ms_fsm.fi, GPRS_SM_MS_EV_RX_ACT_PDP_CTX_REJ, &cause); + if (rc < 0) + goto rejected; + return rc; + +tooshort: + LOGSME(sme, LOGL_ERROR, "Rx GMM message too short! len=%u\n", len); +rejected: + return -EINVAL; /* TODO: what to do on error? */ +} + /* Rx Session Management PDU */ int gprs_sm_rx(struct gprs_sm_entity *sme, struct gsm48_hdr *gh, unsigned int len) { @@ -362,6 +413,9 @@ case GSM48_MT_GSM_ACT_PDP_ACK: rc = gprs_sm_rx_act_pdp_ack(sme, gh, len); break; + case GSM48_MT_GSM_ACT_PDP_REJ: + rc = gprs_sm_rx_act_pdp_rej(sme, gh, len); + break; default: LOGSME(sme, LOGL_ERROR, "Rx SM message not implemented! type=%u len=%u\n",