[layer23] Correctly report to restart mobile instance after band change
[osmocom-bb.git] / src / host / layer23 / src / mobile / support.c
1 /*
2  * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
3  *
4  * All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  */
21
22 #include <stdio.h>
23 #include <stdint.h>
24 #include <string.h>
25
26 #include <osmocom/bb/common/osmocom_data.h>
27
28 void gsm_support_init(struct osmocom_ms *ms)
29 {
30         struct gsm_support *sup = &ms->support;
31
32         memset(sup, 0, sizeof(*sup));
33         sup->ms = ms;
34
35         /* controlled early classmark sending */
36         sup->es_ind = 0; /* no */
37         /* revision level */
38         sup->rev_lev = 1; /* phase 2 mobile station */
39         /* support of VGCS */
40         sup->vgcs = 0; /* no */
41         /* support of VBS */
42         sup->vbs = 0; /* no */
43         /* support of SMS */
44         sup->sms_ptp = 1; /* yes */
45         /* screening indicator */
46         sup->ss_ind = 1; /* phase 2 error handling */
47         /* pseudo synchronised capability */
48         sup->ps_cap = 0; /* no */
49         /* CM service prompt */
50         sup->cmsp = 0; /* no */
51         /* solsa support */
52         sup->solsa = 0; /* no */
53         /* location service support */
54         sup->lcsva = 0; /* no */
55         sup->loc_serv = 0; /* no */
56         /* codec supprot */
57         sup->a5_1 = 1;
58         sup->a5_2 = 1;
59         sup->a5_3 = 0;
60         sup->a5_4 = 0;
61         sup->a5_5 = 0;
62         sup->a5_6 = 0;
63         sup->a5_7 = 0;
64         /* radio support */
65         sup->p_gsm = 1; /* P-GSM */
66         sup->e_gsm = 1; /* E-GSM */
67         sup->r_gsm = 1; /* R-GSM */
68         sup->dcs = 1;
69         sup->gsm_850 = 1;
70         sup->pcs = 1;
71         sup->gsm_480 = 0;
72         sup->gsm_450 = 0;
73         /* rf power capability */
74         sup->class_900 = 4; /* CLASS 4: Handheld 2W */
75         sup->class_850 = 4;
76         sup->class_400 = 4;
77         sup->class_dcs = 1; /* CLASS 1: Handheld 1W */
78         sup->class_pcs = 1;
79         /* multi slot support */
80         sup->ms_sup = 0; /* no */
81         /* ucs2 treatment */
82         sup->ucs2_treat = 0; /* default */
83         /* support extended measurements */
84         sup->ext_meas = 0; /* no */
85         /* support switched measurement capability */
86         sup->meas_cap = 0; /* no */
87         //sup->sms_val = ;
88         //sup->sm_val = ;
89
90         /* radio */
91         sup->ch_cap = GSM_CAP_SDCCH_TCHF_TCHH;
92         sup->min_rxlev_db = -106; // TODO
93         sup->sync_to = 6; /* how long to wait sync (0.9 s) */
94         sup->scan_to = 4; /* how long to wait for all sysinfos (>=4 s) */
95         sup->dsc_max = 90; /* the specs defines 90 */
96
97         /* codec */
98         sup->full_v1 = 1;
99         sup->full_v2 = 1;
100         sup->full_v3 = 0;
101         sup->half_v1 = 1;
102         sup->half_v3 = 0;
103 }
104
105 /* (3.2.1) maximum channels to scan within each band */
106 struct gsm_support_scan_max gsm_sup_smax[] = {
107         { 259, 293, 15, 0 }, /* GSM 450 */
108         { 306, 340, 15, 0 }, /* GSM 480 */
109         { 438, 511, 25, 0 },
110         { 128, 251, 30, 0 }, /* GSM 850 */
111         { 955, 124, 30, 0 }, /* P,E,R GSM */
112         { 512, 885, 40, 0 }, /* DCS 1800 */
113         { 1024, 1322, 40, 0 }, /* PCS 1900 */
114         { 0, 0, 0, 0 }
115 };
116
117 #define SUP_SET(item) \
118         ((sup->item) ? ((set->item) ? "yes" : "disabled") : "no")
119 /* dump support */
120 void gsm_support_dump(struct osmocom_ms *ms,
121                         void (*print)(void *, const char *, ...), void *priv)
122 {
123         struct gsm_support *sup = &ms->support;
124         struct gsm_settings *set = &ms->settings;
125
126         print(priv, "Supported features of MS '%s':\n", sup->ms->name);
127         print(priv, " Phase %d mobile station\n", sup->rev_lev + 1);
128         print(priv, " R-GSM        : %s\n", SUP_SET(r_gsm));
129         print(priv, " E-GSM        : %s\n", SUP_SET(e_gsm));
130         print(priv, " P-GSM        : %s\n", SUP_SET(p_gsm));
131         if (set->r_gsm || set->e_gsm || set->p_gsm)
132                 print(priv, " GSM900 Class : %d\n", set->class_900);
133         print(priv, " DCS 1800     : %s\n", SUP_SET(dcs));
134         if (set->dcs)
135                 print(priv, " DCS Class    : %d\n", set->class_dcs);
136         print(priv, " GSM 850      : %s\n", SUP_SET(gsm_850));
137         if (set->gsm_850)
138                 print(priv, " GSM 850 Class: %d\n", set->class_850);
139         print(priv, " PCS 1900     : %s\n", SUP_SET(pcs));
140         if (set->pcs)
141                 print(priv, " PCS Class    : %d\n", set->class_pcs);
142         print(priv, " GSM 480      : %s\n", SUP_SET(gsm_480));
143         print(priv, " GSM 450      : %s\n", SUP_SET(gsm_450));
144         if (set->gsm_480 | set->gsm_450)
145                 print(priv, " GSM 400 Class: %d\n", set->class_400);
146         print(priv, " CECS         : %s\n", (sup->es_ind) ? "yes" : "no");
147         print(priv, " VGCS         : %s\n", (sup->vgcs) ? "yes" : "no");
148         print(priv, " VBS          : %s\n", (sup->vbs) ? "yes" : "no");
149         print(priv, " SMS          : %s\n", SUP_SET(sms_ptp));
150         print(priv, " SS_IND       : %s\n", (sup->ss_ind) ? "yes" : "no");
151         print(priv, " PS_CAP       : %s\n", (sup->ps_cap) ? "yes" : "no");
152         print(priv, " CMSP         : %s\n", (sup->cmsp) ? "yes" : "no");
153         print(priv, " SoLSA        : %s\n", (sup->solsa) ? "yes" : "no");
154         print(priv, " LCSVA        : %s\n", (sup->lcsva) ? "yes" : "no");
155         print(priv, " LOC_SERV     : %s\n", (sup->loc_serv) ? "yes" : "no");
156         print(priv, " A5/1         : %s\n", SUP_SET(a5_1));
157         print(priv, " A5/2         : %s\n", SUP_SET(a5_2));
158         print(priv, " A5/3         : %s\n", SUP_SET(a5_3));
159         print(priv, " A5/4         : %s\n", SUP_SET(a5_4));
160         print(priv, " A5/5         : %s\n", SUP_SET(a5_5));
161         print(priv, " A5/6         : %s\n", SUP_SET(a5_6));
162         print(priv, " A5/7         : %s\n", SUP_SET(a5_7));
163         print(priv, " A5/1         : %s\n", SUP_SET(a5_1));
164         switch (set->ch_cap) {
165                 case GSM_CAP_SDCCH:
166                 print(priv, " Channels     : SDCCH only\n");
167                 break;
168                 case GSM_CAP_SDCCH_TCHF:
169                 print(priv, " Channels     : SDCCH + TCH/F\n");
170                 break;
171                 case GSM_CAP_SDCCH_TCHF_TCHH:
172                 print(priv, " Channels     : SDCCH + TCH/F + TCH/H\n");
173                 break;
174         }
175         print(priv, " Full-Rate V1 : %s\n", SUP_SET(full_v1));
176         print(priv, " Full-Rate V2 : %s\n", SUP_SET(full_v2));
177         print(priv, " Full-Rate V3 : %s\n", SUP_SET(full_v3));
178         print(priv, " Half-Rate V1 : %s\n", SUP_SET(half_v1));
179         print(priv, " Half-Rate V3 : %s\n", SUP_SET(half_v3));
180         print(priv, " Min RXLEV    : %d\n", set->min_rxlev_db);
181 }
182