Fixes and improvements of RR, MM, CC processes.
This commit is contained in:
parent
ff555175d1
commit
d8cc251cf1
|
@ -182,6 +182,7 @@ struct gsm48_mmlayer {
|
|||
uint8_t lupd_ra_failure;/* random access failed */
|
||||
uint8_t lupd_rej_cause; /* cause of last reject */
|
||||
uint8_t lupd_periodic; /* periodic update pending */
|
||||
uint8_t lupd_retry; /* pending T3211/T3213 to */
|
||||
|
||||
/* imsi detach */
|
||||
uint8_t delay_detach; /* do detach when possible */
|
||||
|
|
|
@ -1010,6 +1010,7 @@ static int gsm322_a_switch_on(struct osmocom_ms *ms, struct msgb *msg)
|
|||
struct msgb *nmsg;
|
||||
|
||||
if (!subscr->sim_valid) {
|
||||
LOGP(DSUM, LOGL_INFO, "No SIM inserted\n");
|
||||
LOGP(DPLMN, LOGL_INFO, "Switch on without SIM.\n");
|
||||
new_a_state(plmn, GSM322_A6_NO_SIM);
|
||||
|
||||
|
@ -1022,6 +1023,10 @@ static int gsm322_a_switch_on(struct osmocom_ms *ms, struct msgb *msg)
|
|||
plmn->mcc = subscr->plmn_mcc;
|
||||
plmn->mnc = subscr->plmn_mnc;
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Start search of last registered PLMN "
|
||||
"(mcc=%03d mnc=%02d %s, %s)\n", plmn->mcc, plmn->mnc,
|
||||
gsm_get_mcc(plmn->mcc),
|
||||
gsm_get_mnc(plmn->mcc, plmn->mnc));
|
||||
LOGP(DPLMN, LOGL_INFO, "Use RPLMN (mcc=%03d mnc=%02d "
|
||||
"%s, %s)\n", plmn->mcc, plmn->mnc,
|
||||
gsm_get_mcc(plmn->mcc),
|
||||
|
@ -1039,6 +1044,7 @@ static int gsm322_a_switch_on(struct osmocom_ms *ms, struct msgb *msg)
|
|||
}
|
||||
|
||||
/* initiate search at cell selection */
|
||||
LOGP(DSUM, LOGL_INFO, "Search for network\n");
|
||||
LOGP(DPLMN, LOGL_INFO, "Switch on, start PLMN search first.\n");
|
||||
|
||||
nmsg = gsm322_msgb_alloc(GSM322_EVENT_PLMN_SEARCH_START);
|
||||
|
@ -1205,6 +1211,7 @@ static int gsm322_m_switch_on(struct osmocom_ms *ms, struct msgb *msg)
|
|||
struct msgb *nmsg;
|
||||
|
||||
if (!subscr->sim_valid) {
|
||||
LOGP(DSUM, LOGL_INFO, "No SIM inserted\n");
|
||||
LOGP(DPLMN, LOGL_INFO, "Switch on without SIM.\n");
|
||||
new_m_state(plmn, GSM322_M5_NO_SIM);
|
||||
|
||||
|
@ -1219,6 +1226,10 @@ static int gsm322_m_switch_on(struct osmocom_ms *ms, struct msgb *msg)
|
|||
plmn->mcc = subscr->plmn_mcc;
|
||||
plmn->mnc = subscr->plmn_mnc;
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Start search of last registered PLMN "
|
||||
"(mcc=%03d mnc=%02d %s, %s)\n", plmn->mcc, plmn->mnc,
|
||||
gsm_get_mcc(plmn->mcc),
|
||||
gsm_get_mnc(plmn->mcc, plmn->mnc));
|
||||
LOGP(DPLMN, LOGL_INFO, "Use RPLMN (mcc=%03d mnc=%02d "
|
||||
"%s, %s)\n", plmn->mcc, plmn->mnc,
|
||||
gsm_get_mcc(plmn->mcc),
|
||||
|
@ -1236,6 +1247,7 @@ static int gsm322_m_switch_on(struct osmocom_ms *ms, struct msgb *msg)
|
|||
}
|
||||
|
||||
/* initiate search at cell selection */
|
||||
LOGP(DSUM, LOGL_INFO, "Search for network\n");
|
||||
LOGP(DPLMN, LOGL_INFO, "Switch on, start PLMN search first.\n");
|
||||
vty_notify(ms, "Searching Network, please wait...\n");
|
||||
|
||||
|
@ -1986,7 +1998,7 @@ static int gsm322_c_camp_sysinfo_bcch(struct osmocom_ms *ms, struct msgb *msg)
|
|||
LOGP(DCS, LOGL_INFO, "Sysinfo of selected cell is "
|
||||
"updated.\n");
|
||||
memcpy(&cs->sel_si, s, sizeof(cs->sel_si));
|
||||
gsm48_sysinfo_dump(s, print_dcs, NULL);
|
||||
//gsm48_sysinfo_dump(s, print_dcs, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2084,7 +2096,7 @@ static int gsm322_c_scan_sysinfo_bcch(struct osmocom_ms *ms, struct msgb *msg)
|
|||
/* stop timer */
|
||||
stop_cs_timer(cs);
|
||||
|
||||
gsm48_sysinfo_dump(s, print_dcs, NULL);
|
||||
//gsm48_sysinfo_dump(s, print_dcs, NULL);
|
||||
|
||||
/* store sysinfo and continue scan */
|
||||
return gsm322_cs_store(ms);
|
||||
|
@ -2679,6 +2691,10 @@ static int gsm322_c_new_plmn(struct osmocom_ms *ms, struct msgb *msg)
|
|||
cs->mcc = plmn->mcc;
|
||||
cs->mnc = plmn->mnc;
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Selecting network (mcc=%03d "
|
||||
"mnc=%02d %s, %s)\n", cs->mcc, cs->mnc, gsm_get_mcc(cs->mcc),
|
||||
gsm_get_mnc(cs->mcc, cs->mnc));
|
||||
|
||||
/* search for BA list */
|
||||
ba = gsm322_find_ba_list(cs, plmn->mcc, plmn->mnc);
|
||||
|
||||
|
@ -2697,6 +2713,8 @@ static int gsm322_c_camp_normally(struct osmocom_ms *ms, struct msgb *msg)
|
|||
struct gsm322_cellsel *cs = &ms->cellsel;
|
||||
struct msgb *nmsg;
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Camping normally on cell of network\n");
|
||||
|
||||
/* tell that we have selected a (new) cell */
|
||||
nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_CELL_SELECTED);
|
||||
if (!nmsg)
|
||||
|
@ -2714,6 +2732,8 @@ static int gsm322_c_camp_any_cell(struct osmocom_ms *ms, struct msgb *msg)
|
|||
struct gsm322_cellsel *cs = &ms->cellsel;
|
||||
struct msgb *nmsg;
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Camping on any cell of network\n");
|
||||
|
||||
/* tell that we have selected a (new) cell */
|
||||
nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_CELL_SELECTED);
|
||||
if (!nmsg)
|
||||
|
|
|
@ -1591,6 +1591,12 @@ static int gsm48_cc_rx_disconnect(struct gsm_trans *trans, struct msgb *msg)
|
|||
gsm48_decode_facility(&disc.facility,
|
||||
TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
|
||||
}
|
||||
/* progress */
|
||||
if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
|
||||
disc.fields |= MNCC_F_PROGRESS;
|
||||
gsm48_decode_progress(&disc.progress,
|
||||
TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
|
||||
}
|
||||
/* user-user */
|
||||
if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
|
||||
disc.fields |= MNCC_F_USERUSER;
|
||||
|
|
|
@ -51,6 +51,7 @@ static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg);
|
|||
static void new_mm_state(struct gsm48_mmlayer *mm, int state, int substate);
|
||||
static int gsm48_mm_loc_upd_normal(struct osmocom_ms *ms, struct msgb *msg);
|
||||
static int gsm48_mm_loc_upd_periodic(struct osmocom_ms *ms, struct msgb *msg);
|
||||
static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg);
|
||||
|
||||
/*
|
||||
* notes
|
||||
|
@ -276,7 +277,7 @@ int gsm48_encode_mi(uint8_t *buf, struct msgb *msg, struct osmocom_ms *ms,
|
|||
break;
|
||||
}
|
||||
/* alter MI type */
|
||||
buf[2] = (buf[2] & 0xf8) | mi_type;
|
||||
buf[2] = (buf[2] & ~GSM_MI_TYPE_MASK) | mi_type;
|
||||
|
||||
if (msg) {
|
||||
/* MI as LV */
|
||||
|
@ -316,6 +317,7 @@ static void timeout_mm_t3211(void *arg)
|
|||
{
|
||||
struct gsm48_mmlayer *mm = arg;
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Location update retry\n");
|
||||
LOGP(DMM, LOGL_INFO, "timer T3211 (loc. upd. retry delay) has fired\n");
|
||||
gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3211, NULL);
|
||||
}
|
||||
|
@ -324,6 +326,7 @@ static void timeout_mm_t3212(void *arg)
|
|||
{
|
||||
struct gsm48_mmlayer *mm = arg;
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Periodic location update\n");
|
||||
LOGP(DMM, LOGL_INFO, "timer T3212 (periodic loc. upd. delay) has "
|
||||
"fired\n");
|
||||
|
||||
|
@ -339,6 +342,7 @@ static void timeout_mm_t3213(void *arg)
|
|||
{
|
||||
struct gsm48_mmlayer *mm = arg;
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Location update retry\n");
|
||||
LOGP(DMM, LOGL_INFO, "timer T3213 (delay after RA failure) has "
|
||||
"fired\n");
|
||||
gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3213, NULL);
|
||||
|
@ -917,11 +921,21 @@ static void new_mm_state(struct gsm48_mmlayer *mm, int state, int substate)
|
|||
if (!bsc_timer_pending(&mm->t3212))
|
||||
start_mm_t3212(mm, mm->t3212_value);
|
||||
/* perform pending location update */
|
||||
if (mm->lupd_retry) {
|
||||
LOGP(DMM, LOGL_INFO, "Loc. upd. pending (type %d)\n",
|
||||
mm->lupd_type);
|
||||
mm->lupd_retry = 0;
|
||||
gsm48_mm_loc_upd(mm->ms, NULL);
|
||||
/* must exit, because this function can be called
|
||||
* recursively
|
||||
*/
|
||||
return;
|
||||
}
|
||||
if (mm->lupd_periodic) {
|
||||
struct gsm48_sysinfo *s = &mm->ms->cellsel.sel_si;
|
||||
|
||||
LOGP(DMM, LOGL_INFO, "Loc. upd. pending (type %d)\n",
|
||||
mm->lupd_type);
|
||||
LOGP(DMM, LOGL_INFO, "Periodic loc. upd. pending "
|
||||
"(type %d)\n", mm->lupd_type);
|
||||
mm->lupd_periodic = 0;
|
||||
if (s->t3212)
|
||||
gsm48_mm_loc_upd_periodic(mm->ms, NULL);
|
||||
|
@ -1438,7 +1452,8 @@ static int gsm48_mm_rx_tmsi_realloc_cmd(struct osmocom_ms *ms, struct msgb *msg)
|
|||
memcpy(&tmsi, mi+2, 4);
|
||||
subscr->tmsi = ntohl(tmsi);
|
||||
subscr->tmsi_valid = 1;
|
||||
LOGP(DMM, LOGL_INFO, "TMSI 0x%08x assigned.\n", subscr->tmsi);
|
||||
LOGP(DMM, LOGL_INFO, "TMSI 0x%08x (%u) assigned.\n",
|
||||
subscr->tmsi, subscr->tmsi);
|
||||
gsm48_mm_tx_tmsi_reall_cpl(ms);
|
||||
break;
|
||||
case GSM_MI_TYPE_IMSI:
|
||||
|
@ -1938,6 +1953,7 @@ static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg)
|
|||
struct gsm322_cellsel *cs = &ms->cellsel;
|
||||
struct gsm48_sysinfo *s = &cs->sel_si;
|
||||
struct gsm_subscriber *subscr = &ms->subscr;
|
||||
struct msgb *nmsg;
|
||||
|
||||
/* (re)start only if we still require location update */
|
||||
if (!mm->lupd_pending) {
|
||||
|
@ -1948,21 +1964,26 @@ static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg)
|
|||
/* must camp normally */
|
||||
if (cs->state != GSM322_C3_CAMPED_NORMALLY) {
|
||||
LOGP(DMM, LOGL_INFO, "Loc. upd. not camping normally.\n");
|
||||
stop:
|
||||
LOGP(DSUM, LOGL_INFO, "Location update not possible\n");
|
||||
mm->lupd_pending = 0;
|
||||
/* send message to PLMN search process */
|
||||
nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
gsm322_plmn_sendmsg(ms, nmsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if LAI is forbidden, don't start */
|
||||
if (gsm_subscr_is_forbidden_plmn(subscr, cs->sel_mcc, cs->sel_mnc)) {
|
||||
LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed PLMN.\n");
|
||||
mm->lupd_pending = 0;
|
||||
return 0;
|
||||
goto stop;
|
||||
}
|
||||
if (gsm322_is_forbidden_la(ms, cs->sel_mcc,
|
||||
cs->sel_mnc, cs->sel_lac)) {
|
||||
LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed LA.\n");
|
||||
mm->lupd_pending = 0;
|
||||
return 0;
|
||||
goto stop;
|
||||
}
|
||||
|
||||
/* 4.4.4.9 if cell is barred, don't start */
|
||||
|
@ -1970,10 +1991,11 @@ static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg)
|
|||
|| (!subscr->acc_barr && !((subscr->acc_class & 0xfbff) &
|
||||
(s->class_barr ^ 0xffff)))) {
|
||||
LOGP(DMM, LOGL_INFO, "Loc. upd. no access.\n");
|
||||
mm->lupd_pending = 0;
|
||||
return 0;
|
||||
goto stop;
|
||||
}
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Perform location update\n");
|
||||
|
||||
return gsm48_mm_tx_loc_upd_req(ms);
|
||||
}
|
||||
|
||||
|
@ -2199,6 +2221,7 @@ static int gsm48_mm_rx_loc_upd_acc(struct osmocom_ms *ms, struct msgb *msg)
|
|||
sim: store plmn
|
||||
#endif
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Location update accepted\n");
|
||||
LOGP(DMM, LOGL_INFO, "LOCATION UPDATING ACCEPT (mcc %03d mnc %02d "
|
||||
"lac 0x%04x)\n", subscr->lai_mcc, subscr->lai_mnc,
|
||||
subscr->lai_lac);
|
||||
|
@ -2225,8 +2248,8 @@ static int gsm48_mm_rx_loc_upd_acc(struct osmocom_ms *ms, struct msgb *msg)
|
|||
memcpy(&tmsi, mi+2, 4);
|
||||
subscr->tmsi = ntohl(tmsi);
|
||||
subscr->tmsi_valid = 1;
|
||||
LOGP(DMM, LOGL_INFO, "got TMSI 0x%08x\n",
|
||||
subscr->tmsi);
|
||||
LOGP(DMM, LOGL_INFO, "got TMSI 0x%08x (%u)\n",
|
||||
subscr->tmsi, subscr->tmsi);
|
||||
#ifdef TODO
|
||||
sim: store tmsi
|
||||
#endif
|
||||
|
@ -2343,10 +2366,12 @@ static int gsm48_mm_rel_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg)
|
|||
switch(mm->lupd_rej_cause) {
|
||||
case GSM48_REJECT_ROAMING_NOT_ALLOWED:
|
||||
nmsg = gsm322_msgb_alloc(GSM322_EVENT_ROAMING_NA);
|
||||
break;
|
||||
case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR:
|
||||
case GSM48_REJECT_ILLEGAL_MS:
|
||||
case GSM48_REJECT_ILLEGAL_ME:
|
||||
nmsg = gsm322_msgb_alloc(GSM322_EVENT_INVALID_SIM);
|
||||
break;
|
||||
default:
|
||||
nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
|
||||
}
|
||||
|
@ -2381,7 +2406,7 @@ static int gsm48_mm_rel_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg)
|
|||
}
|
||||
|
||||
/* 4.2.2 delay a location update */
|
||||
static int gsm48_mm_loc_upd_delay(struct osmocom_ms *ms, struct msgb *msg)
|
||||
static int gsm48_mm_loc_upd_delay_per(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
struct gsm48_mmlayer *mm = &ms->mmlayer;
|
||||
|
||||
|
@ -2391,6 +2416,17 @@ static int gsm48_mm_loc_upd_delay(struct osmocom_ms *ms, struct msgb *msg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* delay a location update retry */
|
||||
static int gsm48_mm_loc_upd_delay_retry(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
struct gsm48_mmlayer *mm = &ms->mmlayer;
|
||||
|
||||
LOGP(DMM, LOGL_INFO, "Schedule a pending periodic loc. upd.\n");
|
||||
mm->lupd_retry = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* process failues as described in the lower part of 4.4.4.9 */
|
||||
static int gsm48_mm_loc_upd_failed(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
|
@ -2398,6 +2434,8 @@ static int gsm48_mm_loc_upd_failed(struct osmocom_ms *ms, struct msgb *msg)
|
|||
struct gsm_subscriber *subscr = &ms->subscr;
|
||||
struct gsm322_cellsel *cs = &ms->cellsel;
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Location update failed\n");
|
||||
|
||||
/* stop location update timer, if running */
|
||||
stop_mm_t3210(mm);
|
||||
|
||||
|
@ -2407,6 +2445,7 @@ static int gsm48_mm_loc_upd_failed(struct osmocom_ms *ms, struct msgb *msg)
|
|||
&& cs->sel_mnc == subscr->lai_mnc
|
||||
&& cs->sel_lac == subscr->lai_lac) {
|
||||
if (mm->lupd_attempt < 4) {
|
||||
LOGP(DSUM, LOGL_INFO, "Try location update later\n");
|
||||
LOGP(DMM, LOGL_INFO, "Loc. upd. failed, retry #%d\n",
|
||||
mm->lupd_attempt);
|
||||
|
||||
|
@ -2436,8 +2475,10 @@ static int gsm48_mm_loc_upd_failed(struct osmocom_ms *ms, struct msgb *msg)
|
|||
#endif
|
||||
|
||||
/* start update retry timer (RR connection is released) */
|
||||
if (mm->lupd_attempt < 4)
|
||||
if (mm->lupd_attempt < 4) {
|
||||
mm->start_t3211 = 1;
|
||||
LOGP(DSUM, LOGL_INFO, "Try location update later\n");
|
||||
}
|
||||
|
||||
/* CS process will trigger: return to MM IDLE */
|
||||
return 0;
|
||||
|
@ -2449,6 +2490,13 @@ static int gsm48_mm_rel_loc_upd_abort(struct osmocom_ms *ms, struct msgb *msg)
|
|||
struct gsm48_mmlayer *mm = &ms->mmlayer;
|
||||
struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
|
||||
|
||||
if (rrh->msg_type == GSM48_RR_REL_IND) {
|
||||
LOGP(DMM, LOGL_INFO, "RR link released after loc. upd.\n");
|
||||
|
||||
/* continue with failure handling */
|
||||
return gsm48_mm_loc_upd_failed(ms, NULL);
|
||||
}
|
||||
|
||||
LOGP(DMM, LOGL_INFO, "Loc. upd. aborted by radio (cause #%d)\n",
|
||||
rrh->cause);
|
||||
|
||||
|
@ -2527,7 +2575,7 @@ static int gsm48_mm_tx_cm_serv_req(struct osmocom_ms *ms, int rr_prim,
|
|||
gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_TMSI);
|
||||
else
|
||||
gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_IMSI);
|
||||
msgb_put(nmsg, buf[1]);
|
||||
msgb_put(nmsg, buf[1]); /* length is part of nsr */
|
||||
memcpy(&nsr->mi_len, buf + 1, 1 + buf[1]);
|
||||
/* prio is optional for eMLPP */
|
||||
|
||||
|
@ -2762,6 +2810,8 @@ static int gsm48_mm_init_mm(struct osmocom_ms *ms, struct msgb *msg,
|
|||
proto = GSM48_PDISC_SMS;
|
||||
break;
|
||||
}
|
||||
#warning HACK: always request SDCCH for test
|
||||
cause = RR_EST_CAUSE_LOC_UPD;
|
||||
|
||||
/* create MM connection instance */
|
||||
conn = mm_conn_new(mm, proto, mmh->transaction_id, mmh->ref);
|
||||
|
@ -3246,88 +3296,124 @@ static struct downstate {
|
|||
/* 4.2.2.1 Normal service */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
|
||||
GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
|
||||
GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_no_rr},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
|
||||
GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_no_rr},
|
||||
|
||||
/* 4.2.2.2 Attempt to update / Loc. Upd. needed */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
|
||||
SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
|
||||
GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr}, /* emergency only */
|
||||
|
||||
/* 4.2.2.3 Limited service */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
|
||||
GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
|
||||
|
||||
/* 4.2.2.4 No IMSI */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_IMSI),
|
||||
GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
|
||||
|
||||
/* 4.2.2.5 PLMN search, normal service */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
|
||||
GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
|
||||
GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_no_rr},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
|
||||
GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_no_rr},
|
||||
|
||||
/* 4.2.2.6 PLMN search */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
|
||||
GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
|
||||
|
||||
/* 4.5.1.1 MM Connection (EST) */
|
||||
{SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
|
||||
GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_first},
|
||||
|
||||
{SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
|
||||
GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_first},
|
||||
|
||||
{SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
|
||||
GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_first},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
|
||||
GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_more},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
|
||||
GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_more},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
|
||||
GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_more},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
|
||||
GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_wait},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
|
||||
GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_wait},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
|
||||
GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_wait},
|
||||
|
||||
{ALL_STATES, ALL_STATES,
|
||||
GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_reject},
|
||||
|
||||
{ALL_STATES, ALL_STATES,
|
||||
GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_reject},
|
||||
|
||||
{ALL_STATES, ALL_STATES,
|
||||
GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_reject},
|
||||
|
||||
/* 4.5.2.1 MM Connection (DATA) */
|
||||
{SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
|
||||
SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
|
||||
GSM48_MMCC_DATA_REQ, gsm48_mm_data},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
|
||||
SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
|
||||
GSM48_MMSS_DATA_REQ, gsm48_mm_data},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
|
||||
SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
|
||||
GSM48_MMSMS_DATA_REQ, gsm48_mm_data},
|
||||
|
||||
/* 4.5.2.1 MM Connection (REL) */
|
||||
{SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
|
||||
GSM48_MMCC_REL_REQ, gsm48_mm_release_active},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
|
||||
GSM48_MMSS_REL_REQ, gsm48_mm_release_active},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
|
||||
GSM48_MMSMS_REL_REQ, gsm48_mm_release_active},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
|
||||
GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_add},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
|
||||
GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_add},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
|
||||
GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_add},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
|
||||
GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_active},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
|
||||
GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_active},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
|
||||
GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_active},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
|
||||
GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_rr},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
|
||||
GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_rr},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
|
||||
GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_rr},
|
||||
};
|
||||
|
@ -3384,56 +3470,74 @@ static struct rrdatastate {
|
|||
/* paging */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE),
|
||||
GSM48_RR_EST_IND, gsm48_mm_est},
|
||||
|
||||
/* imsi detach */
|
||||
{SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 */
|
||||
GSM48_RR_EST_CNF, gsm48_mm_imsi_detach_sent},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 (unsuc.) */
|
||||
GSM48_RR_REL_IND, gsm48_mm_imsi_detach_end},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 (lost) */
|
||||
GSM48_RR_ABORT_IND, gsm48_mm_imsi_detach_end},
|
||||
|
||||
/* location update */
|
||||
{SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.1 */
|
||||
GSM48_RR_EST_CNF, gsm48_mm_est_loc_upd},
|
||||
|
||||
{SBIT(GSM48_MM_ST_LOC_UPD_INIT) |
|
||||
SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.9 */
|
||||
GSM48_RR_REL_IND, gsm48_mm_rel_loc_upd_abort},
|
||||
|
||||
{SBIT(GSM48_MM_ST_LOC_UPD_INIT) |
|
||||
SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.9 */
|
||||
GSM48_RR_ABORT_IND, gsm48_mm_rel_loc_upd_abort},
|
||||
|
||||
{SBIT(GSM48_MM_ST_LOC_UPD_REJ), /* 4.4.4.7 */
|
||||
GSM48_RR_REL_IND, gsm48_mm_rel_loc_upd_rej},
|
||||
|
||||
{SBIT(GSM48_MM_ST_LOC_UPD_REJ), /* 4.4.4.7 */
|
||||
GSM48_RR_ABORT_IND, gsm48_mm_rel_loc_upd_rej},
|
||||
|
||||
/* MM connection (EST) */
|
||||
{SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), /* 4.5.1.1 */
|
||||
GSM48_RR_EST_CNF, gsm48_mm_est_mm_con},
|
||||
|
||||
/* MM connection (DATA) */
|
||||
{ALL_STATES,
|
||||
GSM48_RR_DATA_IND, gsm48_mm_data_ind},
|
||||
|
||||
/* MM connection (SYNC) */
|
||||
{SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
|
||||
SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.1 */
|
||||
GSM48_RR_SYNC_IND, gsm48_mm_sync_ind_wait},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_CONN_ACTIVE),
|
||||
GSM48_RR_SYNC_IND, gsm48_mm_sync_ind_active},
|
||||
|
||||
/* MM connection (REL/ABORT) */
|
||||
{SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON) |
|
||||
SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
|
||||
SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.2 */
|
||||
GSM48_RR_REL_IND, gsm48_mm_abort_mm_con},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON) |
|
||||
SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
|
||||
SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.2 */
|
||||
GSM48_RR_ABORT_IND, gsm48_mm_abort_mm_con},
|
||||
|
||||
/* MM connection (REL/ABORT with re-establishment possibility) */
|
||||
{SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), /* not supported */
|
||||
GSM48_RR_REL_IND, gsm48_mm_abort_mm_con},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
|
||||
SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* not supported */
|
||||
GSM48_RR_ABORT_IND, gsm48_mm_abort_mm_con},
|
||||
|
||||
/* other */
|
||||
{ALL_STATES,
|
||||
GSM48_RR_REL_IND, gsm48_mm_rel_other},
|
||||
|
||||
{ALL_STATES,
|
||||
GSM48_RR_ABORT_IND, gsm48_mm_rel_other},
|
||||
};
|
||||
|
@ -3479,22 +3583,31 @@ static struct mmdatastate {
|
|||
} mmdatastatelist[] = {
|
||||
{ALL_STATES, /* 4.3.1.2 */
|
||||
GSM48_MT_MM_TMSI_REALL_CMD, gsm48_mm_rx_tmsi_realloc_cmd},
|
||||
|
||||
{ALL_STATES, /* 4.3.2.2 */
|
||||
GSM48_MT_MM_AUTH_REQ, gsm48_mm_rx_auth_req},
|
||||
|
||||
{ALL_STATES, /* 4.3.2.5 */
|
||||
GSM48_MT_MM_AUTH_REJ, gsm48_mm_rx_auth_rej},
|
||||
|
||||
{ALL_STATES, /* 4.3.3.2 */
|
||||
GSM48_MT_MM_ID_REQ, gsm48_mm_rx_id_req},
|
||||
|
||||
{ALL_STATES, /* 4.3.5.2 */
|
||||
GSM48_MT_MM_ABORT, gsm48_mm_rx_abort},
|
||||
|
||||
{ALL_STATES, /* 4.3.6.2 */
|
||||
GSM48_MT_MM_INFO, gsm48_mm_rx_info},
|
||||
|
||||
{SBIT(GSM48_MM_ST_LOC_UPD_INIT), /* 4.4.4.6 */
|
||||
GSM48_MT_MM_LOC_UPD_ACCEPT, gsm48_mm_rx_loc_upd_acc},
|
||||
|
||||
{SBIT(GSM48_MM_ST_LOC_UPD_INIT), /* 4.4.4.7 */
|
||||
GSM48_MT_MM_LOC_UPD_REJECT, gsm48_mm_rx_loc_upd_rej},
|
||||
|
||||
{ALL_STATES, /* 4.5.1.1 */
|
||||
GSM48_MT_MM_CM_SERV_ACC, gsm48_mm_rx_cm_service_acc},
|
||||
|
||||
{ALL_STATES, /* 4.5.1.1 */
|
||||
GSM48_MT_MM_CM_SERV_REJ, gsm48_mm_rx_cm_service_rej},
|
||||
};
|
||||
|
@ -3653,77 +3766,105 @@ static struct eventstate {
|
|||
/* 4.2.3 return to MM IDLE */
|
||||
{ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
|
||||
GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found},
|
||||
|
||||
{ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
|
||||
GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_return_idle},
|
||||
|
||||
/* 4.2.2.1 Normal service */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
|
||||
GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_plmn_search}, /* 4.2.1.2 */
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
|
||||
GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* change */
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
|
||||
GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
|
||||
GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
|
||||
GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_periodic},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
|
||||
GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_start},
|
||||
|
||||
/* 4.2.2.2 Attempt to update / Loc. upd. needed */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
|
||||
SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
|
||||
GSM48_MM_EVENT_USER_PLMN_SEL, gsm48_mm_plmn_search}, /* 4.2.1.2 */
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
|
||||
SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
|
||||
GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_plmn_search}, /* 4.2.1.2 */
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
|
||||
SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
|
||||
GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* change */
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
|
||||
GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
|
||||
GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
|
||||
GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_periodic},
|
||||
|
||||
/* 4.2.2.3 Limited service */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
|
||||
GSM48_MM_EVENT_USER_PLMN_SEL, gsm48_mm_plmn_search}, /* 4.2.1.2 */
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
|
||||
GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_plmn_search}, /* 4.2.1.2 */
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
|
||||
GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* if allow. */
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
|
||||
GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay}, /* 4.4.2 */
|
||||
GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
|
||||
|
||||
/* 4.2.2.4 No IMSI */
|
||||
/* 4.2.2.5 PLMN search, normal service */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
|
||||
GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found}, /* 4.2.1.1 */
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
|
||||
GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
|
||||
#warning MUST DELAY
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
|
||||
GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd},
|
||||
#warning MUST DELAY
|
||||
GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd_delay_retry},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
|
||||
GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd},
|
||||
GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd_delay_retry},
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
|
||||
GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay}, /* 4.4.2 */
|
||||
GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
|
||||
GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_start},
|
||||
|
||||
/* 4.2.2.6 PLMN search */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
|
||||
GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found}, /* 4.2.1.1 */
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
|
||||
GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
|
||||
GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay}, /* 4.4.2 */
|
||||
GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
|
||||
|
||||
/* No cell available */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_CELL_AVAIL),
|
||||
GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
|
||||
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_CELL_AVAIL),
|
||||
GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay}, /* 4.4.2 */
|
||||
GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
|
||||
|
||||
/* IMSI detach in other cases */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES, /* silently detach */
|
||||
GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_end},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
|
||||
SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
|
||||
SBIT(GSM48_MM_ST_PROCESS_CM_SERV_P) |
|
||||
|
@ -3732,35 +3873,46 @@ static struct eventstate {
|
|||
SBIT(GSM48_MM_ST_MM_CONN_ACTIVE_VGCS) |
|
||||
SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES, /* we can release */
|
||||
GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_release},
|
||||
|
||||
{SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D) |
|
||||
SBIT(GSM48_MM_ST_IMSI_DETACH_INIT) |
|
||||
SBIT(GSM48_MM_ST_IMSI_DETACH_PEND), ALL_STATES, /* ignore */
|
||||
GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_ignore},
|
||||
|
||||
{ALL_STATES, ALL_STATES,
|
||||
GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_delay},
|
||||
|
||||
{GSM48_MM_ST_IMSI_DETACH_INIT, ALL_STATES,
|
||||
GSM48_MM_EVENT_TIMEOUT_T3220, gsm48_mm_imsi_detach_end},
|
||||
|
||||
/* location update in other cases */
|
||||
{ALL_STATES, ALL_STATES,
|
||||
GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_ignore},
|
||||
|
||||
{ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
|
||||
GSM48_MM_EVENT_TIMEOUT_T3210, gsm48_mm_loc_upd_timeout},
|
||||
|
||||
{ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
|
||||
GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd_failed},
|
||||
/* 4.4.4.9 c) (but without retry) */
|
||||
|
||||
/* SYSINFO event */
|
||||
{ALL_STATES, ALL_STATES,
|
||||
GSM48_MM_EVENT_SYSINFO, gsm48_mm_sysinfo},
|
||||
|
||||
/* T3240 timed out */
|
||||
{SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD) |
|
||||
SBIT(GSM48_MM_ST_LOC_UPD_REJ), ALL_STATES, /* 4.4.4.8 */
|
||||
GSM48_MM_EVENT_TIMEOUT_T3240, gsm48_mm_abort_rr},
|
||||
|
||||
/* T3230 timed out */
|
||||
{SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
|
||||
GSM48_MM_EVENT_TIMEOUT_T3230, gsm48_mm_timeout_mm_con},
|
||||
|
||||
/* SIM reports SRES */
|
||||
{ALL_STATES, ALL_STATES, /* 4.3.2.2 */
|
||||
GSM48_MM_EVENT_AUTH_RESPONSE, gsm48_mm_tx_auth_rsp},
|
||||
|
||||
#if 0
|
||||
/* change in classmark is reported */
|
||||
{ALL_STATES, ALL_STATES,
|
||||
|
|
|
@ -336,6 +336,7 @@ static void timeout_rr_t3126(void *arg)
|
|||
struct msgb *msg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
|
||||
struct gsm48_rr_hdr *rrh;
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Requesting channel failed\n");
|
||||
if (!msg)
|
||||
return;
|
||||
rrh = (struct gsm48_rr_hdr *)msg->data;
|
||||
|
@ -722,6 +723,9 @@ static int gsm48_rr_chan_req(struct osmocom_ms *ms, int cause, int paging)
|
|||
uint8_t chan_req_val, chan_req_mask;
|
||||
int rc;
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Establish radio link due to %s request\n",
|
||||
(paging) ? "paging" : "mobility management");
|
||||
|
||||
/* ignore paging, if not camping */
|
||||
if (paging
|
||||
&& (!cs->selected || (cs->state != GSM322_C3_CAMPED_NORMALLY
|
||||
|
@ -862,6 +866,8 @@ static int gsm48_rr_chan_req(struct osmocom_ms *ms, int cause, int paging)
|
|||
LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: with unknown "
|
||||
"establishment cause: %d\n", cause);
|
||||
undefined:
|
||||
LOGP(DSUM, LOGL_INFO, "Requesting channel failed\n");
|
||||
|
||||
nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
|
@ -911,6 +917,7 @@ int gsm48_rr_tx_rand_acc(struct osmocom_ms *ms, struct msgb *msg)
|
|||
gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
|
||||
struct gsm48_rr_hdr *rrh;
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Requesting channel failed\n");
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
rrh = (struct gsm48_rr_hdr *)msg->data;
|
||||
|
@ -2838,8 +2845,8 @@ static int gsm48_rr_dl_est(struct osmocom_ms *ms)
|
|||
static int gsm48_rr_estab_cnf(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
struct gsm48_rrlayer *rr = &ms->rrlayer;
|
||||
struct msgb *nmsg;
|
||||
uint8_t *mode;
|
||||
struct msgb *nmsg;
|
||||
|
||||
/* if MM has releases before confirm, we start release */
|
||||
if (rr->state == GSM48_RR_ST_IDLE) {
|
||||
|
@ -2913,6 +2920,8 @@ static int gsm48_rr_est_req(struct osmocom_ms *ms, struct msgb *msg)
|
|||
LOGP(DRR, LOGL_INFO, "T3122 running, rejecting!\n");
|
||||
cause = RR_REL_CAUSE_T3122;
|
||||
reject:
|
||||
LOGP(DSUM, LOGL_INFO, "Establishing radio link not "
|
||||
"possible\n");
|
||||
nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
|
@ -3230,6 +3239,89 @@ for(i=0;i<msgb_l3len(msg);i++)
|
|||
}
|
||||
}
|
||||
|
||||
/* 3.4.13.3 RR abort in dedicated mode (also in conn. pending mode) */
|
||||
static int gsm48_rr_abort_req(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
struct gsm48_rrlayer *rr = &ms->rrlayer;
|
||||
uint8_t *mode;
|
||||
|
||||
/* stop pending RACH timer */
|
||||
stop_rr_t3126(rr);
|
||||
|
||||
/* release "normally" if we are in dedicated mode */
|
||||
if (rr->state == GSM48_RR_ST_DEDICATED) {
|
||||
struct msgb *nmsg;
|
||||
|
||||
LOGP(DRR, LOGL_INFO, "Abort in dedicated state, send release "
|
||||
"to layer 2.\n");
|
||||
/* release message */
|
||||
nmsg = gsm48_l3_msgb_alloc();
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
mode = msgb_put(nmsg, 2);
|
||||
mode[0] = RSL_IE_RELEASE_MODE;
|
||||
mode[1] = 0; /* normal release */
|
||||
return gsm48_send_rsl(ms, RSL_MT_REL_REQ, nmsg);
|
||||
}
|
||||
|
||||
LOGP(DRR, LOGL_INFO, "Abort in connection pending state, return to "
|
||||
"idle state.\n");
|
||||
/* return idle */
|
||||
new_rr_state(rr, GSM48_RR_ST_IDLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* release confirm in dedicated mode */
|
||||
static int gsm48_rr_susp_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
struct gsm48_rrlayer *rr = &ms->rrlayer;
|
||||
|
||||
if (rr->hando_susp_state || rr->assign_susp_state) {
|
||||
struct msgb *nmsg;
|
||||
|
||||
/* change radio to new channel */
|
||||
tx_ph_dm_est_req(ms, rr->cd_now.arfcn, rr->cd_now.chan_nr);
|
||||
|
||||
/* send DL-ESTABLISH REQUEST */
|
||||
nmsg = gsm48_l3_msgb_alloc();
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
gsm48_send_rsl(ms, RSL_MT_EST_REQ, nmsg);
|
||||
|
||||
#ifdef TODO
|
||||
/* trigger RACH */
|
||||
if (rr->hando_susp_state) {
|
||||
gsm48_rr_tx_hando_access(ms);
|
||||
rr->hando_acc_left = 3;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* release confirm in dedicated mode (abort) */
|
||||
static int gsm48_rr_rel_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
struct gsm48_rrlayer *rr = &ms->rrlayer;
|
||||
struct msgb *nmsg;
|
||||
struct gsm48_rr_hdr *nrrh;
|
||||
|
||||
LOGP(DSUM, LOGL_INFO, "Requesting channel aborted\n");
|
||||
|
||||
/* send release indication */
|
||||
nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
nrrh = (struct gsm48_rr_hdr *)nmsg->data;
|
||||
nrrh->cause = RR_REL_CAUSE_UNDEFINED;
|
||||
gsm48_rr_upmsg(ms, nmsg);
|
||||
|
||||
/* return idle */
|
||||
new_rr_state(rr, GSM48_RR_ST_IDLE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* state machines
|
||||
*/
|
||||
|
@ -3240,32 +3332,46 @@ static struct dldatastate {
|
|||
int type;
|
||||
int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
|
||||
} dldatastatelist[] = {
|
||||
{SBIT(GSM48_RR_ST_IDLE) | SBIT(GSM48_RR_ST_CONN_PEND) |
|
||||
{SBIT(GSM48_RR_ST_IDLE) |
|
||||
SBIT(GSM48_RR_ST_CONN_PEND) |
|
||||
SBIT(GSM48_RR_ST_DEDICATED),
|
||||
RSL_MT_UNIT_DATA_IND, gsm48_rr_unit_data_ind},
|
||||
|
||||
{SBIT(GSM48_RR_ST_DEDICATED), /* 3.4.2 */
|
||||
RSL_MT_DATA_IND, gsm48_rr_data_ind},
|
||||
{SBIT(GSM48_RR_ST_IDLE) | SBIT(GSM48_RR_ST_CONN_PEND),
|
||||
|
||||
{SBIT(GSM48_RR_ST_IDLE) |
|
||||
SBIT(GSM48_RR_ST_CONN_PEND),
|
||||
RSL_MT_EST_CONF, gsm48_rr_estab_cnf},
|
||||
|
||||
#if 0
|
||||
{SBIT(GSM48_RR_ST_DEDICATED),
|
||||
RSL_MT_EST_CONF, gsm48_rr_estab_cnf_dedicated},
|
||||
|
||||
{SBIT(GSM_RRSTATE),
|
||||
RSL_MT_CONNECT_CNF, gsm48_rr_connect_cnf},
|
||||
|
||||
{SBIT(GSM_RRSTATE),
|
||||
RSL_MT_RELEASE_IND, gsm48_rr_rel_ind},
|
||||
#endif
|
||||
{SBIT(GSM48_RR_ST_IDLE) | SBIT(GSM48_RR_ST_CONN_PEND),
|
||||
|
||||
{SBIT(GSM48_RR_ST_IDLE) |
|
||||
SBIT(GSM48_RR_ST_CONN_PEND),
|
||||
RSL_MT_REL_CONF, gsm48_rr_rel_cnf},
|
||||
#if 0
|
||||
|
||||
{SBIT(GSM48_RR_ST_DEDICATED),
|
||||
RSL_MT_REL_CONF, gsm48_rr_rel_cnf_dedicated},
|
||||
#endif
|
||||
|
||||
{SBIT(GSM48_RR_ST_DEDICATED),
|
||||
RSL_MT_SUSP_CONF, gsm48_rr_susp_cnf_dedicated},
|
||||
|
||||
{SBIT(GSM48_RR_ST_CONN_PEND), /* 3.3.1.1.2 */
|
||||
RSL_MT_CHAN_CNF, gsm48_rr_tx_rand_acc},
|
||||
|
||||
#if 0
|
||||
{SBIT(GSM48_RR_ST_DEDICATED),
|
||||
RSL_MT_CHAN_CNF, gsm48_rr_rand_acc_cnf_dedicated},
|
||||
|
||||
{SBIT(GSM_RRSTATE),
|
||||
RSL_MT_MDL_ERROR_IND, gsm48_rr_mdl_error_ind},
|
||||
#endif
|
||||
|
@ -3316,11 +3422,15 @@ static struct rrdownstate {
|
|||
} rrdownstatelist[] = {
|
||||
{SBIT(GSM48_RR_ST_IDLE), /* 3.3.1.1 */
|
||||
GSM48_RR_EST_REQ, gsm48_rr_est_req},
|
||||
|
||||
{SBIT(GSM48_RR_ST_DEDICATED), /* 3.4.2 */
|
||||
GSM48_RR_DATA_REQ, gsm48_rr_data_req},
|
||||
#if 0
|
||||
{SBIT(GSM48_RR_ST_CONN_PEND) | SBIT(GSM48_RR_ST_DEDICATED),
|
||||
|
||||
{SBIT(GSM48_RR_ST_CONN_PEND) |
|
||||
SBIT(GSM48_RR_ST_DEDICATED), /* 3.4.13.3 */
|
||||
GSM48_RR_ABORT_REQ, gsm48_rr_abort_req},
|
||||
|
||||
#if 0
|
||||
{SBIT(GSM48_RR_ST_DEDICATED),
|
||||
GSM48_RR_ACT_REQ, gsm48_rr_act_req},
|
||||
#endif
|
||||
|
@ -3440,7 +3550,6 @@ queue messages (rslms_data_req) if channel changes
|
|||
|
||||
flush rach msg in all cases: during sending, after its done, and when aborted
|
||||
stop timers on abort
|
||||
debugging. (wenn dies todo erledigt ist, bitte in den anderen code moven)
|
||||
wird beim abbruch immer der gepufferte cm-service-request entfernt, auch beim verschicken?:
|
||||
measurement reports
|
||||
todo rr_sync_ind when receiving ciph, re ass, channel mode modify
|
||||
|
@ -3456,25 +3565,6 @@ they queue must be flushed when rr fails
|
|||
#include <osmocore/utils.h>
|
||||
#include <osmocore/gsm48.h>
|
||||
|
||||
static int gsm48_rr_abort_req(struct osmocom_ms *ms, struct gsm48_rr *rrmsg)
|
||||
{
|
||||
struct gsm48_rrlayer *rr = ms->rrlayer;
|
||||
uint8_t *mode;
|
||||
|
||||
stop_rr_t3126(rr);
|
||||
if (rr->state == GSM48_RR_ST_DEDICATED) {
|
||||
/* release message */
|
||||
nmsg = gsm48_l3_msgb_alloc();
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
mode = msgb_put(nmsg, 2);
|
||||
mode[0] = RSL_IE_RELEASE_MODE;
|
||||
mode[1] = 0; /* normal release */
|
||||
return gsm48_send_rsl(ms, RSL_MT_REL_REQ, nmsg);
|
||||
}
|
||||
new_rr_state(rr, GSM48_RR_ST_IDLE);
|
||||
}
|
||||
|
||||
static int gsm48_rr_act_req(struct osmocom_ms *ms, struct gsm48_rr *rrmsg)
|
||||
{
|
||||
}
|
||||
|
@ -3741,31 +3831,6 @@ static int gsm48_rr_rel_ind(struct osmocom_ms *ms, struct msgb *msg)
|
|||
{
|
||||
}
|
||||
|
||||
static int gsm48_rr_rel_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
struct gsm48_rrlayer *rr = ms->rrlayer;
|
||||
struct msgb *nmsg;
|
||||
|
||||
if (rr->hando_susp_state || rr->assign_susp_state) {
|
||||
struct msgb *msg;
|
||||
|
||||
/* change radio to new channel */
|
||||
tx_ph_dm_est_req(ms, rr->cd_now.arfcn, rr->cd_now.chan_nr);
|
||||
|
||||
nmsg = gsm48_l3_msgb_alloc();
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
/* send DL-ESTABLISH REQUEST */
|
||||
gsm48_send_rsl(ms, RSL_MT_EST_REQ, nmsg);
|
||||
|
||||
}
|
||||
if (rr->hando_susp_state) {
|
||||
gsm48_rr_tx_hando_access(ms);
|
||||
rr->hando_acc_left = 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gsm48_rr_mdl_error_ind(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
struct gsm48_rrlayer *rr = ms->rrlayer;
|
||||
|
|
Loading…
Reference in New Issue