blob: 4ab8a20985299b28fb531fe597d351360109839f [file] [log] [blame]
Harald Weltefbc5ca02010-03-04 10:39:50 +01001/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
Harald Welte8470bf22008-12-25 23:28:35 +00002 *
Harald Welte52b1f982008-12-23 20:25:15 +00003 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +01006 * it under the terms of the GNU Affero General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
Harald Welte52b1f982008-12-23 20:25:15 +00008 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010013 * GNU Affero General Public License for more details.
Harald Welte52b1f982008-12-23 20:25:15 +000014 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010015 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte52b1f982008-12-23 20:25:15 +000017 *
18 */
19
20
21#include <stdlib.h>
Harald Welte51f38452009-02-24 22:36:40 +000022#include <stdio.h>
Harald Welte52b1f982008-12-23 20:25:15 +000023#include <string.h>
Harald Weltefcd24452009-06-20 18:15:19 +020024#include <errno.h>
Harald Welte42581822009-08-08 16:12:58 +020025#include <ctype.h>
Maxc08ee712016-05-11 12:45:13 +020026#include <stdbool.h>
Harald Welte97a282b2010-03-14 15:37:43 +080027#include <netinet/in.h>
28
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010029#include <osmocom/core/linuxlist.h>
30#include <osmocom/core/talloc.h>
31#include <osmocom/gsm/gsm_utils.h>
Harald Welte867d9f32011-05-23 20:30:39 +020032#include <osmocom/gsm/abis_nm.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010033#include <osmocom/core/statistics.h>
Maxc08ee712016-05-11 12:45:13 +020034#include <osmocom/gsm/protocol/gsm_04_08.h>
Harald Welte52b1f982008-12-23 20:25:15 +000035
Neels Hofmeyr90843962017-09-04 15:04:35 +020036#include <osmocom/msc/gsm_data.h>
37#include <osmocom/msc/bsc_msc_data.h>
38#include <osmocom/msc/abis_nm.h>
Holger Hans Peter Freythered832862010-06-28 18:20:22 +080039
Andreas Eversberg8226fa72009-06-29 15:19:38 +020040void *tall_bsc_ctx;
41
Harald Welte39315c42010-01-10 18:01:52 +010042static LLIST_HEAD(bts_models);
43
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +020044void set_ts_e1link(struct gsm_bts_trx_ts *ts, uint8_t e1_nr,
45 uint8_t e1_ts, uint8_t e1_ts_ss)
Harald Weltecd06bfb2009-02-10 17:33:56 +000046{
47 ts->e1_link.e1_nr = e1_nr;
48 ts->e1_link.e1_ts = e1_ts;
49 ts->e1_link.e1_ts_ss = e1_ts_ss;
50}
51
Harald Weltee555c2b2012-08-17 13:02:12 +020052const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1] = {
53 { GSM_BTS_TYPE_UNKNOWN, "Unknown BTS Type" },
54 { GSM_BTS_TYPE_BS11, "Siemens BTS (BS-11 or compatible)" },
55 { GSM_BTS_TYPE_NANOBTS, "ip.access nanoBTS or compatible" },
56 { GSM_BTS_TYPE_RBS2000, "Ericsson RBS2000 Series" },
Harald Weltee555c2b2012-08-17 13:02:12 +020057 { GSM_BTS_TYPE_NOKIA_SITE, "Nokia {Metro,Ultra,In}Site" },
Maxf9685c12017-03-23 12:01:07 +010058 { GSM_BTS_TYPE_OSMOBTS, "sysmocom sysmoBTS" },
Harald Weltee555c2b2012-08-17 13:02:12 +020059 { 0, NULL }
60};
61
Harald Welte6e670aa2010-01-07 20:44:32 +010062struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr)
63{
64 struct gsm_bts_trx *trx;
65
66 llist_for_each_entry(trx, &bts->trx_list, list) {
67 if (trx->nr == nr)
68 return trx;
69 }
70 return NULL;
71}
72
Harald Weltebe991492009-05-23 13:56:40 +000073/* Search for a BTS in the given Location Area; optionally start searching
74 * with start_bts (for continuing to search after the first result) */
75struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
76 struct gsm_bts *start_bts)
77{
78 int i;
79 struct gsm_bts *bts;
80 int skip = 0;
81
82 if (start_bts)
83 skip = 1;
84
85 for (i = 0; i < net->num_bts; i++) {
Harald Weltee441d9c2009-06-21 16:17:15 +020086 bts = gsm_bts_num(net, i);
Harald Weltebe991492009-05-23 13:56:40 +000087
88 if (skip) {
89 if (start_bts == bts)
90 skip = 0;
91 continue;
92 }
93
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +020094 if (lac == GSM_LAC_RESERVED_ALL_BTS || bts->location_area_code == lac)
Harald Weltebe991492009-05-23 13:56:40 +000095 return bts;
96 }
97 return NULL;
98}
Harald Weltefcd24452009-06-20 18:15:19 +020099
Harald Welte92b1fe42010-03-25 11:45:30 +0800100static const struct value_string auth_policy_names[] = {
101 { GSM_AUTH_POLICY_CLOSED, "closed" },
102 { GSM_AUTH_POLICY_ACCEPT_ALL, "accept-all" },
103 { GSM_AUTH_POLICY_TOKEN, "token" },
Maxddee01f2016-05-24 14:23:27 +0200104 { GSM_AUTH_POLICY_REGEXP, "regexp" },
Harald Welte92b1fe42010-03-25 11:45:30 +0800105 { 0, NULL }
Harald Welte (local)69de3972009-08-12 14:42:23 +0200106};
107
108enum gsm_auth_policy gsm_auth_policy_parse(const char *arg)
109{
Harald Welte92b1fe42010-03-25 11:45:30 +0800110 return get_string_value(auth_policy_names, arg);
Harald Welte (local)69de3972009-08-12 14:42:23 +0200111}
112
113const char *gsm_auth_policy_name(enum gsm_auth_policy policy)
114{
Harald Welte92b1fe42010-03-25 11:45:30 +0800115 return get_value_string(auth_policy_names, policy);
Harald Welte (local)69de3972009-08-12 14:42:23 +0200116}
117
Harald Welte92b1fe42010-03-25 11:45:30 +0800118static const struct value_string rrlp_mode_names[] = {
119 { RRLP_MODE_NONE, "none" },
120 { RRLP_MODE_MS_BASED, "ms-based" },
121 { RRLP_MODE_MS_PREF, "ms-preferred" },
122 { RRLP_MODE_ASS_PREF, "ass-preferred" },
123 { 0, NULL }
Harald Welteeab84a12009-12-13 10:53:12 +0100124};
125
126enum rrlp_mode rrlp_mode_parse(const char *arg)
127{
Harald Welte92b1fe42010-03-25 11:45:30 +0800128 return get_string_value(rrlp_mode_names, arg);
Harald Welteeab84a12009-12-13 10:53:12 +0100129}
130
131const char *rrlp_mode_name(enum rrlp_mode mode)
132{
Harald Welte92b1fe42010-03-25 11:45:30 +0800133 return get_value_string(rrlp_mode_names, mode);
Harald Welteeab84a12009-12-13 10:53:12 +0100134}
Harald Welted12b0fd2009-12-15 21:36:05 +0100135
Harald Welte4511d892010-04-18 15:51:20 +0200136static const struct value_string bts_gprs_mode_names[] = {
137 { BTS_GPRS_NONE, "none" },
138 { BTS_GPRS_GPRS, "gprs" },
139 { BTS_GPRS_EGPRS, "egprs" },
140 { 0, NULL }
141};
142
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +0100143enum bts_gprs_mode bts_gprs_mode_parse(const char *arg, int *valid)
Harald Welte4511d892010-04-18 15:51:20 +0200144{
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +0100145 int rc;
146
147 rc = get_string_value(bts_gprs_mode_names, arg);
148 if (valid)
149 *valid = rc != -EINVAL;
150 return rc;
Harald Welte4511d892010-04-18 15:51:20 +0200151}
152
153const char *bts_gprs_mode_name(enum bts_gprs_mode mode)
154{
155 return get_value_string(bts_gprs_mode_names, mode);
156}
157
Harald Welte3300c012011-06-05 13:31:33 +0200158void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts)
159{
160 raid->mcc = bts->network->country_code;
161 raid->mnc = bts->network->network_code;
162 raid->lac = bts->location_area_code;
163 raid->rac = bts->gprs.rac;
164}
165
166int gsm48_ra_id_by_bts(uint8_t *buf, struct gsm_bts *bts)
167{
168 struct gprs_ra_id raid;
169
170 gprs_ra_id_by_bts(&raid, bts);
171
172 return gsm48_construct_ra(buf, &raid);
173}
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200174
175int gsm_parse_reg(void *ctx, regex_t *reg, char **str, int argc, const char **argv)
176{
177 int ret;
178
179 ret = 0;
180 if (*str) {
181 talloc_free(*str);
182 *str = NULL;
183 }
184 regfree(reg);
185
186 if (argc > 0) {
187 *str = talloc_strdup(ctx, argv[0]);
188 ret = regcomp(reg, argv[0], 0);
189
190 /* handle compilation failures */
191 if (ret != 0) {
192 talloc_free(*str);
193 *str = NULL;
194 }
195 }
196
197 return ret;
198}
199
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100200/* Assume there are only 256 possible bts */
201osmo_static_assert(sizeof(((struct gsm_bts *) 0)->nr) == 1, _bts_nr_is_256);
Harald Welte2f8b9d22017-06-18 11:12:13 +0300202
Harald Welte2483f1b2016-06-19 18:06:02 +0200203bool classmark_is_r99(struct gsm_classmark *cm)
204{
205 int rev_lev = 0;
206 if (cm->classmark1_set)
207 rev_lev = cm->classmark1.rev_lev;
208 else if (cm->classmark2_len > 0)
209 rev_lev = (cm->classmark2[0] >> 5) & 0x3;
210 return rev_lev >= 2;
211}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200212
213const struct value_string ran_type_names[] = {
214 OSMO_VALUE_STRING(RAN_UNKNOWN),
215 OSMO_VALUE_STRING(RAN_GERAN_A),
216 OSMO_VALUE_STRING(RAN_UTRAN_IU),
217 { 0, NULL }
218};