Work on layer 3 processes:
- Fixed reference to system informations. (did crash when re-selecting). - Fix in cell selection state machine. (any re-selection). - MCC, MNC, LAC change of cell now triggers re-selection. - Fixed some paging issues. Empty pagings are not displayed anymore. Also paging is now possible when 'camping on any cell'.
This commit is contained in:
parent
fe1dc19c6e
commit
7f009e41f9
|
@ -75,6 +75,7 @@ struct gsm_support {
|
|||
|
||||
/* radio */
|
||||
int8_t min_rxlev_db;
|
||||
uint8_t scan_to;
|
||||
};
|
||||
|
||||
struct gsm_support_scan_max {
|
||||
|
|
|
@ -102,7 +102,7 @@ int mobile_exit(struct osmocom_ms *ms)
|
|||
|
||||
int l23_app_init(struct osmocom_ms *ms)
|
||||
{
|
||||
log_parse_category_mask(stderr_target, "DCS:DPLMN:DRR:DMM:DCC:DMNCC");
|
||||
log_parse_category_mask(stderr_target, "DCS:DPLMN:DRR:DMM:DCC:DMNCC:DPAG");
|
||||
|
||||
gsm48_cc_init(ms);
|
||||
gsm_support_init(ms);
|
||||
|
|
|
@ -77,6 +77,14 @@ int l1ctl_tx_ccch_req_(struct osmocom_ms *ms, uint16_t arfcn)
|
|||
* if the cell is 'suitable' and 'allowable' to 'camp' on.
|
||||
*
|
||||
* This list is also used to generate a list of available networks.
|
||||
*
|
||||
* The states are:
|
||||
*
|
||||
* - cs->list[0..1023].xxx for each cell, where
|
||||
* - flags and rxlev_db are used to store outcome of cell scanning process
|
||||
* - sysinfo pointing to sysinfo memory, allocated temporarily
|
||||
* - cs->selected and cs->sel_* states of the current / last selected cell.
|
||||
*
|
||||
*/
|
||||
|
||||
/* PLMN selection process
|
||||
|
@ -361,7 +369,8 @@ int gsm322_is_plmn_avail(struct gsm322_cellsel *cs, uint16_t mcc, uint16_t mnc)
|
|||
int i;
|
||||
|
||||
for (i = 0; i <= 1023; i++) {
|
||||
if (cs->list[i].sysinfo->mcc == mcc
|
||||
if (cs->list[i].sysinfo
|
||||
&& cs->list[i].sysinfo->mcc == mcc
|
||||
&& cs->list[i].sysinfo->mnc == mnc)
|
||||
return 1;
|
||||
}
|
||||
|
@ -569,7 +578,8 @@ static int gsm322_sort_list(struct osmocom_ms *ms)
|
|||
/* Create a temporary list of all networks */
|
||||
INIT_LLIST_HEAD(&temp_list);
|
||||
for (i = 0; i <= 1023; i++) {
|
||||
if (!(cs->list[i].flags & GSM322_CS_FLAG_TEMP_AA))
|
||||
if (!(cs->list[i].flags & GSM322_CS_FLAG_TEMP_AA)
|
||||
|| !cs->list[i].sysinfo)
|
||||
continue;
|
||||
|
||||
/* search if network has multiple cells */
|
||||
|
@ -1363,7 +1373,7 @@ static int gsm322_cs_select(struct osmocom_ms *ms, int any)
|
|||
s = cs->list[i].sysinfo;
|
||||
|
||||
/* channel has no informations for us */
|
||||
if ((cs->list[i].flags & mask) != flags) {
|
||||
if (!s || (cs->list[i].flags & mask) != flags) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1576,7 +1586,8 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
|
|||
}
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
gsm322_cs_sendmsg(ms, nmsg);
|
||||
gsm322_c_event(ms, nmsg);
|
||||
msgb_free(nmsg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1592,8 +1603,9 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
|
|||
l1ctl_tx_ccch_req_(ms, cs->arfcn);
|
||||
|
||||
/* Allocate system information. */
|
||||
cs->list[cs->arfcn].sysinfo = talloc_zero(l23_ctx,
|
||||
struct gsm48_sysinfo);
|
||||
if (!cs->list[cs->arfcn].sysinfo)
|
||||
cs->list[cs->arfcn].sysinfo = talloc_zero(l23_ctx,
|
||||
struct gsm48_sysinfo);
|
||||
if (!cs->list[cs->arfcn].sysinfo)
|
||||
exit(-ENOMEM);
|
||||
cs->si = cs->list[cs->arfcn].sysinfo;
|
||||
|
@ -1609,8 +1621,7 @@ static int gsm322_cs_store(struct osmocom_ms *ms)
|
|||
{
|
||||
struct gsm322_cellsel *cs = &ms->cellsel;
|
||||
struct gsm_subscriber *subscr = &ms->subscr;
|
||||
int i = cs->scan_state & 1023;
|
||||
struct gsm48_sysinfo *s = cs->list[i].sysinfo;
|
||||
struct gsm48_sysinfo *s = cs->si;
|
||||
|
||||
if (cs->state != GSM322_C2_STORED_CELL_SEL
|
||||
&& cs->state != GSM322_C1_NORMAL_CELL_SEL
|
||||
|
@ -1625,35 +1636,35 @@ static int gsm322_cs_store(struct osmocom_ms *ms)
|
|||
}
|
||||
|
||||
/* store sysinfo */
|
||||
cs->list[i].flags |= GSM322_CS_FLAG_SYSINFO;
|
||||
cs->list[cs->arfcn].flags |= GSM322_CS_FLAG_SYSINFO;
|
||||
if (s->cell_barr)
|
||||
cs->list[i].flags |= GSM322_CS_FLAG_BARRED;
|
||||
cs->list[cs->arfcn].flags |= GSM322_CS_FLAG_BARRED;
|
||||
else
|
||||
cs->list[i].flags &= ~GSM322_CS_FLAG_BARRED;
|
||||
cs->list[cs->arfcn].flags &= ~GSM322_CS_FLAG_BARRED;
|
||||
|
||||
#if 0
|
||||
cs->list[i].min_db = s->rxlev_acc_min_db;
|
||||
cs->list[i].class_barr = s->class_barr;
|
||||
cs->list[i].max_pwr = s->ms_txpwr_max_ccch;
|
||||
cs->list[cs->arfcn].min_db = s->rxlev_acc_min_db;
|
||||
cs->list[cs->arfcn].class_barr = s->class_barr;
|
||||
cs->list[cs->arfcn].max_pwr = s->ms_txpwr_max_ccch;
|
||||
#endif
|
||||
|
||||
/* store selected network */
|
||||
if (s->mcc) {
|
||||
#if 0
|
||||
cs->list[i].mcc = s->mcc;
|
||||
cs->list[i].mnc = s->mnc;
|
||||
cs->list[i].lac = s->lac;
|
||||
cs->list[cs->arfcn].mcc = s->mcc;
|
||||
cs->list[cs->arfcn].mnc = s->mnc;
|
||||
cs->list[cs->arfcn].lac = s->lac;
|
||||
#endif
|
||||
|
||||
if (gsm322_is_forbidden_la(ms, s->mcc, s->mnc, s->lac))
|
||||
cs->list[i].flags |= GSM322_CS_FLAG_FORBIDD;
|
||||
cs->list[cs->arfcn].flags |= GSM322_CS_FLAG_FORBIDD;
|
||||
else
|
||||
cs->list[i].flags &= ~GSM322_CS_FLAG_FORBIDD;
|
||||
cs->list[cs->arfcn].flags &= ~GSM322_CS_FLAG_FORBIDD;
|
||||
}
|
||||
|
||||
LOGP(DCS, LOGL_INFO, "Scan frequency %d: Cell found. (rxlev=%d "
|
||||
"mcc=%03d mnc=%02d lac=%04x)\n", i, cs->list[i].rxlev_db,
|
||||
s->mcc, s->mnc, s->lac);
|
||||
"mcc=%03d mnc=%02d lac=%04x)\n", cs->arfcn,
|
||||
cs->list[cs->arfcn].rxlev_db, s->mcc, s->mnc, s->lac);
|
||||
|
||||
/* special prositive case for HPLMN search */
|
||||
if (cs->state == GSM322_HPLMN_SEARCH && s->mcc == subscr->mcc
|
||||
|
@ -1802,11 +1813,19 @@ static int gsm322_c_camp_sysinfo_bcch(struct osmocom_ms *ms, struct msgb *msg)
|
|||
trigger_resel:
|
||||
/* mark cell as unscanned */
|
||||
cs->list[cs->arfcn].flags &= ~GSM322_CS_FLAG_SYSINFO;
|
||||
/* trigger reselection event */
|
||||
if (cs->list[cs->arfcn].sysinfo) {
|
||||
talloc_free(cs->list[cs->arfcn].sysinfo);
|
||||
cs->list[cs->arfcn].sysinfo = NULL;
|
||||
}
|
||||
/* trigger reselection without queueing,
|
||||
* because other sysinfo message may be queued
|
||||
* before
|
||||
*/
|
||||
nmsg = gsm322_msgb_alloc(GSM322_EVENT_CELL_RESEL);
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
gsm322_cs_sendmsg(ms, nmsg);
|
||||
gsm322_c_event(ms, nmsg);
|
||||
msgb_free(nmsg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1818,6 +1837,14 @@ static int gsm322_c_camp_sysinfo_bcch(struct osmocom_ms *ms, struct msgb *msg)
|
|||
}
|
||||
}
|
||||
|
||||
/* check if MCC, MNC, LAC changes */
|
||||
if (cs->sel_mcc != s->mcc || cs->sel_mnc != s->mnc
|
||||
|| cs->sel_lac != s->lac) {
|
||||
LOGP(DCS, LOGL_NOTICE, "Cell changes location area. "
|
||||
"This is not good!\n");
|
||||
goto trigger_resel;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1876,17 +1903,16 @@ static void gsm322_cs_timeout(void *arg)
|
|||
{
|
||||
struct gsm322_cellsel *cs = arg;
|
||||
struct osmocom_ms *ms = cs->ms;
|
||||
int i = cs->scan_state & 1023;
|
||||
|
||||
LOGP(DCS, LOGL_INFO, "Cell selection timer has fired.\n");
|
||||
LOGP(DCS, LOGL_INFO, "Scan frequency %d: Cell not found. (rxlev=%d)\n",
|
||||
i, cs->list[i].rxlev_db);
|
||||
cs->arfcn, cs->list[cs->arfcn].rxlev_db);
|
||||
|
||||
/* remove system information */
|
||||
cs->list[i].flags &= ~GSM322_CS_FLAG_SYSINFO;
|
||||
if (cs->list[i].sysinfo) {
|
||||
talloc_free(cs->list[i].sysinfo);
|
||||
cs->list[i].sysinfo = NULL;
|
||||
cs->list[cs->arfcn].flags &= ~GSM322_CS_FLAG_SYSINFO;
|
||||
if (cs->list[cs->arfcn].sysinfo) {
|
||||
talloc_free(cs->list[cs->arfcn].sysinfo);
|
||||
cs->list[cs->arfcn].sysinfo = NULL;
|
||||
}
|
||||
|
||||
/* tune to next cell */
|
||||
|
@ -2053,7 +2079,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, 8, 0);
|
||||
start_cs_timer(cs, ms->support.scan_to, 0);
|
||||
// TODO: timer depends on BCCH config
|
||||
}
|
||||
break;
|
||||
|
@ -2278,7 +2304,10 @@ if we return from dedicated mode and we have a ba range, we can use that for cel
|
|||
nmsg = gsm322_msgb_alloc(GSM322_EVENT_NO_CELL_FOUND);
|
||||
if (!nmsg)
|
||||
return -ENOMEM;
|
||||
gsm322_cs_sendmsg(ms, nmsg);
|
||||
gsm322_c_event(ms, nmsg);
|
||||
msgb_free(nmsg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* flag all frequencies that are in current band allocation */
|
||||
|
@ -2628,7 +2657,7 @@ static struct cellselstatelist {
|
|||
SBIT(GSM322_C4_NORMAL_CELL_RESEL) | SBIT(GSM322_C5_CHOOSE_CELL),
|
||||
GSM322_EVENT_CELL_FOUND, gsm322_c_camp_normally},
|
||||
{SBIT(GSM322_C9_CHOOSE_ANY_CELL) | SBIT(GSM322_C6_ANY_CELL_SEL) |
|
||||
SBIT(GSM322_C4_NORMAL_CELL_RESEL),
|
||||
SBIT(GSM322_C8_ANY_CELL_RESEL),
|
||||
GSM322_EVENT_CELL_FOUND, gsm322_c_camp_any_cell},
|
||||
{SBIT(GSM322_C1_NORMAL_CELL_SEL) | SBIT(GSM322_C6_ANY_CELL_SEL) |
|
||||
SBIT(GSM322_C9_CHOOSE_ANY_CELL) | SBIT(GSM322_C8_ANY_CELL_RESEL) |
|
||||
|
@ -2731,17 +2760,18 @@ int gsm322_dump_cs_list(struct osmocom_ms *ms, uint8_t flags)
|
|||
{
|
||||
struct gsm322_cellsel *cs = &ms->cellsel;
|
||||
int i, j;
|
||||
struct gsm48_sysinfo *s;
|
||||
|
||||
printf("rx-lev |MCC |MNC |forb.LA|barred,0123456789abcdef|"
|
||||
"min-db |max-pwr\n"
|
||||
"-------+-------+-------+-------+-----------------------+"
|
||||
"-------+-------\n");
|
||||
for (i = 0; i <= 1023; i++) {
|
||||
if (!(cs->list[i].flags & flags))
|
||||
s = cs->list[i].sysinfo;
|
||||
if (!s || !(cs->list[i].flags & flags))
|
||||
continue;
|
||||
printf("%4d |", cs->list[i].rxlev_db);
|
||||
if ((cs->list[i].flags & GSM322_CS_FLAG_SYSINFO)) {
|
||||
struct gsm48_sysinfo *s = cs->list[i].sysinfo;
|
||||
printf("%03d |%02d |", s->mcc, s->mnc);
|
||||
if ((cs->list[i].flags & GSM322_CS_FLAG_FORBIDD))
|
||||
printf("yes |");
|
||||
|
|
|
@ -72,6 +72,7 @@ int gsm48_cc_exit(struct osmocom_ms *ms)
|
|||
|
||||
llist_for_each_entry_safe(trans, trans2, &ms->trans_list, entry) {
|
||||
if (trans->protocol == GSM48_PDISC_CC)
|
||||
LOGP(DCC, LOGL_NOTICE, "Free pendig CC-transaction.\n");
|
||||
trans_free(trans);
|
||||
}
|
||||
|
||||
|
|
|
@ -725,8 +725,9 @@ static int gsm48_rr_tx_chan_req(struct osmocom_ms *ms, int cause, int paging)
|
|||
|
||||
/* ignore paging, if not camping */
|
||||
if (paging
|
||||
&& (!cs->selected || cs->state != GSM322_C3_CAMPED_NORMALLY)) {
|
||||
LOGP(DRR, LOGL_INFO, "Paging, but not camping normally.\n");
|
||||
&& (!cs->selected || (cs->state != GSM322_C3_CAMPED_NORMALLY
|
||||
&& cs->state != GSM322_C7_CAMPED_ANY_CELL))) {
|
||||
LOGP(DRR, LOGL_INFO, "Paging, but not camping, ignore.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -2051,25 +2052,25 @@ static int gsm_match_mi(struct osmocom_ms *ms, uint8_t *mi)
|
|||
memcpy(&tmsi, mi+2, 4);
|
||||
if (ms->subscr.tmsi == ntohl(tmsi)
|
||||
&& ms->subscr.tmsi_valid) {
|
||||
LOGP(DRR, LOGL_INFO, "TMSI %08x matches\n",
|
||||
LOGP(DPAG, LOGL_INFO, "TMSI %08x matches\n",
|
||||
ntohl(tmsi));
|
||||
|
||||
return 1;
|
||||
} else
|
||||
LOGP(DRR, LOGL_INFO, "TMSI %08x (not for us)\n",
|
||||
LOGP(DPAG, LOGL_INFO, "TMSI %08x (not for us)\n",
|
||||
ntohl(tmsi));
|
||||
break;
|
||||
case GSM_MI_TYPE_IMSI:
|
||||
gsm48_mi_to_string(imsi, sizeof(imsi), mi + 1, mi[0]);
|
||||
if (!strcmp(imsi, ms->subscr.imsi)) {
|
||||
LOGP(DRR, LOGL_INFO, "IMSI %s matches\n", imsi);
|
||||
LOGP(DPAG, LOGL_INFO, "IMSI %s matches\n", imsi);
|
||||
|
||||
return 1;
|
||||
} else
|
||||
LOGP(DRR, LOGL_INFO, "IMSI %s (not for us)\n", imsi);
|
||||
LOGP(DPAG, LOGL_INFO, "IMSI %s (not for us)\n", imsi);
|
||||
break;
|
||||
default:
|
||||
LOGP(DRR, LOGL_NOTICE, "Paging with unsupported MI type %d.\n",
|
||||
LOGP(DPAG, LOGL_NOTICE, "Paging with unsupported MI type %d.\n",
|
||||
mi_type);
|
||||
}
|
||||
|
||||
|
@ -2086,16 +2087,19 @@ static int gsm48_rr_rx_pag_req_1(struct osmocom_ms *ms, struct msgb *msg)
|
|||
int chan_1, chan_2;
|
||||
uint8_t *mi;
|
||||
|
||||
/* empty paging request */
|
||||
if (payload_len >= 2 && (pa->data[1] & GSM_MI_TYPE_MASK) == 0)
|
||||
return 0;
|
||||
|
||||
/* 3.3.1.1.2: ignore paging while not camping on a cell */
|
||||
if (rr->state != GSM48_RR_ST_IDLE
|
||||
|| !cs->selected || cs->state != GSM322_C3_CAMPED_NORMALLY) {
|
||||
#if 0
|
||||
if (rr->state != GSM48_RR_ST_IDLE || !cs->selected
|
||||
|| (cs->state != GSM322_C3_CAMPED_NORMALLY
|
||||
&& cs->state != GSM322_C7_CAMPED_ANY_CELL)) {
|
||||
LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping "
|
||||
"normally.\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
LOGP(DRR, LOGL_INFO, "PAGING REQUEST 1\n");
|
||||
LOGP(DPAG, LOGL_INFO, "PAGING REQUEST 1\n");
|
||||
|
||||
if (payload_len < 2) {
|
||||
short_read:
|
||||
|
@ -2139,13 +2143,14 @@ static int gsm48_rr_rx_pag_req_2(struct osmocom_ms *ms, struct msgb *msg)
|
|||
int chan_1, chan_2, chan_3;
|
||||
|
||||
/* 3.3.1.1.2: ignore paging while not camping on a cell */
|
||||
if (rr->state != GSM48_RR_ST_IDLE
|
||||
&& cs->state != GSM322_C3_CAMPED_NORMALLY) {
|
||||
if (rr->state != GSM48_RR_ST_IDLE || !cs->selected
|
||||
|| (cs->state != GSM322_C3_CAMPED_NORMALLY
|
||||
&& cs->state != GSM322_C7_CAMPED_ANY_CELL)) {
|
||||
LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping "
|
||||
"normally.\n");
|
||||
return 0;
|
||||
}
|
||||
LOGP(DRR, LOGL_INFO, "PAGING REQUEST 2\n");
|
||||
LOGP(DPAG, LOGL_INFO, "PAGING REQUEST 2\n");
|
||||
|
||||
if (payload_len < 0) {
|
||||
short_read:
|
||||
|
@ -2160,18 +2165,18 @@ static int gsm48_rr_rx_pag_req_2(struct osmocom_ms *ms, struct msgb *msg)
|
|||
/* first MI */
|
||||
if (ms->subscr.tmsi == ntohl(pa->tmsi1)
|
||||
&& ms->subscr.tmsi_valid) {
|
||||
LOGP(DRR, LOGL_INFO, "TMSI %08x matches\n", ntohl(pa->tmsi1));
|
||||
LOGP(DPAG, LOGL_INFO, "TMSI %08x matches\n", ntohl(pa->tmsi1));
|
||||
return gsm48_rr_tx_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1);
|
||||
} else
|
||||
LOGP(DRR, LOGL_INFO, "TMSI %08x (not for us)\n",
|
||||
LOGP(DPAG, LOGL_INFO, "TMSI %08x (not for us)\n",
|
||||
ntohl(pa->tmsi1));
|
||||
/* second MI */
|
||||
if (ms->subscr.tmsi == ntohl(pa->tmsi2)
|
||||
&& ms->subscr.tmsi_valid) {
|
||||
LOGP(DRR, LOGL_INFO, "TMSI %08x matches\n", ntohl(pa->tmsi2));
|
||||
LOGP(DPAG, LOGL_INFO, "TMSI %08x matches\n", ntohl(pa->tmsi2));
|
||||
return gsm48_rr_tx_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1);
|
||||
} else
|
||||
LOGP(DRR, LOGL_INFO, "TMSI %08x (not for us)\n",
|
||||
LOGP(DPAG, LOGL_INFO, "TMSI %08x (not for us)\n",
|
||||
ntohl(pa->tmsi2));
|
||||
/* third MI */
|
||||
mi = pa->data;
|
||||
|
@ -2198,13 +2203,14 @@ static int gsm48_rr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg)
|
|||
int chan_1, chan_2, chan_3, chan_4;
|
||||
|
||||
/* 3.3.1.1.2: ignore paging while not camping on a cell */
|
||||
if (rr->state != GSM48_RR_ST_IDLE
|
||||
&& cs->state != GSM322_C3_CAMPED_NORMALLY) {
|
||||
if (rr->state != GSM48_RR_ST_IDLE || !cs->selected
|
||||
|| (cs->state != GSM322_C3_CAMPED_NORMALLY
|
||||
&& cs->state != GSM322_C7_CAMPED_ANY_CELL)) {
|
||||
LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping "
|
||||
"normally.\n");
|
||||
return 0;
|
||||
}
|
||||
LOGP(DRR, LOGL_INFO, "PAGING REQUEST 3\n");
|
||||
LOGP(DPAG, LOGL_INFO, "PAGING REQUEST 3\n");
|
||||
|
||||
if (payload_len < 0) { /* must include "channel needed", part of *pa */
|
||||
LOGP(DRR, LOGL_NOTICE, "Short read of PAGING REQUEST 3 "
|
||||
|
@ -2220,34 +2226,34 @@ static int gsm48_rr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg)
|
|||
/* first MI */
|
||||
if (ms->subscr.tmsi == ntohl(pa->tmsi1)
|
||||
&& ms->subscr.tmsi_valid) {
|
||||
LOGP(DRR, LOGL_INFO, "TMSI %08x matches\n", ntohl(pa->tmsi1));
|
||||
LOGP(DPAG, LOGL_INFO, "TMSI %08x matches\n", ntohl(pa->tmsi1));
|
||||
return gsm48_rr_tx_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1);
|
||||
} else
|
||||
LOGP(DRR, LOGL_INFO, "TMSI %08x (not for us)\n",
|
||||
LOGP(DPAG, LOGL_INFO, "TMSI %08x (not for us)\n",
|
||||
ntohl(pa->tmsi1));
|
||||
/* second MI */
|
||||
if (ms->subscr.tmsi == ntohl(pa->tmsi2)
|
||||
&& ms->subscr.tmsi_valid) {
|
||||
LOGP(DRR, LOGL_INFO, "TMSI %08x matches\n", ntohl(pa->tmsi2));
|
||||
LOGP(DPAG, LOGL_INFO, "TMSI %08x matches\n", ntohl(pa->tmsi2));
|
||||
return gsm48_rr_tx_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1);
|
||||
} else
|
||||
LOGP(DRR, LOGL_INFO, "TMSI %08x (not for us)\n",
|
||||
LOGP(DPAG, LOGL_INFO, "TMSI %08x (not for us)\n",
|
||||
ntohl(pa->tmsi2));
|
||||
/* thrid MI */
|
||||
if (ms->subscr.tmsi == ntohl(pa->tmsi3)
|
||||
&& ms->subscr.tmsi_valid) {
|
||||
LOGP(DRR, LOGL_INFO, "TMSI %08x matches\n", ntohl(pa->tmsi3));
|
||||
LOGP(DPAG, LOGL_INFO, "TMSI %08x matches\n", ntohl(pa->tmsi3));
|
||||
return gsm48_rr_tx_chan_req(ms, gsm48_rr_chan2cause[chan_3], 1);
|
||||
} else
|
||||
LOGP(DRR, LOGL_INFO, "TMSI %08x (not for us)\n",
|
||||
LOGP(DPAG, LOGL_INFO, "TMSI %08x (not for us)\n",
|
||||
ntohl(pa->tmsi3));
|
||||
/* fourth MI */
|
||||
if (ms->subscr.tmsi == ntohl(pa->tmsi4)
|
||||
&& ms->subscr.tmsi_valid) {
|
||||
LOGP(DRR, LOGL_INFO, "TMSI %08x matches\n", ntohl(pa->tmsi4));
|
||||
LOGP(DPAG, LOGL_INFO, "TMSI %08x matches\n", ntohl(pa->tmsi4));
|
||||
return gsm48_rr_tx_chan_req(ms, gsm48_rr_chan2cause[chan_4], 1);
|
||||
} else
|
||||
LOGP(DRR, LOGL_INFO, "TMSI %08x (not for us)\n",
|
||||
LOGP(DPAG, LOGL_INFO, "TMSI %08x (not for us)\n",
|
||||
ntohl(pa->tmsi4));
|
||||
|
||||
return 0;
|
||||
|
@ -2997,7 +3003,7 @@ static int gsm48_rr_rx_bcch(struct osmocom_ms *ms, struct msgb *msg)
|
|||
}
|
||||
|
||||
/* receive CCCH at RR layer */
|
||||
static int gsm48_rr_rx_ccch(struct osmocom_ms *ms, struct msgb *msg)
|
||||
static int gsm48_rr_rx_pch_agch(struct osmocom_ms *ms, struct msgb *msg)
|
||||
{
|
||||
struct gsm48_system_information_type_header *sih = msgb_l3(msg);
|
||||
struct gsm322_cellsel *cs = &ms->cellsel;
|
||||
|
@ -3056,8 +3062,16 @@ static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
|
|||
|
||||
switch (rllh->chan_nr) {
|
||||
case RSL_CHAN_PCH_AGCH:
|
||||
return gsm48_rr_rx_ccch(ms, msg);
|
||||
return gsm48_rr_rx_pch_agch(ms, msg);
|
||||
case RSL_CHAN_BCCH:
|
||||
#if 0
|
||||
#warning testing corrupt frames
|
||||
{int i;
|
||||
if (ms->cellsel.state == GSM322_C7_CAMPED_ANY_CELL)
|
||||
for(i=0;i<msgb_l3len(msg);i++)
|
||||
msg->l3h[i] = random();
|
||||
}
|
||||
#endif
|
||||
return gsm48_rr_rx_bcch(ms, msg);
|
||||
default:
|
||||
LOGP(DRSL, LOGL_NOTICE, "RSL with chan_nr 0x%02x unknown.\n",
|
||||
|
|
|
@ -82,6 +82,7 @@ static const struct log_info_cat default_categories[] = {
|
|||
[DPAG] = {
|
||||
.name = "DPAG",
|
||||
.description = "Paging",
|
||||
.color = "\033[33m",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
},
|
||||
[DLAPDM] = {
|
||||
|
|
|
@ -27,85 +27,86 @@
|
|||
|
||||
void gsm_support_init(struct osmocom_ms *ms)
|
||||
{
|
||||
struct gsm_support *s = &ms->support;
|
||||
struct gsm_support *sup = &ms->support;
|
||||
int i;
|
||||
|
||||
memset(s, 0, sizeof(*s));
|
||||
memset(sup, 0, sizeof(*sup));
|
||||
|
||||
/* rf power capability */
|
||||
s->pwr_lev_900 = 3; /* CLASS 4: Handheld 2W */
|
||||
s->pwr_lev_1800 = 0; /* CLASS 1: Handheld 1W */
|
||||
sup->pwr_lev_900 = 3; /* CLASS 4: Handheld 2W */
|
||||
sup->pwr_lev_1800 = 0; /* CLASS 1: Handheld 1W */
|
||||
/* controlled early classmark sending */
|
||||
s->es_ind = 0; /* no */
|
||||
sup->es_ind = 0; /* no */
|
||||
/* revision level */
|
||||
s->rev_lev = 1; /* phase 2 mobile station */
|
||||
sup->rev_lev = 1; /* phase 2 mobile station */
|
||||
/* support of VGCS */
|
||||
s->vgcs = 0; /* no */
|
||||
sup->vgcs = 0; /* no */
|
||||
/* support of VBS */
|
||||
s->vbs = 0; /* no */
|
||||
sup->vbs = 0; /* no */
|
||||
/* support of SMS */
|
||||
s->sms_ptp = 1; /* yes */
|
||||
sup->sms_ptp = 1; /* yes */
|
||||
/* screening indicator */
|
||||
s->ss_ind = 1; /* phase 2 error handling */
|
||||
sup->ss_ind = 1; /* phase 2 error handling */
|
||||
/* pseudo synchronised capability */
|
||||
s->ps_cap = 0; /* no */
|
||||
sup->ps_cap = 0; /* no */
|
||||
/* CM service prompt */
|
||||
s->cmsp = 0; /* no */
|
||||
sup->cmsp = 0; /* no */
|
||||
/* solsa support */
|
||||
s->solsa = 0; /* no */
|
||||
sup->solsa = 0; /* no */
|
||||
/* location service support */
|
||||
s->lcsva = 0; /* no */
|
||||
s->loc_serv = 0; /* no */
|
||||
sup->lcsva = 0; /* no */
|
||||
sup->loc_serv = 0; /* no */
|
||||
/* codec supprot */
|
||||
s->a5_1 = 0; /* currently not */
|
||||
s->a5_2 = 0;
|
||||
s->a5_3 = 0;
|
||||
s->a5_4 = 0;
|
||||
s->a5_5 = 0;
|
||||
s->a5_6 = 0;
|
||||
s->a5_7 = 0;
|
||||
sup->a5_1 = 0; /* currently not */
|
||||
sup->a5_2 = 0;
|
||||
sup->a5_3 = 0;
|
||||
sup->a5_4 = 0;
|
||||
sup->a5_5 = 0;
|
||||
sup->a5_6 = 0;
|
||||
sup->a5_7 = 0;
|
||||
/* radio support */
|
||||
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;
|
||||
sup->p_gsm = 1; /* P-GSM only */
|
||||
sup->e_gsm = 0; /* E-GSM */
|
||||
sup->r_gsm = 0; /* R-GSM */
|
||||
sup->r_capa = 0;
|
||||
sup->low_capa = 4; /* p,e,r power class */
|
||||
sup->dcs_1800 = 0;
|
||||
/* set supported frequencies */
|
||||
if (s->e_gsm || s->r_gsm)
|
||||
s->freq_map[0] |= 1;
|
||||
if (s->p_gsm || s->e_gsm || s->r_gsm)
|
||||
if (sup->e_gsm || sup->r_gsm)
|
||||
sup->freq_map[0] |= 1;
|
||||
if (sup->p_gsm || sup->e_gsm || sup->r_gsm)
|
||||
for(i = 1; i <= 124; i++)
|
||||
s->freq_map[i >> 3] |= (1 << (i & 7));
|
||||
if (s->dcs_1800)
|
||||
sup->freq_map[i >> 3] |= (1 << (i & 7));
|
||||
if (sup->dcs_1800)
|
||||
for(i = 512; i <= 885; i++)
|
||||
s->freq_map[i >> 3] |= (1 << (i & 7));
|
||||
if (s->e_gsm)
|
||||
sup->freq_map[i >> 3] |= (1 << (i & 7));
|
||||
if (sup->e_gsm)
|
||||
for(i = 975; i <= 1023; i++)
|
||||
s->freq_map[i >> 3] |= (1 << (i & 7));
|
||||
sup->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)
|
||||
// sup->freq_map[i >> 3] |= (1 << (i & 7));
|
||||
if (sup->r_gsm)
|
||||
for(i = 955; i <= 1023; i++)
|
||||
s->freq_map[i >> 3] |= (1 << (i & 7));
|
||||
s->dcs_capa = 1; /* dcs power class */
|
||||
sup->freq_map[i >> 3] |= (1 << (i & 7));
|
||||
sup->dcs_capa = 1; /* dcs power class */
|
||||
/* multi slot support */
|
||||
s->ms_sup = 0; /* no */
|
||||
sup->ms_sup = 0; /* no */
|
||||
/* ucs2 treatment */
|
||||
s->ucs2_treat = 0; /* default */
|
||||
sup->ucs2_treat = 0; /* default */
|
||||
/* support extended measurements */
|
||||
s->ext_meas = 0; /* no */
|
||||
sup->ext_meas = 0; /* no */
|
||||
/* support switched measurement capability */
|
||||
s->meas_cap = 0; /* no */
|
||||
//s->sms_val = ;
|
||||
//s->sm_val = ;
|
||||
sup->meas_cap = 0; /* no */
|
||||
//sup->sms_val = ;
|
||||
//sup->sm_val = ;
|
||||
|
||||
/* IMEI */
|
||||
sprintf(s->imei, "000000000000000");
|
||||
sprintf(s->imeisv, "0000000000000000");
|
||||
sprintf(sup->imei, "000000000000000");
|
||||
sprintf(sup->imeisv, "0000000000000000");
|
||||
|
||||
/* radio */
|
||||
s->min_rxlev_db = -106; // TODO
|
||||
sup->min_rxlev_db = -106; // TODO
|
||||
sup->scan_to = 4; /* how long to wait for all sysinfos (>=4 s) */
|
||||
}
|
||||
|
||||
/* (3.2.1) maximum channels to scan within each band */
|
||||
|
|
Loading…
Reference in New Issue