pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmocom-bb/+/32973 )
Change subject: layer23: modem: Submit GMMRR-PAGE.ind upon rx of Paging Request Type 1/2/3 ......................................................................
layer23: modem: Submit GMMRR-PAGE.ind upon rx of Paging Request Type 1/2/3
Change-Id: Iee4b5ee5e1e5874b550dd8536b095bf0b5eeb8f4 --- M src/host/layer23/src/modem/grr.c 1 file changed, 172 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/73/32973/1
diff --git a/src/host/layer23/src/modem/grr.c b/src/host/layer23/src/modem/grr.c index 70c6c53..6a287af 100644 --- a/src/host/layer23/src/modem/grr.c +++ b/src/host/layer23/src/modem/grr.c @@ -35,6 +35,8 @@ #include <osmocom/gsm/protocol/gsm_04_08.h> #include <osmocom/gsm/protocol/gsm_08_58.h> #include <osmocom/gprs/rlcmac/rlcmac_prim.h> +#include <osmocom/gprs/rlcmac/csn1_defs.h> +#include <osmocom/gprs/gmm/gmm_prim.h>
#include <osmocom/bb/common/logging.h> #include <osmocom/bb/common/sysinfo.h> @@ -315,6 +317,161 @@ return 0; }
+/* TS 44.018 3.3.2.1.1: +* It is used when sending paging information to a mobile station in packet idle mode, if PCCCH is not present in the cell. +* If the mobile station in packet idle mode is identified by its IMSI, it shall parse the message for a corresponding Packet +* Page Indication field: +* - if the Packet Page Indication field indicates a packet paging procedure, the mobile station shall proceed as +* specified in sub-clause 3.5.1.2. +* 3.5.1.2 "On receipt of a packet paging request": +* On the receipt of a paging request message, the RR sublayer of addressed mobile station indicates the receipt of a +* paging request to the MM sublayer, see 3GPP TS 24.007. +*/ +/* TS 44.018 9.1.22 "Paging request type 1" */ +static int grr_rx_pag_req_1(struct osmocom_ms *ms, struct msgb *msg) +{ + struct gsm48_paging1 *pag = msgb_l3(msg); + (void)pag; + uint8_t len; + uint8_t *buf = pag->data; + int rc; + struct osmo_mobile_identity mi1 = {}; /* GSM_MI_TYPE_NONE */ + struct osmo_mobile_identity mi2 = {}; /* GSM_MI_TYPE_NONE */ + P1_Rest_Octets_t p1ro = {}; + unsigned p1_rest_oct_len; + struct osmo_gprs_gmm_prim *gmm_prim; + /* TS 44.018 3.3.2.1.1: + * It is used when sending paging information to a mobile station in + * packet idle mode, if PCCCH is not present in the cell. + * If the mobile station in packet idle mode is identified by its IMSI, it shall parse the message for a corresponding Packet + * Page Indication field: + * - if the Packet Page Indication field indicates a packet paging procedure, the mobile station shall proceed as + * specified in sub-clause 3.5.1.2. + * 3.5.1.2 "On receipt of a packet paging request": + * On the receipt of a paging request message, the RR sublayer of addressed mobile station indicates the receipt of a + * paging request to the MM sublayer, see 3GPP TS 24.007. + */ + + /* TODO: skip messages outside paging group? (3GPP TS 45.002) */ + + LOGP(DRR, LOGL_NOTICE, "Rx Paging Request Type 1\n"); + + if (msgb_l3len(msg) < sizeof(*pag)) + return -EBADMSG; + + /* The L2 pseudo length of this message is the sum of lengths of all + * information elements present in the message except the P1 Rest Octets and L2 + * Pseudo Length information elements. */ + if (pag->l2_plen == msgb_l3len(msg) - sizeof(pag->l2_plen)) { + /* no P1 Rest Octets => no Packet Page Indication => Discard */ + return 0; + } + + if (msgb_l3len(msg) < sizeof(*pag) + 1) + return -EBADMSG; + len = *buf; + buf++; + + if (msgb_l3len(msg) < sizeof(*pag) + 1 + len) + return -EBADMSG; + + if ((rc = osmo_mobile_identity_decode(&mi1, buf, len, false)) < 0) + return rc; + buf += len; + + if (msgb_l3len(msg) < (buf - (uint8_t *)pag) + 1) { + /* No MI2 and no P1 Rest Octets => no Packet Page Indication => Discard */ + return 0; + } + + if (*buf == GSM48_IE_MOBILE_ID) { + buf++; + if (msgb_l3len(msg) < (buf - (uint8_t *)pag) + 1) + return -EBADMSG; + len = *buf; + buf++; + if (msgb_l3len(msg) < (buf - (uint8_t *)pag) + len) + return -EBADMSG; + if ((rc = osmo_mobile_identity_decode(&mi2, buf, len, false)) < 0) + return rc; + buf += len; + } + + p1_rest_oct_len = msgb_l3len(msg) - (buf - (uint8_t *)pag); + if (p1_rest_oct_len == 0) { + /*No P1 Rest Octets => no Packet Page Indication => Discard */ + return 0; + } + + rc = osmo_gprs_rlcmac_decode_p1ro(&p1ro, buf, p1_rest_oct_len); + if (rc != 0) { + LOGP(DRR, LOGL_ERROR, "Failed to parse P1 Rest Octets\n"); + return rc; + } + + if (p1ro.Packet_Page_Indication_1 == 1) { /* for GPRS*/ + switch (mi1.type) { + case GSM_MI_TYPE_IMSI: + if (strcmp(mi1.imsi, ms->subscr.imsi) == 0) + goto tx_page_ind; + break; + case GSM_MI_TYPE_TMSI: + if (mi1.tmsi == ms->subscr.gprs.ptmsi) + goto tx_page_ind; + break; + default: + return -EINVAL; + } + } + + if (p1ro.Packet_Page_Indication_2 == 1) { /* for GPRS*/ + switch (mi2.type) { + case GSM_MI_TYPE_IMSI: + if (strcmp(mi2.imsi, ms->subscr.imsi) == 0) + goto tx_page_ind; + break; + case GSM_MI_TYPE_TMSI: + if (mi2.tmsi == ms->subscr.gprs.ptmsi) + goto tx_page_ind; + break; + default: + return -EINVAL; + } + } + + return rc; + +tx_page_ind: + /* TODO: convert IMSI/PTMSI -> TLLI using some cached values from GMM layers */ + uint32_t tlli = 0; + /* TS 24.007 C.13: Submit GMMRR-PAGE.ind: */ + gmm_prim = osmo_gprs_gmm_prim_alloc_gmmrr_page_ind(tlli); + rc = osmo_gprs_gmm_prim_lower_up(gmm_prim); + return rc; +} + +static int grr_rx_pag_req_2(struct osmocom_ms *ms, struct msgb *msg) +{ + struct gsm48_paging2 *pag = msgb_l3(msg); + (void)pag; + + /* TODO: skip messages outside paging group? (3GPP TS 45.002) */ + + LOGP(DRR, LOGL_NOTICE, "Rx Paging Request Type 2\n"); + return 0; +} + +static int grr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg) +{ + struct gsm48_paging3 *pag = msgb_l3(msg); + (void)pag; + + /* TODO: skip messages outside paging group? (3GPP TS 45.002) */ + + LOGP(DRR, LOGL_ERROR, "Rx Paging Request Type 3: TODO Cell Update\n"); + return 0; +} + /* Dummy Paging Request 1 with "no identity" */ static const uint8_t paging_fill[] = { 0x15, 0x06, 0x21, 0x00, 0x01, 0xf0, 0x2b, @@ -363,6 +520,12 @@ switch (sih->system_information) { case GSM48_MT_RR_IMM_ASS: return grr_rx_imm_ass(ms, msg); + case GSM48_MT_RR_PAG_REQ_1: + return grr_rx_pag_req_1(ms, msg); + case GSM48_MT_RR_PAG_REQ_2: + return grr_rx_pag_req_2(ms, msg); + case GSM48_MT_RR_PAG_REQ_3: + return grr_rx_pag_req_3(ms, msg); default: return 0; }