gmm: Implement GMMSM-UNITDATA.ind

Change-Id: Ib1ac220292c61419a65f27fa88a731357728459d
This commit is contained in:
Pau Espin 2023-05-03 11:17:36 +02:00
parent 644780008d
commit 226c2a140c
6 changed files with 82 additions and 9 deletions

View File

@ -106,6 +106,7 @@ struct gprs_gmm_entity *gprs_gmm_gmme_find_or_create_by_ptmsi_imsi(uint32_t ptms
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,

View File

@ -236,6 +236,17 @@ struct gprs_gmm_entity *gprs_gmm_find_gmme_by_tlli(uint32_t tlli)
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 @@ static int gprs_gmm_rx_auth_ciph_req(struct gprs_gmm_entity *gmme, struct gsm48_
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:

View File

@ -508,10 +508,29 @@ static int gprs_gmm_prim_handle_gmmsm_establish_req(struct osmo_gprs_gmm_prim *g
/* 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 @@ static int gprs_gmm_prim_handle_ll_unitdata_ind(struct osmo_gprs_llc_prim *llc_p
{
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;
}

View File

@ -204,6 +204,12 @@ int test_gmm_prim_up_cb(struct osmo_gprs_gmm_prim *gmm_prim, void *user_data)
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 @@ static void test_gmm_prim_ms_gmmsm(void)
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 @@ static void test_gmm_prim_ms_gmmsm(void)
/* 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 */

View File

@ -46,3 +46,5 @@ DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM ATTACH A
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

View File

@ -22,4 +22,6 @@ test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request old_TLLI=0x80001234 new_TLL
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] ====