Fixed many issues in MM IDLE mode process.
This commit is contained in:
parent
30b48d6212
commit
8e5f33b4d3
|
@ -140,6 +140,10 @@ struct gsm322_cellsel {
|
|||
uint8_t powerscan; /* currently scanning for power */
|
||||
uint32_t scan_state; /* special state of current scan */
|
||||
uint8_t ccch_active; /* set, if ccch is active */
|
||||
|
||||
uint8_t selected; /* if a cell is selected */
|
||||
uint16_t selected_arfcn;
|
||||
uint16_t selected_mcc, selected_mnc, selected_lac;
|
||||
};
|
||||
|
||||
/* GSM 03.22 message */
|
||||
|
|
|
@ -117,11 +117,12 @@ struct gsm48_mmr {
|
|||
#define GSM48_MM_SST_RX_VGCS_LIMITED 10
|
||||
|
||||
/* MM events */
|
||||
#define GSM48_MM_EVENT_NEW_LAI 1
|
||||
#define GSM48_MM_EVENT_TIMEOUT_T3210 2
|
||||
#define GSM48_MM_EVENT_TIMEOUT_T3211 3
|
||||
#define GSM48_MM_EVENT_TIMEOUT_T3212 4
|
||||
#define GSM48_MM_EVENT_TIMEOUT_T3213 5
|
||||
#define GSM48_MM_EVENT_CELL_SELECTED 1
|
||||
#define GSM48_MM_EVENT_NO_CELL_FOUND 2
|
||||
#define GSM48_MM_EVENT_TIMEOUT_T3210 3
|
||||
#define GSM48_MM_EVENT_TIMEOUT_T3211 4
|
||||
#define GSM48_MM_EVENT_TIMEOUT_T3212 5
|
||||
#define GSM48_MM_EVENT_TIMEOUT_T3213 6
|
||||
#define GSM48_MM_EVENT_TIMEOUT_T3220 7
|
||||
#define GSM48_MM_EVENT_TIMEOUT_T3230 8
|
||||
#define GSM48_MM_EVENT_TIMEOUT_T3240 9
|
||||
|
@ -130,6 +131,7 @@ struct gsm48_mmr {
|
|||
#define GSM48_MM_EVENT_PAGING 12
|
||||
#define GSM48_MM_EVENT_AUTH_RESPONSE 13
|
||||
#define GSM48_MM_EVENT_SYSINFO 14
|
||||
#define GSM48_MM_EVENT_USER_PLMN_SEL 15
|
||||
|
||||
/* message for MM events */
|
||||
struct gsm48_mm_event {
|
||||
|
@ -178,6 +180,7 @@ struct gsm48_mmlayer {
|
|||
uint8_t lupd_attempt; /* attempt counter */
|
||||
uint8_t lupd_ra_failure;/* random access failed */
|
||||
uint8_t lupd_rej_cause; /* cause of last reject */
|
||||
uint8_t lupd_periodic; /* periodic update pending */
|
||||
|
||||
/* imsi detach */
|
||||
uint8_t delay_detach; /* do detach when possible */
|
||||
|
|
|
@ -26,7 +26,7 @@ struct gsm_subscriber {
|
|||
/* status */
|
||||
uint8_t sim_valid; /* sim inserted and valid */
|
||||
uint8_t ustate; /* update status */
|
||||
uint8_t sim_att; /* attached state */
|
||||
uint8_t imsi_attached; /* attached state */
|
||||
|
||||
/* LAI */
|
||||
uint8_t lai_valid;
|
||||
|
|
|
@ -1002,6 +1002,12 @@ static int gsm322_a_switch_off(struct osmocom_ms *ms, struct msgb *msg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gsm322_a_sim_insert(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
LOGP(DPLMN, LOGL_INFO, "SIM already inserted when switched on.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SIM is removed */
|
||||
static int gsm322_a_sim_removed(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
|
@ -1054,12 +1060,18 @@ static int gsm322_a_hplmn_search(struct osmocom_ms *ms, struct msgb *msg)
|
|||
static int gsm322_a_sel_manual(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
struct gsm322_plmn *plmn = &ms->plmn;
|
||||
struct msgb *nmsg;
|
||||
|
||||
/* restart state machine */
|
||||
gsm322_a_switch_off(ms, msg);
|
||||
plmn->mode = PLMN_MODE_MANUAL;
|
||||
gsm322_m_switch_on(ms, msg);
|
||||
|
||||
nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_USER_PLMN_SEL);
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
gsm48_mmevent_msg(ms, nmsg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1136,6 +1148,12 @@ static int gsm322_m_switch_off(struct osmocom_ms *ms, struct msgb *msg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gsm322_m_sim_insert(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
LOGP(DPLMN, LOGL_INFO, "SIM already inserted when switched on.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SIM is removed */
|
||||
static int gsm322_m_sim_removed(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
|
@ -1218,12 +1236,18 @@ static int gsm322_m_choose_plmn(struct osmocom_ms *ms, struct msgb *msg)
|
|||
static int gsm322_m_sel_auto(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
struct gsm322_plmn *plmn = &ms->plmn;
|
||||
struct msgb *nmsg;
|
||||
|
||||
/* restart state machine */
|
||||
gsm322_m_switch_off(ms, msg);
|
||||
plmn->mode = PLMN_MODE_AUTO;
|
||||
gsm322_a_switch_on(ms, msg);
|
||||
|
||||
nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_USER_PLMN_SEL);
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
gsm48_mmevent_msg(ms, nmsg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1358,17 +1382,10 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
|
|||
struct gsm322_cellsel *cs = &ms->cellsel;
|
||||
struct gsm_subscriber *subscr = &ms->subscr;
|
||||
struct gsm48_sysinfo *s = &ms->sysinfo;
|
||||
struct gsm48_rrlayer *rr = &ms->rrlayer;
|
||||
int i, j;
|
||||
uint8_t mask, flags;
|
||||
uint32_t weight = 0, test = cs->scan_state;
|
||||
|
||||
if (rr->state != GSM48_RR_ST_IDLE) {
|
||||
LOGP(DCS, LOGL_FATAL, "This must only happen in IDLE mode, "
|
||||
"please fix!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* special prositive case for HPLMN search */
|
||||
if (cs->state == GSM322_HPLMN_SEARCH && s->mcc == subscr->mcc
|
||||
&& s->mnc == subscr->mnc) {
|
||||
|
@ -1473,8 +1490,21 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
|
|||
return -ENOMEM;
|
||||
gsm322_plmn_sendmsg(ms, nmsg);
|
||||
|
||||
/* set selected cell */
|
||||
cs->selected = 1;
|
||||
cs->selected_arfcn = cs->arfcn;
|
||||
cs->selected_mcc = cs->list[cs->arfcn].mcc;
|
||||
cs->selected_mnc = cs->list[cs->arfcn].mnc;
|
||||
cs->selected_lac = cs->list[cs->arfcn].lac;
|
||||
|
||||
/* tell CS process about available cell */
|
||||
nmsg = gsm322_msgb_alloc(GSM322_EVENT_CELL_FOUND);
|
||||
LOGP(DCS, LOGL_INFO, "Cell available.\n");
|
||||
} else {
|
||||
/* unset selected cell */
|
||||
cs->selected = 0;
|
||||
|
||||
/* tell CS process about no cell available */
|
||||
nmsg = gsm322_msgb_alloc(GSM322_EVENT_NO_CELL_FOUND);
|
||||
LOGP(DCS, LOGL_INFO, "No cell available.\n");
|
||||
}
|
||||
|
@ -1635,19 +1665,12 @@ static int gsm322_c_camp_sysinfo_bcch(struct osmocom_ms *ms, struct msgb *msg)
|
|||
static int gsm322_c_scan_sysinfo_bcch(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
struct gsm322_cellsel *cs = &ms->cellsel;
|
||||
struct gsm48_rrlayer *rr = &ms->rrlayer;
|
||||
struct gsm48_sysinfo *s = &ms->sysinfo;
|
||||
struct gsm322_msg *gm = (struct gsm322_msg *) msg->data;
|
||||
struct gsm322_ba_list *ba;
|
||||
int i;
|
||||
uint8_t freq[128];
|
||||
|
||||
if (rr->state != GSM48_RR_ST_IDLE) {
|
||||
LOGP(DCS, LOGL_FATAL, "This must only happen in IDLE mode, "
|
||||
"please fix!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* no sysinfo if we are not done with power scan */
|
||||
if (cs->powerscan) {
|
||||
LOGP(DCS, LOGL_INFO, "Ignoring sysinfo during power scan.\n");
|
||||
|
@ -1745,16 +1768,9 @@ static void gsm322_cs_timeout(void *arg)
|
|||
static int gsm322_cs_powerscan(struct osmocom_ms *ms)
|
||||
{
|
||||
struct gsm322_cellsel *cs = &ms->cellsel;
|
||||
struct gsm48_rrlayer *rr = &ms->rrlayer;
|
||||
int i, s = -1, e;
|
||||
uint8_t mask, flags;
|
||||
|
||||
if (rr->state != GSM48_RR_ST_IDLE) {
|
||||
LOGP(DCS, LOGL_FATAL, "This must only happen in IDLE mode, "
|
||||
"please fix!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
again:
|
||||
|
||||
/* search for first frequency to scan */
|
||||
|
@ -1888,7 +1904,7 @@ static int gsm322_l1_signal(unsigned int subsys, unsigned int signal,
|
|||
|| cs->state == GSM322_C8_ANY_CELL_RESEL
|
||||
|| cs->state == GSM322_C5_CHOOSE_CELL
|
||||
|| cs->state == GSM322_C9_CHOOSE_ANY_CELL)
|
||||
start_cs_timer(cs, 4, 0);
|
||||
start_cs_timer(cs, 8, 0);
|
||||
// TODO: timer depends on BCCH config
|
||||
}
|
||||
break;
|
||||
|
@ -1969,6 +1985,14 @@ static int gsm322_c_any_cell_sel(struct osmocom_ms *ms, struct msgb *msg)
|
|||
|
||||
/* in case we already tried any cell selection, power scan again */
|
||||
if (cs->state == GSM322_C6_ANY_CELL_SEL) {
|
||||
struct msgb *nmsg;
|
||||
|
||||
/* tell that we have no cell found */
|
||||
nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_NO_CELL_FOUND);
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
gsm48_mmevent_msg(ms, nmsg);
|
||||
|
||||
for (i = 0; i <= 1023; i++)
|
||||
cs->list[i].flags &= ~(GSM322_CS_FLAG_POWER
|
||||
| GSM322_CS_FLAG_SIGNAL
|
||||
|
@ -2141,7 +2165,8 @@ static int gsm322_c_camp_normally(struct osmocom_ms *ms, struct msgb *msg)
|
|||
struct gsm322_cellsel *cs = &ms->cellsel;
|
||||
struct msgb *nmsg;
|
||||
|
||||
nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_NEW_LAI);
|
||||
/* tell that we have selected a (new) cell */
|
||||
nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_CELL_SELECTED);
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
gsm48_mmevent_msg(ms, nmsg);
|
||||
|
@ -2155,6 +2180,13 @@ static int gsm322_c_camp_normally(struct osmocom_ms *ms, struct msgb *msg)
|
|||
static int gsm322_c_camp_any_cell(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
struct gsm322_cellsel *cs = &ms->cellsel;
|
||||
struct msgb *nmsg;
|
||||
|
||||
/* tell that we have selected a (new) cell */
|
||||
nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_CELL_SELECTED);
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
gsm48_mmevent_msg(ms, nmsg);
|
||||
|
||||
new_c_state(cs, GSM322_C7_CAMPED_ANY_CELL);
|
||||
|
||||
|
@ -2223,6 +2255,8 @@ static struct plmnastatelist {
|
|||
GSM322_EVENT_SWITCH_OFF, gsm322_a_switch_off},
|
||||
{SBIT(GSM322_A6_NO_SIM),
|
||||
GSM322_EVENT_SIM_INSERT, gsm322_a_switch_on},
|
||||
{ALL_STATES,
|
||||
GSM322_EVENT_SIM_INSERT, gsm322_a_sim_insert},
|
||||
{ALL_STATES,
|
||||
GSM322_EVENT_SIM_REMOVE, gsm322_a_sim_removed},
|
||||
{ALL_STATES,
|
||||
|
@ -2298,6 +2332,8 @@ static struct plmnmstatelist {
|
|||
GSM322_EVENT_SWITCH_OFF, gsm322_m_switch_off},
|
||||
{SBIT(GSM322_M5_NO_SIM),
|
||||
GSM322_EVENT_SIM_INSERT, gsm322_m_switch_on},
|
||||
{ALL_STATES,
|
||||
GSM322_EVENT_SIM_INSERT, gsm322_m_sim_insert},
|
||||
{ALL_STATES,
|
||||
GSM322_EVENT_SIM_REMOVE, gsm322_m_sim_removed},
|
||||
{SBIT(GSM322_M1_TRYING_RPLMN),
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -65,9 +65,9 @@ void gsm_support_init(struct osmocom_ms *ms)
|
|||
s->a5_6 = 0;
|
||||
s->a5_7 = 0;
|
||||
/* radio support */
|
||||
s->p_gsm = 0; /* P-GSM only */
|
||||
s->e_gsm = 1; /* E-GSM */
|
||||
s->r_gsm = 0; /* R-GSM only */
|
||||
s->p_gsm = 1; /* P-GSM only */
|
||||
s->e_gsm = 0; /* E-GSM */
|
||||
s->r_gsm = 0; /* R-GSM */
|
||||
s->r_capa = 0;
|
||||
s->low_capa = 4; /* p,e,r power class */
|
||||
s->dcs_1800 = 0;
|
||||
|
@ -83,6 +83,8 @@ void gsm_support_init(struct osmocom_ms *ms)
|
|||
if (s->e_gsm)
|
||||
for(i = 975; i <= 1023; i++)
|
||||
s->freq_map[i >> 3] |= (1 << (i & 7));
|
||||
// for(i = 978; i <= 978; i++)
|
||||
// s->freq_map[i >> 3] |= (1 << (i & 7));
|
||||
if (s->r_gsm)
|
||||
for(i = 955; i <= 1023; i++)
|
||||
s->freq_map[i >> 3] |= (1 << (i & 7));
|
||||
|
@ -103,7 +105,7 @@ void gsm_support_init(struct osmocom_ms *ms)
|
|||
sprintf(s->imeisv, "0000000000000000");
|
||||
|
||||
/* radio */
|
||||
s->min_rxlev_db = -106;
|
||||
s->min_rxlev_db = -106; // TODO
|
||||
}
|
||||
|
||||
/* (3.2.1) maximum channels to scan within each band */
|
||||
|
|
Loading…
Reference in New Issue