static int gsm322_cs_select(struct osmocom_ms *ms, int any, int plmn_allowed);
static int gsm322_m_switch_on(struct osmocom_ms *ms, struct msgb *msg);
+#define SKIP_MAX_PER_BAND
+
#warning HACKING!!!
int hack;
{
struct osmocom_ms *ms = cs->ms;
struct gsm48_sysinfo *s = cs->si;
+ struct rx_meas_stat *meas = &ms->meas;
- LOGP(DCS, LOGL_INFO, "Start syncing. (ARFCN=%d)\n", cs->arfcn);
cs->ccch_state = GSM322_CCCH_ST_INIT;
- if (s) {
+ if (s && s->si3) {
if (s->ccch_conf == 1) {
- LOGP(DCS, LOGL_INFO, "Sysinfo, ccch mode COMB\n");
+ LOGP(DCS, LOGL_INFO, "Sync to ARFCN=%d rxlev=%s "
+ "(Sysinfo, ccch mode COMB)\n", cs->arfcn,
+ gsm_print_rxlev(cs->list[cs->arfcn].rxlev));
cs->ccch_mode = CCCH_MODE_COMBINED;
} else {
- LOGP(DCS, LOGL_INFO, "Sysinfo, ccch mode NON-COMB\n");
+ LOGP(DCS, LOGL_INFO, "Sync to ARFCN=%d rxlev=%s "
+ "(Sysinfo, ccch mode NON-COMB)\n", cs->arfcn,
+ gsm_print_rxlev(cs->list[cs->arfcn].rxlev));
cs->ccch_mode = CCCH_MODE_NON_COMBINED;
}
} else {
- LOGP(DCS, LOGL_INFO, "No sysinfo, ccch mode NONE\n");
+ LOGP(DCS, LOGL_INFO, "Sync to ARFCN=%d rxlev=%s (No sysinfo "
+ "yet, ccch mode NONE)\n", cs->arfcn,
+ gsm_print_rxlev(cs->list[cs->arfcn].rxlev));
cs->ccch_mode = CCCH_MODE_NONE;
}
-// printf("s->ccch_conf %d\n", cs->si->ccch_conf);
+
+ meas->frames = meas->snr = meas->berr = meas->rxlev = 0;
l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
return l1ctl_tx_fbsb_req(ms, cs->arfcn,
static void gsm322_unselect_cell(struct gsm322_cellsel *cs)
{
cs->selected = 0;
+ if (cs->si)
+ cs->si->si5 = 0; /* unset SI5* */
cs->si = NULL;
memset(&cs->sel_si, 0, sizeof(cs->sel_si));
cs->sel_mcc = cs->sel_mnc = cs->sel_lac = cs->sel_id = 0;
/* start cell selection timer */
void start_cs_timer(struct gsm322_cellsel *cs, int sec, int micro)
{
- LOGP(DCS, LOGL_INFO, "Starting CS timer with %d seconds.\n", sec);
+ LOGP(DCS, LOGL_DEBUG, "Starting CS timer with %d seconds.\n", sec);
cs->timer.cb = gsm322_cs_timeout;
cs->timer.data = cs;
bsc_schedule_timer(&cs->timer, sec, micro);
}
-/* start loss timer */
-void start_loss_timer(struct gsm322_cellsel *cs, int sec, int micro)
-{
- /* update timer */
- cs->timer.cb = gsm322_cs_loss;
- cs->timer.data = cs;
- if (bsc_timer_pending(&cs->timer)) {
- struct timeval current_time;
- unsigned long long currentTime;
-
- gettimeofday(¤t_time, NULL);
- currentTime = current_time.tv_sec * 1000000LL
- + current_time.tv_usec;
- currentTime += sec * 1000000LL + micro;
- cs->timer.timeout.tv_sec = currentTime / 1000000LL;
- cs->timer.timeout.tv_usec = currentTime % 1000000LL;
-
- return;
- }
-
- LOGP(DCS, LOGL_INFO, "Starting loss CS timer with %d seconds.\n", sec);
- bsc_schedule_timer(&cs->timer, sec, micro);
-}
-
/* stop cell selection timer */
static void stop_cs_timer(struct gsm322_cellsel *cs)
{
if (bsc_timer_pending(&cs->timer)) {
- LOGP(DCS, LOGL_INFO, "stopping pending CS timer.\n");
+ LOGP(DCS, LOGL_DEBUG, "stopping pending CS timer.\n");
bsc_del_timer(&cs->timer);
}
}
/* set out access class depending on the cell selection type */
if (any) {
acc_class = subscr->acc_class | 0x0400; /* add emergency */
- LOGP(DCS, LOGL_INFO, "Select using access class with Emergency "
- "class.\n");
+ LOGP(DCS, LOGL_DEBUG, "Select using access class with "
+ "Emergency class.\n");
} else {
acc_class = subscr->acc_class;
- LOGP(DCS, LOGL_INFO, "Select using access class \n");
+ LOGP(DCS, LOGL_DEBUG, "Select using access class \n");
}
/* flags to match */
static int gsm322_cs_scan(struct osmocom_ms *ms)
{
struct gsm322_cellsel *cs = &ms->cellsel;
- int i, j;
+ int i;
+#ifndef SKIP_MAX_PER_BAND
+ int j;
+#endif
uint8_t mask, flags;
uint32_t weight = 0, test = cs->scan_state;
mask |= GSM322_CS_FLAG_BA;
flags = mask; /* all masked flags are requied */
for (i = 0; i <= 1023; i++) {
+#ifndef SKIP_MAX_PER_BAND
/* skip if band has enough frequencies scanned (3.2.1) */
for (j = 0; gsm_sup_smax[j].max; j++) {
if (gsm_sup_smax[j].end > gsm_sup_smax[j].start) {
if (gsm_sup_smax[j].temp == gsm_sup_smax[j].max)
continue;
}
+#endif
/* search for unscanned frequency */
if ((cs->list[i].flags & mask) == flags) {
/* weight depends on the power level
gsm_print_rxlev(cs->list[cs->arfcn].rxlev));
hack = 1;
gsm322_sync_to_cell(cs);
-// start_cs_timer(cs, ms->support.sync_to, 0);
return 0;
}
/* Tune to frequency for a while, to receive broadcasts. */
cs->arfcn = weight & 1023;
- LOGP(DCS, LOGL_INFO, "Scanning frequency %d (rxlev %s).\n", cs->arfcn,
+ LOGP(DCS, LOGL_DEBUG, "Scanning frequency %d (rxlev %s).\n", cs->arfcn,
gsm_print_rxlev(cs->list[cs->arfcn].rxlev));
hack = 1;
gsm322_sync_to_cell(cs);
-// start_cs_timer(cs, ms->support.sync_to, 0);
/* Allocate/clean system information. */
cs->list[cs->arfcn].flags &= ~GSM322_CS_FLAG_SYSINFO;
cs->si = cs->list[cs->arfcn].sysinfo;
/* increase scan counter for each maximum scan range */
+#ifndef SKIP_MAX_PER_BAND
if (gsm_sup_smax[j].max) {
- LOGP(DCS, LOGL_INFO, "%d frequencies left in band %d..%d\n",
+ LOGP(DCS, LOGL_DEBUG, "%d frequencies left in band %d..%d\n",
gsm_sup_smax[j].max - gsm_sup_smax[j].temp,
gsm_sup_smax[j].start, gsm_sup_smax[j].end);
gsm_sup_smax[j].temp++;
}
+#endif
return 0;
}
cs->list[cs->arfcn].flags &= ~GSM322_CS_FLAG_FORBIDD;
}
- LOGP(DCS, LOGL_INFO, "Scan frequency %d: Cell found. (rxlev %s "
+ LOGP(DCS, LOGL_DEBUG, "Scan frequency %d: Cell found. (rxlev %s "
"mcc %s mnc %s lac %04x)\n", cs->arfcn,
gsm_print_rxlev(cs->list[cs->arfcn].rxlev),
gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), s->lac);
llist_add_tail(&ba->entry, &cs->ba_list);
}
/* update (add) ba list */
- memcpy(freq, ba->freq, sizeof(freq));
+ memset(freq, 0, sizeof(freq));
for (i = 0; i <= 1023; i++) {
- if ((s->freq[i].mask & FREQ_TYPE_REP))
+ if ((s->freq[i].mask & (FREQ_TYPE_SERV
+ | FREQ_TYPE_NCELL | FREQ_TYPE_REP)))
freq[i >> 3] |= (1 << (i & 7));
}
if (!!memcmp(freq, ba->freq, sizeof(freq))) {
freq[cs->arfcn >> 3] |= (1 << (cs->arfcn & 7));
for (i = 0; i <= 1023; i++) {
if ((s->freq[i].mask &
- (FREQ_TYPE_SERV | FREQ_TYPE_NCELL)))
+ (FREQ_TYPE_SERV | FREQ_TYPE_NCELL | FREQ_TYPE_REP)))
freq[i >> 3] |= (1 << (i & 7));
}
if (!!memcmp(freq, ba->freq, sizeof(freq))) {
|| (s->si2bis && s->nb_ext_ind_si2 && !s->nb_ext_ind_si2bis)
|| (s->si2bis && s->si2ter && s->nb_ext_ind_si2
&& s->nb_ext_ind_si2bis))) {
- LOGP(DCS, LOGL_INFO, "Received relevant sysinfo.\n");
+ LOGP(DCS, LOGL_DEBUG, "Received relevant sysinfo.\n");
/* stop timer */
stop_cs_timer(cs);
struct gsm322_cellsel *cs = arg;
struct osmocom_ms *ms = cs->ms;
- LOGP(DCS, LOGL_INFO, "Cell selection failed.\n");
-
/* if we have no lock, we retry */
if (cs->ccch_state != GSM322_CCCH_ST_SYNC)
- LOGP(DCS, LOGL_INFO, "Sync timeout.\n");
+ LOGP(DCS, LOGL_INFO, "Cell selection failed, sync timeout.\n");
else
- LOGP(DCS, LOGL_INFO, "Read timeout.\n");
-
- LOGP(DCS, LOGL_INFO, "Scan frequency %d: Cell not found. (rxlev %s)\n",
- cs->arfcn, gsm_print_rxlev(cs->list[cs->arfcn].rxlev));
+ LOGP(DCS, LOGL_INFO, "Cell selection failed, read timeout.\n");
/* remove system information */
cs->list[cs->arfcn].flags &= ~GSM322_CS_FLAG_SYSINFO;
if (cs->list[cs->arfcn].sysinfo) {
- LOGP(DCS, LOGL_INFO, "free sysinfo arfcn=%d\n", cs->arfcn);
+ LOGP(DCS, LOGL_DEBUG, "free sysinfo arfcn=%d\n", cs->arfcn);
talloc_free(cs->list[cs->arfcn].sysinfo);
cs->list[cs->arfcn].sysinfo = NULL;
gsm322_unselect_cell(cs);
/* in case of sticking to a cell, we only select it */
if (set->stick) {
- LOGP(DCS, LOGL_FATAL, "Scanning power for sticked cell.\n");
+ LOGP(DCS, LOGL_DEBUG, "Scanning power for sticked cell.\n");
i = set->stick_arfcn;
if ((cs->list[i].flags & mask) == flags)
s = e = i;
/* search for first frequency to scan */
if (cs->state == GSM322_C2_STORED_CELL_SEL
|| cs->state == GSM322_C5_CHOOSE_CELL) {
- LOGP(DCS, LOGL_FATAL, "Scanning power for stored BA "
+ LOGP(DCS, LOGL_DEBUG, "Scanning power for stored BA "
"list.\n");
mask |= GSM322_CS_FLAG_BA;
flags |= GSM322_CS_FLAG_BA;
} else
- LOGP(DCS, LOGL_FATAL, "Scanning power for all "
+ LOGP(DCS, LOGL_DEBUG, "Scanning power for all "
"frequencies.\n");
for (i = 0; i <= 1023; i++) {
if ((cs->list[i].flags & mask) == flags) {
cs->list[cs->arfcn].rxlev));
hack = 1;
gsm322_sync_to_cell(cs);
-// start_cs_timer(cs, ms->support.sync_to, 0);
} else
new_c_state(cs, GSM322_C0_NULL);
}
}
- LOGP(DCS, LOGL_INFO, "Scanning frequencies. (%d..%d)\n", s, e);
+ LOGP(DCS, LOGL_DEBUG, "Scanning frequencies. (%d..%d)\n", s, e);
/* start scan on radio interface */
if (!cs->powerscan) {
struct osmocom_ms *ms;
struct gsm322_cellsel *cs;
struct osmobb_meas_res *mr;
+ struct osmobb_fbsb_res *fr;
int i;
int8_t rxlev;
return -EINVAL;
i = mr->band_arfcn & 1023;
rxlev = mr->rx_lev;
+ if ((cs->list[i].flags & GSM322_CS_FLAG_POWER)) {
+ LOGP(DCS, LOGL_ERROR, "Getting PM for frequency %d "
+ "twice. Overwriting the first! Please fix "
+ "prim_pm.c\n", i);
+ }
cs->list[i].rxlev = rxlev;
cs->list[i].flags |= GSM322_CS_FLAG_POWER;
+ cs->list[i].flags &= ~GSM322_CS_FLAG_SIGNAL;
/* if minimum level is reached or if we stick to a cell */
- if (rxlev2dbm(rxlev) >= ms->support.min_rxlev_db
+ if (rxlev2dbm(rxlev) >= ms->settings.min_rxlev_db
|| ms->settings.stick) {
cs->list[i].flags |= GSM322_CS_FLAG_SIGNAL;
LOGP(DCS, LOGL_INFO, "Found signal (frequency %d "
}
break;
case S_L1CTL_PM_DONE:
- LOGP(DCS, LOGL_INFO, "Done with power scanning range.\n");
+ LOGP(DCS, LOGL_DEBUG, "Done with power scanning range.\n");
ms = signal_data;
cs = &ms->cellsel;
if (!cs->powerscan)
gsm322_cs_powerscan(ms);
break;
case S_L1CTL_FBSB_RESP:
- ms = signal_data;
+ fr = signal_data;
+ ms = fr->ms;
cs = &ms->cellsel;
if (cs->ccch_state == GSM322_CCCH_ST_INIT) {
- LOGP(DCS, LOGL_INFO, "Channel synched. (ARFCN=%d)\n",
- cs->arfcn);
+ LOGP(DCS, LOGL_INFO, "Channel synched. (ARFCN=%d, "
+ "snr=%u, BSIC=%u)\n", cs->arfcn, fr->snr,
+ fr->bsic);
cs->ccch_state = GSM322_CCCH_ST_SYNC;
+ if (cs->si)
+ cs->si->bsic = fr->bsic;
#if 0
stop_cs_timer(cs);
|| cs->state == GSM322_HPLMN_SEARCH)
start_cs_timer(cs, ms->support.scan_to, 0);
// TODO: timer depends on BCCH config
+
+ /* set downlink signalling failure criterion */
+ ms->meas.ds_fail = ms->meas.dsc = ms->settings.dsc_max;
+ LOGP(DRR, LOGL_INFO, "using DSC of %d\n", ms->meas.dsc);
}
break;
case S_L1CTL_FBSB_ERR:
+#if 0
if (hack) {
ms = signal_data;
cs = &ms->cellsel;
gsm322_sync_to_cell(cs);
hack--;
- LOGP(DCS, LOGL_INFO, "Channel sync error, try again.\n");
+ LOGP(DCS, LOGL_INFO, "Channel sync error, try again\n");
break;
}
+#endif
LOGP(DCS, LOGL_INFO, "Channel sync error.\n");
ms = signal_data;
cs = &ms->cellsel;
else
gsm322_cs_timeout(cs);
break;
+ case S_L1CTL_LOSS_IND:
+ ms = signal_data;
+ cs = &ms->cellsel;
+ gsm322_cs_loss(cs);
+ break;
case S_L1CTL_RESET:
ms = signal_data;
if (ms->mmlayer.power_off_idle) {
if (!subscr->sim_valid) {
LOGP(DCS, LOGL_INFO, "Switch on without SIM.\n");
return gsm322_c_any_cell_sel(ms, msg);
- LOGP(DCS, LOGL_INFO, "Switch on with SIM inserted.\n");
}
+ LOGP(DCS, LOGL_INFO, "Switch on with SIM inserted.\n");
/* stay in NULL state until PLMN is selected */
{ALL_STATES,
GSM322_EVENT_SWITCH_OFF, gsm322_a_switch_off},
- {SBIT(GSM322_A6_NO_SIM),
+ {SBIT(GSM322_A0_NULL) | SBIT(GSM322_A6_NO_SIM),
GSM322_EVENT_SIM_INSERT, gsm322_a_switch_on},
{ALL_STATES,
{ALL_STATES,
GSM322_EVENT_SWITCH_OFF, gsm322_m_switch_off},
- {SBIT(GSM322_M5_NO_SIM),
+ {SBIT(GSM322_M0_NULL) | SBIT(GSM322_M5_NO_SIM),
GSM322_EVENT_SIM_INSERT, gsm322_m_switch_on},
{ALL_STATES,
int rc;
int i;
- LOGP(DCS, LOGL_INFO, "(ms %s) Event '%s' for Cell selection in state "
- "'%s'\n", ms->name, get_event_name(msg_type),
- cs_state_names[cs->state]);
+ if (msg_type != GSM322_EVENT_SYSINFO)
+ LOGP(DCS, LOGL_INFO, "(ms %s) Event '%s' for Cell selection "
+ "in state '%s'\n", ms->name, get_event_name(msg_type),
+ cs_state_names[cs->state]);
/* find function for current state and message */
for (i = 0; i < CELLSELSLLEN; i++)
if ((msg_type == cellselstatelist[i].type)