pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/32581 )
Change subject: gmm: Implement GMMSM-UNITDATA.ind ......................................................................
gmm: Implement GMMSM-UNITDATA.ind
Change-Id: Ib1ac220292c61419a65f27fa88a731357728459d --- M include/osmocom/gprs/gmm/gmm_private.h M src/gmm/gmm.c M src/gmm/gmm_prim.c M tests/gmm/gmm_prim_test.c M tests/gmm/gmm_prim_test.err M tests/gmm/gmm_prim_test.ok 6 files changed, 91 insertions(+), 9 deletions(-)
Approvals: Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve pespin: Looks good to me, approved
diff --git a/include/osmocom/gprs/gmm/gmm_private.h b/include/osmocom/gprs/gmm/gmm_private.h index 6abf3be..df97e1d 100644 --- a/include/osmocom/gprs/gmm/gmm_private.h +++ b/include/osmocom/gprs/gmm/gmm_private.h @@ -106,6 +106,7 @@ struct gprs_gmm_entity *gprs_gmm_find_gmme_by_ptmsi(uint32_t ptmsi); struct gprs_gmm_entity *gprs_gmm_find_gmme_by_imsi(const char *imsi); struct gprs_gmm_entity *gprs_gmm_find_gmme_by_tlli(uint32_t tlli); +struct gprs_gmm_entity *gprs_gmm_find_gmme_by_sess_id(uint32_t id); uint32_t gprs_gmm_alloc_rand_tlli(void); int gprs_gmm_rx(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len); int gprs_gmm_tx_att_req(struct gprs_gmm_entity *gmme, diff --git a/src/gmm/gmm.c b/src/gmm/gmm.c index 980f8f4..0070dda 100644 --- a/src/gmm/gmm.c +++ b/src/gmm/gmm.c @@ -236,6 +236,17 @@ return NULL; }
+struct gprs_gmm_entity *gprs_gmm_find_gmme_by_sess_id(uint32_t id) +{ + struct gprs_gmm_entity *gmme; + + llist_for_each_entry(gmme, &g_gmm_ctx->gmme_list, list) { + if (gmme->sess_id == id) + return gmme; + } + return NULL; +} + uint32_t gprs_gmm_alloc_rand_tlli(void) { /* 3GPP TS 23.003 Table 1: Type of TLLI = Random TLLI_ @@ -754,10 +765,6 @@ int gprs_gmm_rx(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len) { int rc = 0; - if (len < sizeof(struct gsm48_hdr)) { - LOGGMME(gmme, LOGL_ERROR, "Rx GMM message too short! len=%u\n", len); - return -EINVAL; - }
switch (gh->msg_type) { case GSM48_MT_GMM_ATTACH_ACK: diff --git a/src/gmm/gmm_prim.c b/src/gmm/gmm_prim.c index 8f8d218..573b568 100644 --- a/src/gmm/gmm_prim.c +++ b/src/gmm/gmm_prim.c @@ -508,10 +508,29 @@ /* TS 24.007 9.5.1.5 GMMSM-Unitdata.request:*/ static int gprs_gmm_prim_handle_gmmsm_unitdata_req(struct osmo_gprs_gmm_prim *gmm_prim) { + struct osmo_gprs_llc_prim *llc_prim; int rc; + struct gprs_gmm_entity *gmme;
- rc = gprs_gmm_prim_handle_unsupported(gmm_prim); + gmme = gprs_gmm_find_gmme_by_sess_id(gmm_prim->gmmsm.sess_id); + if (!gmme) { + LOGGMM(LOGL_ERROR, "No GMME with sess_id=%u found\n", + gmm_prim->gmmsm.sess_id); + return -ENOENT; + }
+ llc_prim = osmo_gprs_llc_prim_alloc_ll_unitdata_req( + gmme->tlli, OSMO_GPRS_LLC_SAPI_GMM, + gmm_prim->gmmsm.unitdata_req.smpdu, + gmm_prim->gmmsm.unitdata_req.smpdu_len); + llc_prim->ll.unitdata_req.radio_prio = gmme->radio_prio; + /* TODO: + llc_prim->ll.qos_params[3]; + llc_prim->ll.apply_gea; + llc_prim->ll.apply_gia; + */ + + rc = gprs_gmm_prim_call_llc_down_cb(llc_prim); return rc; }
@@ -660,15 +679,39 @@ { struct gprs_gmm_entity *gmme; int rc = 0; + struct gsm48_hdr *gh = (struct gsm48_hdr *)llc_prim->ll.l3_pdu; + unsigned int len = llc_prim->ll.l3_pdu_len; + uint8_t pdisc; + struct osmo_gprs_gmm_prim *gmm_prim; + gmme = gprs_gmm_find_gmme_by_tlli(llc_prim->ll.tlli); if (!gmme) { LOGGMM(LOGL_NOTICE, "Rx %s: Unknown TLLI 0x%08x\n", osmo_gprs_llc_prim_name(llc_prim), llc_prim->ll.tlli); return -ENOENT; } - rc = gprs_gmm_rx(gmme, - (struct gsm48_hdr *)llc_prim->ll.l3_pdu, - llc_prim->ll.l3_pdu_len); + + if (len < sizeof(struct gsm48_hdr)) { + LOGGMME(gmme, LOGL_ERROR, "Rx GMM message too short! len=%u\n", len); + return -EINVAL; + } + + pdisc = gsm48_hdr_pdisc(gh); + + switch (pdisc) { + case GSM48_PDISC_MM_GPRS: + rc = gprs_gmm_rx(gmme, gh, len); + break; + case GSM48_PDISC_SM_GPRS: + /* Forward up to SM layer: */ + gmm_prim = gprs_gmm_prim_alloc_gmmsm_unitdata_ind(gmme->sess_id, + (uint8_t *)gh, + len); + rc = gprs_gmm_prim_call_up_cb(gmm_prim); + break; + default: + OSMO_ASSERT(0); + }
return rc; } diff --git a/tests/gmm/gmm_prim_test.c b/tests/gmm/gmm_prim_test.c index acf1e22..7bc02b0 100644 --- a/tests/gmm/gmm_prim_test.c +++ b/tests/gmm/gmm_prim_test.c @@ -204,6 +204,12 @@ gmm_prim->gmmsm.establish_cnf.accepted, gmm_prim->gmmsm.establish_cnf.rej.cause); break; + case OSMO_PRIM(OSMO_GPRS_GMM_GMMSM_UNITDATA, PRIM_OP_INDICATION): + printf("%s(): Rx %s sess_id=%u sm_pdu=%s\n", __func__, pdu_name, + gmm_prim->gmmsm.sess_id, + osmo_hexdump(gmm_prim->gmmsm.unitdata_ind.smpdu, + gmm_prim->gmmsm.unitdata_ind.smpdu_len)); + break; //case OSMO_PRIM(OSMO_GPRS_GMM_GMMSM_DETACH, PRIM_OP_CONFIRM): // printf("%s(): Rx %s detach_type='%s'\n", __func__, pdu_name, // osmo_gprs_gmm_detach_ms_type_name(gmm_prim->gmmsm.detach_cnf.detach_type)); @@ -355,6 +361,7 @@ char *imei = "42342342342342"; char *imeisv = "4234234234234275"; uint32_t sess_id = 1234; + uint8_t sm_pdu[] = {GSM48_PDISC_SM_GPRS, 0x28, 0x29, 0x30}; /* fake SM PDU */
printf("==== %s() [start] ====\n", __func__);
@@ -400,7 +407,18 @@ /* As a result, MS answers GMM Attach Complete */ /* As a result, MS submits GMMSM Establish.cnf */
- /* ... */ + /* SM layer submits Activate PDP Context Req: */ + gmm_prim = osmo_gprs_gmm_prim_alloc_gmmsm_unitdata_req(sess_id, sm_pdu, sizeof(sm_pdu)); + rc = osmo_gprs_gmm_prim_upper_down(gmm_prim); + OSMO_ASSERT(rc == 0); + /* As a result, GMM submits LLC-LL-UNITDATA.req */ + + /* Network answers with Activate PDP Ctx Accept, LLC submits the pdu up to GMM: */ + llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(rand_tlli, OSMO_GPRS_LLC_SAPI_GMM, sm_pdu, sizeof(sm_pdu)); + OSMO_ASSERT(llc_prim); + rc = osmo_gprs_gmm_prim_llc_lower_up(llc_prim); + OSMO_ASSERT(rc == 0); + /* As a result, GMM submits GMMSM-UNITDATA.ind */
/* DEACT: TODO */
diff --git a/tests/gmm/gmm_prim_test.err b/tests/gmm/gmm_prim_test.err index d589876..7aca515 100644 --- a/tests/gmm/gmm_prim_test.err +++ b/tests/gmm/gmm_prim_test.err @@ -46,3 +46,5 @@ DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) Tx GMM ATTACH COMPL DLGLOBAL INFO GMM_MS{RegisteredInitiated}: Received Event ATTACH_ACCEPTED DLGLOBAL INFO GMM_MS{RegisteredInitiated}: state_chg to Registered +DLGLOBAL INFO Rx from upper layers: GMMSM-UNITDATA.request +DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication diff --git a/tests/gmm/gmm_prim_test.ok b/tests/gmm/gmm_prim_test.ok index 156a282..e37507e 100644 --- a/tests/gmm/gmm_prim_test.ok +++ b/tests/gmm/gmm_prim_test.ok @@ -22,4 +22,6 @@ test_gmm_prim_down_cb(): Rx GMRR-ASSIGN.request old_tlli=0x80001234 new_tlli=0xea711b41 test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0xea711b41 SAPI=GMM l3=[08 03 ] test_gmm_prim_up_cb(): Rx GMMSM-ESTABLISH.confirm sess_id=1234 accepted=1 rej_cause=0 +test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0xea711b41 SAPI=GMM l3=[0a 28 29 30 ] +test_gmm_prim_up_cb(): Rx GMMSM-UNITDATA.indication sess_id=1234 sm_pdu=0a 28 29 30 ==== test_gmm_prim_ms_gmmsm() [end] ====