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:
Andreas.Eversberg 2010-05-04 09:48:51 +00:00
parent fe1dc19c6e
commit 7f009e41f9
7 changed files with 164 additions and 116 deletions

View File

@ -75,6 +75,7 @@ struct gsm_support {
/* radio */
int8_t min_rxlev_db;
uint8_t scan_to;
};
struct gsm_support_scan_max {

View File

@ -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);

View File

@ -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 |");

View File

@ -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);
}

View File

@ -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",

View File

@ -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] = {

View File

@ -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 */