blob: 473e1caeae935728926dad7b799681f1b47b10f1 [file] [log] [blame]
Philippb4cb8382016-09-29 17:01:57 +02001/* ip.access nanoBTS specific code, OML attribute table generator */
2
3/* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
4 * All Rights Reserved
5 *
6 * Author: Philipp Maier
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <arpa/inet.h>
23#include <osmocom/core/msgb.h>
24#include <openbsc/gsm_data.h>
25#include <openbsc/abis_nm.h>
26
27static void patch_16(uint8_t *data, const uint16_t val)
28{
29 memcpy(data, &val, sizeof(val));
30}
31
32static void patch_32(uint8_t *data, const uint32_t val)
33{
34 memcpy(data, &val, sizeof(val));
35}
36
37struct msgb *nanobts_attr_bts_get(struct gsm_bts *bts)
38{
39 struct msgb *msgb;
40 uint8_t buf[256];
Harald Welte2f8b9d22017-06-18 11:12:13 +030041 int rlt;
Philippb4cb8382016-09-29 17:01:57 +020042 msgb = msgb_alloc(1024, "nanobts_attr_bts");
43
44 memcpy(buf, "\x55\x5b\x61\x67\x6d\x73", 6);
45 msgb_tv_fixed_put(msgb, NM_ATT_INTERF_BOUND, 6, buf);
46
47 /* interference avg. period in numbers of SACCH multifr */
48 msgb_tv_put(msgb, NM_ATT_INTAVE_PARAM, 0x06);
49
Harald Welte2f8b9d22017-06-18 11:12:13 +030050 rlt = gsm_bts_get_radio_link_timeout(bts);
51 if (rlt == -1) {
52 /* Osmocom extension: Use infinite radio link timeout */
53 buf[0] = 0xFF;
54 buf[1] = 0x00;
55 } else {
56 /* conn fail based on SACCH error rate */
57 buf[0] = 0x01;
58 buf[1] = rlt;
59 }
Philippb4cb8382016-09-29 17:01:57 +020060 msgb_tl16v_put(msgb, NM_ATT_CONN_FAIL_CRIT, 2, buf);
61
62 memcpy(buf, "\x1e\x24\x24\xa8\x34\x21\xa8", 7);
63 msgb_tv_fixed_put(msgb, NM_ATT_T200, 7, buf);
64
65 msgb_tv_put(msgb, NM_ATT_MAX_TA, 0x3f);
66
67 /* seconds */
68 memcpy(buf, "\x00\x01\x0a", 3);
69 msgb_tv_fixed_put(msgb, NM_ATT_OVERL_PERIOD, 3, buf);
70
71 /* percent */
72 msgb_tv_put(msgb, NM_ATT_CCCH_L_T, 10);
73
74 /* seconds */
75 msgb_tv_put(msgb, NM_ATT_CCCH_L_I_P, 1);
76
77 /* busy threshold in - dBm */
78 buf[0] = 10;
79 if (bts->rach_b_thresh != -1)
80 buf[0] = bts->rach_b_thresh & 0xff;
81 msgb_tv_put(msgb, NM_ATT_RACH_B_THRESH, buf[0]);
82
83 /* rach load averaging 1000 slots */
84 buf[0] = 0x03;
85 buf[1] = 0xe8;
86 if (bts->rach_ldavg_slots != -1) {
87 buf[0] = (bts->rach_ldavg_slots >> 8) & 0x0f;
88 buf[1] = bts->rach_ldavg_slots & 0xff;
89 }
90 msgb_tv_fixed_put(msgb, NM_ATT_LDAVG_SLOTS, 2, buf);
91
92 /* miliseconds */
93 msgb_tv_put(msgb, NM_ATT_BTS_AIR_TIMER, 128);
94
95 /* 10 retransmissions of physical config */
96 msgb_tv_put(msgb, NM_ATT_NY1, 10);
97
98 buf[0] = (bts->c0->arfcn >> 8) & 0x0f;
99 buf[1] = bts->c0->arfcn & 0xff;
100 msgb_tv_fixed_put(msgb, NM_ATT_BCCH_ARFCN, 2, buf);
101
102 msgb_tv_put(msgb, NM_ATT_BSIC, bts->bsic);
103
104 abis_nm_ipaccess_cgi(buf, bts);
105 msgb_tl16v_put(msgb, NM_ATT_IPACC_CGI, 7, buf);
106
107 return msgb;
108}
109
110struct msgb *nanobts_attr_nse_get(struct gsm_bts *bts)
111{
112 struct msgb *msgb;
113 uint8_t buf[256];
114 msgb = msgb_alloc(1024, "nanobts_attr_bts");
115
116 /* NSEI 925 */
117 buf[0] = bts->gprs.nse.nsei >> 8;
118 buf[1] = bts->gprs.nse.nsei & 0xff;
119 msgb_tl16v_put(msgb, NM_ATT_IPACC_NSEI, 2, buf);
120
121 /* all timers in seconds */
122 OSMO_ASSERT(ARRAY_SIZE(bts->gprs.nse.timer) < sizeof(buf));
123 memcpy(buf, bts->gprs.nse.timer, ARRAY_SIZE(bts->gprs.nse.timer));
124 msgb_tl16v_put(msgb, NM_ATT_IPACC_NS_CFG, 7, buf);
125
126 /* all timers in seconds */
127 buf[0] = 3; /* blockimg timer (T1) */
128 buf[1] = 3; /* blocking retries */
129 buf[2] = 3; /* unblocking retries */
130 buf[3] = 3; /* reset timer (T2) */
131 buf[4] = 3; /* reset retries */
132 buf[5] = 10; /* suspend timer (T3) in 100ms */
133 buf[6] = 3; /* suspend retries */
134 buf[7] = 10; /* resume timer (T4) in 100ms */
135 buf[8] = 3; /* resume retries */
136 buf[9] = 10; /* capability update timer (T5) */
137 buf[10] = 3; /* capability update retries */
138
139 OSMO_ASSERT(ARRAY_SIZE(bts->gprs.cell.timer) < sizeof(buf));
140 memcpy(buf, bts->gprs.cell.timer, ARRAY_SIZE(bts->gprs.cell.timer));
141 msgb_tl16v_put(msgb, NM_ATT_IPACC_BSSGP_CFG, 11, buf);
142
143 return msgb;
144}
145
146struct msgb *nanobts_attr_cell_get(struct gsm_bts *bts)
147{
148 struct msgb *msgb;
149 uint8_t buf[256];
150 msgb = msgb_alloc(1024, "nanobts_attr_bts");
151
152 /* routing area code */
153 buf[0] = bts->gprs.rac;
154 msgb_tl16v_put(msgb, NM_ATT_IPACC_RAC, 1, buf);
155
156 buf[0] = 5; /* repeat time (50ms) */
157 buf[1] = 3; /* repeat count */
158 msgb_tl16v_put(msgb, NM_ATT_IPACC_GPRS_PAGING_CFG, 2, buf);
159
160 /* BVCI 925 */
161 buf[0] = bts->gprs.cell.bvci >> 8;
162 buf[1] = bts->gprs.cell.bvci & 0xff;
163 msgb_tl16v_put(msgb, NM_ATT_IPACC_BVCI, 2, buf);
164
165 /* all timers in seconds, unless otherwise stated */
166 buf[0] = 20; /* T3142 */
167 buf[1] = 5; /* T3169 */
168 buf[2] = 5; /* T3191 */
169 buf[3] = 160; /* T3193 (units of 10ms) */
170 buf[4] = 5; /* T3195 */
171 buf[5] = 10; /* N3101 */
172 buf[6] = 4; /* N3103 */
173 buf[7] = 8; /* N3105 */
174 buf[8] = 15; /* RLC CV countdown */
175 msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG, 9, buf);
176
177 if (bts->gprs.mode == BTS_GPRS_EGPRS) {
178 buf[0] = 0x8f;
179 buf[1] = 0xff;
180 } else {
181 buf[0] = 0x0f;
182 buf[1] = 0x00;
183 }
184 msgb_tl16v_put(msgb, NM_ATT_IPACC_CODING_SCHEMES, 2, buf);
185
186 buf[0] = 0; /* T downlink TBF extension (0..500, high byte) */
187 buf[1] = 250; /* T downlink TBF extension (0..500, low byte) */
188 buf[2] = 0; /* T uplink TBF extension (0..500, high byte) */
189 buf[3] = 250; /* T uplink TBF extension (0..500, low byte) */
190 buf[4] = 2; /* CS2 */
191 msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_2, 5, buf);
192
193#if 0
194 /* EDGE model only, breaks older models.
195 * Should inquire the BTS capabilities */
196 buf[0] = 2; /* MCS2 */
197 msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_3, 1, buf);
198#endif
199
200 return msgb;
201}
202
203struct msgb *nanobts_attr_nscv_get(struct gsm_bts *bts)
204{
205 struct msgb *msgb;
206 uint8_t buf[256];
207 msgb = msgb_alloc(1024, "nanobts_attr_bts");
208
209 /* 925 */
210 buf[0] = bts->gprs.nsvc[0].nsvci >> 8;
211 buf[1] = bts->gprs.nsvc[0].nsvci & 0xff;
212 msgb_tl16v_put(msgb, NM_ATT_IPACC_NSVCI, 2, buf);
213
214 /* remote udp port */
215 patch_16(&buf[0], htons(bts->gprs.nsvc[0].remote_port));
216 /* remote ip address */
217 patch_32(&buf[2], htonl(bts->gprs.nsvc[0].remote_ip));
218 /* local udp port */
219 patch_16(&buf[6], htons(bts->gprs.nsvc[0].local_port));
220 msgb_tl16v_put(msgb, NM_ATT_IPACC_NS_LINK_CFG, 8, buf);
221
222 return msgb;
223}
224
225struct msgb *nanobts_attr_radio_get(struct gsm_bts *bts,
226 struct gsm_bts_trx *trx)
227{
228 struct msgb *msgb;
229 uint8_t buf[256];
230 msgb = msgb_alloc(1024, "nanobts_attr_bts");
231
232 /* number of -2dB reduction steps / Pn */
233 msgb_tv_put(msgb, NM_ATT_RF_MAXPOWR_R, trx->max_power_red / 2);
234
235 buf[0] = trx->arfcn >> 8;
236 buf[1] = trx->arfcn & 0xff;
237 msgb_tl16v_put(msgb, NM_ATT_ARFCN_LIST, 2, buf);
238
239 return msgb;
240}