[layer23] Correctly report to restart mobile instance after band change
[osmocom-bb.git] / src / host / layer23 / src / mobile / settings.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 <stdint.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <osmocom/core/talloc.h>
26
27 #include <osmocom/bb/common/logging.h>
28 #include <osmocom/bb/common/osmocom_data.h>
29 #include <osmocom/bb/common/networks.h>
30
31 static char *layer2_socket_path = "/tmp/osmocom_l2";
32 static char *sap_socket_path = "/tmp/osmocom_sap";
33
34 int gsm_settings_init(struct osmocom_ms *ms)
35 {
36         struct gsm_settings *set = &ms->settings;
37         struct gsm_support *sup = &ms->support;
38
39         strcpy(set->layer2_socket_path, layer2_socket_path);
40         strcpy(set->sap_socket_path, sap_socket_path);
41
42         /* network search */
43         set->plmn_mode = PLMN_MODE_AUTO;
44
45         /* IMEI */
46         sprintf(set->imei,   "000000000000000");
47         sprintf(set->imeisv, "0000000000000000");
48
49         /* SIM type */
50 #warning TODO: Enable after SIM reader is available in master branch.
51 //      set->sim_type = SIM_TYPE_READER;
52
53         /* test SIM */
54         strcpy(set->test_imsi, "001010000000000");
55         set->test_rplmn_mcc = set->test_rplmn_mnc = 1;
56         set->test_lac = 0x0000;
57         set->test_tmsi = 0xffffffff;
58
59         /* set all supported features */
60         set->sms_ptp = sup->sms_ptp;
61         set->a5_1 = sup->a5_1;
62         set->a5_2 = sup->a5_2;
63         set->a5_3 = sup->a5_3;
64         set->a5_4 = sup->a5_4;
65         set->a5_5 = sup->a5_5;
66         set->a5_6 = sup->a5_6;
67         set->a5_7 = sup->a5_7;
68         set->p_gsm = sup->p_gsm;
69         set->e_gsm = sup->e_gsm;
70         set->r_gsm = sup->r_gsm;
71         set->dcs = sup->dcs;
72         set->class_900 = sup->class_900;
73         set->class_dcs = sup->class_dcs;
74         set->class_850 = sup->class_850;
75         set->class_pcs = sup->class_pcs;
76         set->class_400 = sup->class_400;
77         set->full_v1 = sup->full_v1;
78         set->full_v2 = sup->full_v2;
79         set->full_v3 = sup->full_v3;
80         set->half_v1 = sup->half_v1;
81         set->half_v3 = sup->half_v3;
82         set->ch_cap = sup->ch_cap;
83         set->min_rxlev_db = sup->min_rxlev_db;
84         set->dsc_max = sup->dsc_max;
85
86         if (sup->half_v1 || sup->half_v3)
87                 set->half = 1;
88
89
90         /* software features */
91         set->cc_dtmf = 1;
92
93         INIT_LLIST_HEAD(&set->abbrev);
94
95         return 0;
96 }
97
98 int gsm_settings_arfcn(struct osmocom_ms *ms)
99 {
100         int i;
101         struct gsm_settings *set = &ms->settings;
102
103         /* set supported frequencies */
104         memset(set->freq_map, 0, sizeof(set->freq_map));
105         if (set->p_gsm)
106                 for(i = 1; i <= 124; i++)
107                         set->freq_map[i >> 3] |= (1 << (i & 7));
108         if (set->gsm_850)
109                 for(i = 128; i <= 251; i++)
110                         set->freq_map[i >> 3] |= (1 << (i & 7));
111         if (set->gsm_450)
112                 for(i = 259; i <= 293; i++)
113                         set->freq_map[i >> 3] |= (1 << (i & 7));
114         if (set->gsm_480)
115                 for(i = 306; i <= 340; i++)
116                         set->freq_map[i >> 3] |= (1 << (i & 7));
117         if (set->dcs)
118                 for(i = 512; i <= 885; i++)
119                         set->freq_map[i >> 3] |= (1 << (i & 7));
120         if (set->pcs)
121                 for(i = 1024; i <= 1024-512+810; i++)
122                         set->freq_map[i >> 3] |= (1 << (i & 7));
123         if (set->e_gsm) {
124                 for(i = 975; i <= 1023; i++)
125                         set->freq_map[i >> 3] |= (1 << (i & 7));
126                 set->freq_map[0] |= 1;
127         }
128         if (set->r_gsm)
129                 for(i = 955; i <= 974; i++)
130                         set->freq_map[i >> 3] |= (1 << (i & 7));
131
132         return 0;
133 }
134
135 int gsm_settings_exit(struct osmocom_ms *ms)
136 {
137         struct gsm_settings *set = &ms->settings;
138         struct gsm_settings_abbrev *abbrev;
139
140         while (!llist_empty(&set->abbrev)) {
141                 abbrev = llist_entry(set->abbrev.next,
142                         struct gsm_settings_abbrev, list);
143                 llist_del(&abbrev->list);
144                 talloc_free(abbrev);
145         }
146
147         return 0;
148 }
149
150 char *gsm_check_imei(const char *imei, const char *sv)
151 {
152         int i;
153
154         if (!imei || strlen(imei) != 15)
155                 return "IMEI must have 15 digits!";
156
157         for (i = 0; i < strlen(imei); i++) {
158                 if (imei[i] < '0' || imei[i] > '9')
159                         return "IMEI must have digits 0 to 9 only!";
160         }
161
162         if (!sv || strlen(sv) != 1)
163                 return "Software version must have 1 digit!";
164
165         if (sv[0] < '0' || sv[0] > '9')
166                 return "Software version must have digits 0 to 9 only!";
167
168         return NULL;
169 }
170
171 int gsm_random_imei(struct gsm_settings *set)
172 {
173         int digits = set->imei_random;
174         char rand[16];
175
176         if (digits <= 0)
177                 return 0;
178         if (digits > 15)
179                 digits = 15;
180
181         sprintf(rand, "%08ld", random() % 100000000);
182         sprintf(rand + 8, "%07ld", random() % 10000000);
183
184         strcpy(set->imei + 15 - digits, rand + 15 - digits);
185         strncpy(set->imeisv, set->imei, 15);
186         
187         return 0;
188 }
189