diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2010-03-31 20:34:16 +0200 |
---|---|---|
committer | Andreas Eversberg <jolly@eversberg.eu> | 2010-03-31 20:34:16 +0200 |
commit | 4495f10ee08c86c2996fa53231b7e1edf95f7fd6 (patch) | |
tree | 65b2aef25bbc03481ba7f9d4ea76605ed2f22541 /src/host/gsm48-andreas | |
parent | d95222b0722b2537f52bf32a3b2672721b5063ca (diff) |
Work on Mobility Management: Abort process
Diffstat (limited to 'src/host/gsm48-andreas')
-rw-r--r-- | src/host/gsm48-andreas/gsm48_l3.h | 103 | ||||
-rw-r--r-- | src/host/gsm48-andreas/gsm48_mm.c | 192 | ||||
-rw-r--r-- | src/host/gsm48-andreas/gsm48_rr.c | 1 |
3 files changed, 188 insertions, 108 deletions
diff --git a/src/host/gsm48-andreas/gsm48_l3.h b/src/host/gsm48-andreas/gsm48_l3.h index 4cfd9ed1..f2940a00 100644 --- a/src/host/gsm48-andreas/gsm48_l3.h +++ b/src/host/gsm48-andreas/gsm48_l3.h @@ -82,49 +82,49 @@ struct gsm48_rr { }; /* GSM 04.07 9.2.2 */ -#define MMCC_EST_REQ 0x9110 -#define MMCC_EST_IND 0x9112 -#define MMCC_EST_CNF 0x9111 -#define MMCC_REL_REQ 0x9120 -#define MMCC_REL_IND 0x9122 -#define MMCC_DATA_REQ 0x9130 -#define MMCC_DATA_IND 0x9132 -#define MMCC_UNIT_DATA_REQ 0x9140 -#define MMCC_UNIT_DATA_IND 0x9142 -#define MMCC_SYNC_IND 0x9152 -#define MMCC_REEST_REQ 0x9160 -#define MMCC_REEST_CNF 0x9161 -#define MMCC_ERR_IND 0x9172 -#define MMCC_PROMPT_IND 0x9182 -#define MMCC_PROMPT_REJ 0x9184 -#define MMSS_EST_REQ 0x9210 -#define MMSS_EST_IND 0x9212 -#define MMSS_EST_CNF 0x9211 -#define MMSS_REL_REQ 0x9220 -#define MMSS_REL_IND 0x9222 -#define MMSS_DATA_REQ 0x9230 -#define MMSS_DATA_IND 0x9232 -#define MMSS_UNIT_DATA_REQ 0x9240 -#define MMSS_UNIT_DATA_IND 0x9242 -#define MMSS_REEST_REQ 0x9260 -#define MMSS_REEST_CNF 0x9261 -#define MMSS_ERR_IND 0x9272 -#define MMSS_PROMPT_IND 0x9282 -#define MMSS_PROMPT_REJ 0x9284 -#define MMSMS_EST_REQ 0x9310 -#define MMSMS_EST_IND 0x9312 -#define MMSMS_EST_CNF 0x9311 -#define MMSMS_REL_REQ 0x9320 -#define MMSMS_REL_IND 0x9322 -#define MMSMS_DATA_REQ 0x9330 -#define MMSMS_DATA_IND 0x9332 -#define MMSMS_UNIT_DATA_REQ 0x9340 -#define MMSMS_UNIT_DATA_IND 0x9342 -#define MMSMS_REEST_REQ 0x9360 -#define MMSMS_REEST_CNF 0x9361 -#define MMSMS_ERR_IND 0x9372 -#define MMSMS_PROMPT_IND 0x9382 -#define MMSMS_PROMPT_REJ 0x9384 +#define GSM48_MMCC_EST_REQ 0x9110 todo: renumber +#define GSM48_MMCC_EST_IND 0x9112 +#define GSM48_MMCC_EST_CNF 0x9111 +#define GSM48_MMCC_REL_REQ 0x9120 +#define GSM48_MMCC_REL_IND 0x9122 +#define GSM48_MMCC_DATA_REQ 0x9130 +#define GSM48_MMCC_DATA_IND 0x9132 +#define GSM48_MMCC_UNIT_DATA_REQ 0x9140 +#define GSM48_MMCC_UNIT_DATA_IND 0x9142 +#define GSM48_MMCC_SYNC_IND 0x9152 +#define GSM48_MMCC_REEST_REQ 0x9160 +#define GSM48_MMCC_REEST_CNF 0x9161 +#define GSM48_MMCC_ERR_IND 0x9172 +#define GSM48_MMCC_PROMPT_IND 0x9182 +#define GSM48_MMCC_PROMPT_REJ 0x9184 +#define GSM48_MMSS_EST_REQ 0x9210 +#define GSM48_MMSS_EST_IND 0x9212 +#define GSM48_MMSS_EST_CNF 0x9211 +#define GSM48_MMSS_REL_REQ 0x9220 +#define GSM48_MMSS_REL_IND 0x9222 +#define GSM48_MMSS_DATA_REQ 0x9230 +#define GSM48_MMSS_DATA_IND 0x9232 +#define GSM48_MMSS_UNIT_DATA_REQ 0x9240 +#define GSM48_MMSS_UNIT_DATA_IND 0x9242 +#define GSM48_MMSS_REEST_REQ 0x9260 +#define GSM48_MMSS_REEST_CNF 0x9261 +#define GSM48_MMSS_ERR_IND 0x9272 +#define GSM48_MMSS_PROMPT_IND 0x9282 +#define GSM48_MMSS_PROMPT_REJ 0x9284 +#define GSM48_MMSMS_EST_REQ 0x9310 +#define GSM48_MMSMS_EST_IND 0x9312 +#define GSM48_MMSMS_EST_CNF 0x9311 +#define GSM48_MMSMS_REL_REQ 0x9320 +#define GSM48_MMSMS_REL_IND 0x9322 +#define GSM48_MMSMS_DATA_REQ 0x9330 +#define GSM48_MMSMS_DATA_IND 0x9332 +#define GSM48_MMSMS_UNIT_DATA_REQ 0x9340 +#define GSM48_MMSMS_UNIT_DATA_IND 0x9342 +#define GSM48_MMSMS_REEST_REQ 0x9360 +#define GSM48_MMSMS_REEST_CNF 0x9361 +#define GSM48_MMSMS_ERR_IND 0x9372 +#define GSM48_MMSMS_PROMPT_IND 0x9382 +#define GSM48_MMSMS_PROMPT_REJ 0x9384 /* GSM 04.07 9.1.1 */ #define GSM_RRSTATE_IDLE 0 @@ -233,7 +233,7 @@ struct gsm48_mmevent { /* MM sublayer instance */ -struct gsm_mmlayer { +struct gsm48_mmlayer { struct osmocom_ms *ms; int state; int substate; @@ -241,8 +241,23 @@ struct gsm_mmlayer { struct timer_list t3212; struct timer_list t3213; int t3212_value; + struct llist_head mm_conn; }; +/* MM connection types */ +#define GSM48_MM_CONN_TYPE_CC 1 +#define GSM48_MM_CONN_TYPE_SS 2 +#define GSM48_MM_CONN_TYPE_SMS 3 + +/* MM connection entry */ +struct gsm48_mm_conn { + struct llist_head list; + + unsigned int ref; + int type; +}; + + /* GSM 04.08 RR timers */ #define GSM_T3126_MS 5, 0 diff --git a/src/host/gsm48-andreas/gsm48_mm.c b/src/host/gsm48-andreas/gsm48_mm.c index 7bf918f6..e1c09d07 100644 --- a/src/host/gsm48-andreas/gsm48_mm.c +++ b/src/host/gsm48-andreas/gsm48_mm.c @@ -50,8 +50,8 @@ * messages */ -/* allocate GSM 04.08 mobility management message (betreen MM and RR) */ -static struct msgb *gsm48_mm_msgb_alloc(void) +/* allocate GSM 04.08 rr-sap message (between MM and RR) */ +static struct msgb *gsm48_rr_msgb_alloc(void) { struct msgb *msg; @@ -462,7 +462,8 @@ static int gsm48_mm_imsi_detach_sent(struct osmocom_ms *ms, void *arg) /* release MM connection and proceed with IMSI detach */ static int gsm48_mm_imsi_detach_release(struct osmocom_ms *ms, void *arg) { - release all connections + /* release all connections */ + gsm48_mm_release_mm_conn(ms); /* wait for release of RR */ if (!s->att_allowed) { @@ -490,6 +491,93 @@ static int gsm48_mm_imsi_detach_delay(struct osmocom_ms *ms, void *arg) return 0; } +/* support function to release all ongoing MM connections */ +static int gsm48_mm_release_conn(struct osmocom_ms *ms) +{ + struct gsm48_mmlayer *mm = &ms->mm; + struct gsm48_mm_conn *conn; + struct msgb *nmsg; + int msg_type; + + /* loop until all transactions gone */ + while (!llist_empty(&mm->mm_conn)) { + conn = llist_entry(mm->mm_conn->next, struct gsm48_mm_conn, + entry); + + /* send the appropiate release message */ + switch (conn->type) { + case GSM48_MM_CONN_TYPE_CC: + msg_type = GSM48_MMCC_REL_IND; + break; + case GSM48_MM_CONN_TYPE_SS: + msg_type = GSM48_MMSS_REL_IND; + break; + case GSM48_MM_CONN_TYPE_SMS: + msg_type = GSM48_MMSMS_REL_IND; + break; + } + nmsg = gsm48_mm_msgb_alloc(msg_type, conn->ref); + if (!nmsg) + return -ENOMEM; + gsm48_mmxx_upmsg(ms, nmsg); + + /* detach from list and free */ + llist_del(&conn->entry); + free(conn); + } + + return 0; +} + +/* 4.3.5.2 ABORT is received */ +static int gsm48_mm_rx_abort(struct osmocom_ms *ms, struct msgb *msg) +{ + struct gsm48_mmlayer *mm = &ms->mm; + struct gsm48_hdr *gh = msgb_l3(msg); + unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); + + if (payload_len < 1) { + DEBUGP(DMM, "Short read of location updating reject message error.\n"); + return -EINVAL; + } + + reject_cause = *gh->data; + + if (llist_empty(&mm->mm_conn)) { + DEBUGP(DMM, "Abort (cause #%d) while no MM connection is established.\n", reject_cause); + return gsm48_mm_tx_mm_status(ms, + GSM48_REJECT_MSG_NOT_COMPATIBLE); + } else { + DEBUGP(DMM, "Abort (cause #%d) while MM connection is established.\n", reject_cause); + gsm48_mm_release_mm_conn(ms); + } + + if (reject_cause == GSM48_REJECT_ILLEGAL_ME) { + /* SIM invalid */ + subscr->sim_valid = 0; + + /* TMSI and LAI invalid */ + subscr->tmsi_valid = 0; + + /* key is invalid */ + subscr->key_seq = 7; + + /* update status */ + new_sim_ustate(ms, GSM_MMUSTATE_U3_ROAMING_NA); + +#ifdef TODO + sim: delete tmsi + sim: delete key seq number + sim: apply update state +#endif + + /* return to MM IDLE / No SIM */ + gsm48_mm_return_idle(ms); + } + + return 0; +} + @@ -628,13 +716,13 @@ todo todo set cause reject: switch(msg_type) { - case MMCC_EST_REQ: + case GSM48_MMCC_EST_REQ: mmmsg->cause = cause; return mm_recvmsg(ms, trans, MMCC_REL_IND, mmmsg); - case MMSS_EST_REQ: + case GSM48_MMSS_EST_REQ: mmmsg->cause = cause; return mm_recvmsg(ms, trans, MMSS_REL_IND, mmmsg); - case MMSMS_EST_REQ: + case GSM48_MMSMS_EST_REQ: mmmsg->cause = cause; return mm_recvmsg(ms, trans, MMSMS_REL_IND, mmmsg); default: @@ -710,15 +798,15 @@ static int gsm48_mm_init_mm_other(struct osmocom_ms *ms, void *arg) struct gsm_trans *trans = mmmsg->trans; switch(msg_type) { - case MMCC_EST_REQ: + case GSM48_MMCC_EST_REQ: mmmsg->cause = cause; - return mm_recvmsg(ms, trans, MMCC_REL_IND, mmmsg); - case MMSS_EST_REQ: + return mm_recvmsg(ms, trans, GSM48_MMCC_REL_IND, mmmsg); + case GSM48_MMSS_EST_REQ: mmmsg->cause = cause; - return mm_recvmsg(ms, trans, MMSS_REL_IND, mmmsg); - case MMSMS_EST_REQ: + return mm_recvmsg(ms, trans, GSM48_MMSS_REL_IND, mmmsg); + case GSM48_MMSMS_EST_REQ: mmmsg->cause = cause; - return mm_recvmsg(ms, trans, MMSMS_REL_IND, mmmsg); + return mm_recvmsg(ms, trans, GSM48_MMSMS_REL_IND, mmmsg); default: return 0; } @@ -751,7 +839,7 @@ static struct eventstate { u_int32_t states; u_int32_t substates; int type; - int (*rout) (struct gsm_trans *trans, void *arg); + int (*rout) (struct osmocom_ms *ms, struct msgb *msg); } eventstatelist[] = { /* 4.2.2.1 Normal service */ ** todo: check if there is a senders of every event @@ -988,39 +1076,6 @@ static int gsm48_mm_rx_info(struct osmocom_ms *ms, struct msgb *msg) } } -/* location updating reject is received from lower layer */ -static int gsm48_mm_rx_abort(struct osmocom_ms *ms, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - - if (payload_len < 1) { - DEBUGP(DMM, "Short read of location updating reject message error.\n"); - return -EINVAL; - } - - reject_cause = *gh->data; - - if (llist_empty(ms->trans)) { - DEBUGP(DMM, "Abort (cause #%d) while no MM connection is established.\n", reject_cause); - return 0; - } else { - DEBUGP(DMM, "Abort (cause #%d) while MM connection is established.\n", reject_cause); - while(translist not empty) - release trans - todo: release trans must send a release to it's application entitity - todo: release must cause release of state 6 and transfer to state 9 - } - - if (reject_cause == 6) { - new_sim_ustate(ms, GSM_MMUSTATE_U3_ROAMING_NA); -#ifdef TODO - sim: delete tmsi - sim: delete key seq number - sim: apply update state -#endif - } -} /* location updating accept is received from lower layer */ static int gsm48_mm_rx_loc_upd_acc(struct osmocom_ms *ms, struct msgb *msg) @@ -1152,7 +1207,7 @@ static int gsm48_mm_rx_cm_service_ack(struct osmocom_ms *ms, struct msgb *msg) static struct mmdatastate { u_int32_t states; int type; - int (*rout) (struct gsm_trans *trans, struct msgb *msg); + int (*rout) (struct osmocom_ms *ms, struct msgb *msg); } mmdatastatelist[] = { {ALL_STATES, /* 4.3.1.2 */ GSM48_MT_MM_TMSI_REALL_CMD, gsm48_mm_rx_tmsi_realloc_cmd}, @@ -1304,14 +1359,14 @@ static int gsm48_mm_rel_loc_upd_rej(struct osmocom_ms *ms, struct gsm_rr *rel) /* new status */ switch (mm->lupd_rej_cause) { - case 11: - case 12: - case 13: + case GSM48_REJECT_PLMN_NOT_ALLOWED: + case GSM48_REJECT_LOC_NOT_ALLOWED: + case GSM48_REJECT_ROAMING_NOT_ALLOWED: attempt_counter = 0; // fall through - case 2: - case 3: - case 6: + case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR: + case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR: + case GSM48_REJECT_ILLEGAL_ME: new_sim_ustate(ms, GSM_MMUSTATE_U3_ROAMING_NA); #ifdef TODO sim: delete tmsi @@ -1322,19 +1377,19 @@ static int gsm48_mm_rel_loc_upd_rej(struct osmocom_ms *ms, struct gsm_rr *rel) /* forbidden list */ switch (mm->lupd_rej_cause) { - case 2: - case 3: - case 6: + case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR: + case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR: + case GSM48_REJECT_ILLEGAL_ME: /* sim becomes invalid */ subscr->sim_valid = 0; break; - case 11: + case GSM48_REJECT_PLMN_NOT_ALLOWED: add_forbidden_list(ms, FORBIDDEN_PLMN, lai); break; - case 12: + case GSM48_REJECT_LOC_NOT_ALLOWED: add_forbidden_list(ms, FORBIDDEN_LOC_AREA_RPOS, lai); break; - case 13: + case GSM48_REJECT_ROAMING_NOT_ALLOWED: add_forbidden_list(ms, FORBIDDEN_LOC_AREA_ROAM, lai); break; default: @@ -1379,7 +1434,7 @@ static int gsm48_mm_est_mm_con(struct osmocom_ms *ms, struct gsm_rr *est) static struct rrdatastate { u_int32_t states; int type; - int (*rout) (struct gsm_trans *trans, struct gsm_rr *msg); + int (*rout) (struct osmocom_ms *ms, struct msgb *msg); } rrdatastatelist[] = { {SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.1 */ RR_ESTAB_CNF, gsm48_mm_est_loc_upd}, @@ -1429,14 +1484,14 @@ static int gsm48_rcv_rr(struct osmocom_ms *ms, struct msgb *msg) return rc; } -/* dequeue messages from RR */ -int gsm48_mm_queue(struct osmocom_ms *ms) +/* dequeue messages from rr-sap */ +int gsm48_mm_dequeue_rr(struct osmocom_ms *ms) { - struct gsm48_mmlayer *mm = &ms->mmlayer; + struct gsm48_rrlayer *rr = &ms->rrlayer; struct msgb *msg; int work = 0; - while ((msg = msgb_dequeue(&mm->up_queue))) { + while ((msg = msgb_dequeue(&rr->rr_upqueue))) { /* message is also freed here */ gsm48_rcv_rr(ms, msg); work = 1; /* work done */ @@ -1446,4 +1501,13 @@ int gsm48_mm_queue(struct osmocom_ms *ms) } +/* queue message to upper layer at mmxx-sap */ +int gsm48_mmxx_upmsg(struct osmocom_ms *ms, struct msgb *msg) +{ + struct gsm48_mmlayer *mm = &ms->mmlayer; + + msgb_enqueue(&mm->mmxx_upqueue, msg); +} + + wichtig: nur eine MM connection zur zeit, da ja auch nur ein cm-service-request laufen kann. die anderen werden dann als "waiting" deklariert. diff --git a/src/host/gsm48-andreas/gsm48_rr.c b/src/host/gsm48-andreas/gsm48_rr.c index 4267aea0..9c992e35 100644 --- a/src/host/gsm48-andreas/gsm48_rr.c +++ b/src/host/gsm48-andreas/gsm48_rr.c @@ -80,6 +80,7 @@ static void new_rr_state(struct gsm_rrlayer *rr, int state) */ /* allocate GSM 04.08 radio ressource message (RR to L2) */ +wrong sap name, must be changed to msg48_rsl_msgb_alloc... static struct msgb *gsm48_rr_msgb_alloc(void) { struct msgb *msg; |