pespin has uploaded this change for review. (
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(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-gprs refs/changes/81/32581/1
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] ====
--
To view, visit
https://gerrit.osmocom.org/c/libosmo-gprs/+/32581
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: libosmo-gprs
Gerrit-Branch: master
Gerrit-Change-Id: Ib1ac220292c61419a65f27fa88a731357728459d
Gerrit-Change-Number: 32581
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: newchange