blob: 0291129d061f28b593729f100900fcebf75a778b [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];
41 msgb = msgb_alloc(1024, "nanobts_attr_bts");
42
43 memcpy(buf, "\x55\x5b\x61\x67\x6d\x73", 6);
44 msgb_tv_fixed_put(msgb, NM_ATT_INTERF_BOUND, 6, buf);
45
46 /* interference avg. period in numbers of SACCH multifr */
47 msgb_tv_put(msgb, NM_ATT_INTAVE_PARAM, 0x06);
48
49 /* conn fail based on SACCH error rate */
50 buf[0] = 0x01;
51 buf[1] = get_radio_link_timeout(&bts->si_common.cell_options);
52 msgb_tl16v_put(msgb, NM_ATT_CONN_FAIL_CRIT, 2, buf);
53
54 memcpy(buf, "\x1e\x24\x24\xa8\x34\x21\xa8", 7);
55 msgb_tv_fixed_put(msgb, NM_ATT_T200, 7, buf);
56
57 msgb_tv_put(msgb, NM_ATT_MAX_TA, 0x3f);
58
59 /* seconds */
60 memcpy(buf, "\x00\x01\x0a", 3);
61 msgb_tv_fixed_put(msgb, NM_ATT_OVERL_PERIOD, 3, buf);
62
63 /* percent */
64 msgb_tv_put(msgb, NM_ATT_CCCH_L_T, 10);
65
66 /* seconds */
67 msgb_tv_put(msgb, NM_ATT_CCCH_L_I_P, 1);
68
69 /* busy threshold in - dBm */
70 buf[0] = 10;
71 if (bts->rach_b_thresh != -1)
72 buf[0] = bts->rach_b_thresh & 0xff;
73 msgb_tv_put(msgb, NM_ATT_RACH_B_THRESH, buf[0]);
74
75 /* rach load averaging 1000 slots */
76 buf[0] = 0x03;
77 buf[1] = 0xe8;
78 if (bts->rach_ldavg_slots != -1) {
79 buf[0] = (bts->rach_ldavg_slots >> 8) & 0x0f;
80 buf[1] = bts->rach_ldavg_slots & 0xff;
81 }
82 msgb_tv_fixed_put(msgb, NM_ATT_LDAVG_SLOTS, 2, buf);
83
84 /* miliseconds */
85 msgb_tv_put(msgb, NM_ATT_BTS_AIR_TIMER, 128);
86
87 /* 10 retransmissions of physical config */
88 msgb_tv_put(msgb, NM_ATT_NY1, 10);
89
90 buf[0] = (bts->c0->arfcn >> 8) & 0x0f;
91 buf[1] = bts->c0->arfcn & 0xff;
92 msgb_tv_fixed_put(msgb, NM_ATT_BCCH_ARFCN, 2, buf);
93
94 msgb_tv_put(msgb, NM_ATT_BSIC, bts->bsic);
95
96 abis_nm_ipaccess_cgi(buf, bts);
97 msgb_tl16v_put(msgb, NM_ATT_IPACC_CGI, 7, buf);
98
99 return msgb;
100}
101
102struct msgb *nanobts_attr_nse_get(struct gsm_bts *bts)
103{
104 struct msgb *msgb;
105 uint8_t buf[256];
106 msgb = msgb_alloc(1024, "nanobts_attr_bts");
107
108 /* NSEI 925 */
109 buf[0] = bts->gprs.nse.nsei >> 8;
110 buf[1] = bts->gprs.nse.nsei & 0xff;
111 msgb_tl16v_put(msgb, NM_ATT_IPACC_NSEI, 2, buf);
112
113 /* all timers in seconds */
114 OSMO_ASSERT(ARRAY_SIZE(bts->gprs.nse.timer) < sizeof(buf));
115 memcpy(buf, bts->gprs.nse.timer, ARRAY_SIZE(bts->gprs.nse.timer));
116 msgb_tl16v_put(msgb, NM_ATT_IPACC_NS_CFG, 7, buf);
117
118 /* all timers in seconds */
119 buf[0] = 3; /* blockimg timer (T1) */
120 buf[1] = 3; /* blocking retries */
121 buf[2] = 3; /* unblocking retries */
122 buf[3] = 3; /* reset timer (T2) */
123 buf[4] = 3; /* reset retries */
124 buf[5] = 10; /* suspend timer (T3) in 100ms */
125 buf[6] = 3; /* suspend retries */
126 buf[7] = 10; /* resume timer (T4) in 100ms */
127 buf[8] = 3; /* resume retries */
128 buf[9] = 10; /* capability update timer (T5) */
129 buf[10] = 3; /* capability update retries */
130
131 OSMO_ASSERT(ARRAY_SIZE(bts->gprs.cell.timer) < sizeof(buf));
132 memcpy(buf, bts->gprs.cell.timer, ARRAY_SIZE(bts->gprs.cell.timer));
133 msgb_tl16v_put(msgb, NM_ATT_IPACC_BSSGP_CFG, 11, buf);
134
135 return msgb;
136}
137
138struct msgb *nanobts_attr_cell_get(struct gsm_bts *bts)
139{
140 struct msgb *msgb;
141 uint8_t buf[256];
142 msgb = msgb_alloc(1024, "nanobts_attr_bts");
143
144 /* routing area code */
145 buf[0] = bts->gprs.rac;
146 msgb_tl16v_put(msgb, NM_ATT_IPACC_RAC, 1, buf);
147
148 buf[0] = 5; /* repeat time (50ms) */
149 buf[1] = 3; /* repeat count */
150 msgb_tl16v_put(msgb, NM_ATT_IPACC_GPRS_PAGING_CFG, 2, buf);
151
152 /* BVCI 925 */
153 buf[0] = bts->gprs.cell.bvci >> 8;
154 buf[1] = bts->gprs.cell.bvci & 0xff;
155 msgb_tl16v_put(msgb, NM_ATT_IPACC_BVCI, 2, buf);
156
157 /* all timers in seconds, unless otherwise stated */
158 buf[0] = 20; /* T3142 */
159 buf[1] = 5; /* T3169 */
160 buf[2] = 5; /* T3191 */
161 buf[3] = 160; /* T3193 (units of 10ms) */
162 buf[4] = 5; /* T3195 */
163 buf[5] = 10; /* N3101 */
164 buf[6] = 4; /* N3103 */
165 buf[7] = 8; /* N3105 */
166 buf[8] = 15; /* RLC CV countdown */
167 msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG, 9, buf);
168
169 if (bts->gprs.mode == BTS_GPRS_EGPRS) {
170 buf[0] = 0x8f;
171 buf[1] = 0xff;
172 } else {
173 buf[0] = 0x0f;
174 buf[1] = 0x00;
175 }
176 msgb_tl16v_put(msgb, NM_ATT_IPACC_CODING_SCHEMES, 2, buf);
177
178 buf[0] = 0; /* T downlink TBF extension (0..500, high byte) */
179 buf[1] = 250; /* T downlink TBF extension (0..500, low byte) */
180 buf[2] = 0; /* T uplink TBF extension (0..500, high byte) */
181 buf[3] = 250; /* T uplink TBF extension (0..500, low byte) */
182 buf[4] = 2; /* CS2 */
183 msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_2, 5, buf);
184
185#if 0
186 /* EDGE model only, breaks older models.
187 * Should inquire the BTS capabilities */
188 buf[0] = 2; /* MCS2 */
189 msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_3, 1, buf);
190#endif
191
192 return msgb;
193}
194
195struct msgb *nanobts_attr_nscv_get(struct gsm_bts *bts)
196{
197 struct msgb *msgb;
198 uint8_t buf[256];
199 msgb = msgb_alloc(1024, "nanobts_attr_bts");
200
201 /* 925 */
202 buf[0] = bts->gprs.nsvc[0].nsvci >> 8;
203 buf[1] = bts->gprs.nsvc[0].nsvci & 0xff;
204 msgb_tl16v_put(msgb, NM_ATT_IPACC_NSVCI, 2, buf);
205
206 /* remote udp port */
207 patch_16(&buf[0], htons(bts->gprs.nsvc[0].remote_port));
208 /* remote ip address */
209 patch_32(&buf[2], htonl(bts->gprs.nsvc[0].remote_ip));
210 /* local udp port */
211 patch_16(&buf[6], htons(bts->gprs.nsvc[0].local_port));
212 msgb_tl16v_put(msgb, NM_ATT_IPACC_NS_LINK_CFG, 8, buf);
213
214 return msgb;
215}
216
217struct msgb *nanobts_attr_radio_get(struct gsm_bts *bts,
218 struct gsm_bts_trx *trx)
219{
220 struct msgb *msgb;
221 uint8_t buf[256];
222 msgb = msgb_alloc(1024, "nanobts_attr_bts");
223
224 /* number of -2dB reduction steps / Pn */
225 msgb_tv_put(msgb, NM_ATT_RF_MAXPOWR_R, trx->max_power_red / 2);
226
227 buf[0] = trx->arfcn >> 8;
228 buf[1] = trx->arfcn & 0xff;
229 msgb_tl16v_put(msgb, NM_ATT_ARFCN_LIST, 2, buf);
230
231 return msgb;
232}