blob: 2afe257648ac3188f583d4df761e2bdd157579c0 [file] [log] [blame]
Holger Hans Peter Freyther17c31ce2013-08-24 18:31:27 +02001/* Copied from gprs_bssgp_pcu.cpp
2 *
3 * Copyright (C) 2012 Ivan Klyuchnikov
Holger Hans Peter Freyther86921282013-08-24 21:26:42 +02004 * Copyright (C) 2012 Andreas Eversberg <jolly@eversberg.eu>
Holger Hans Peter Freyther17c31ce2013-08-24 18:31:27 +02005 * Copyright (C) 2013 by Holger Hans Peter Freyther
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
Holger Hans Peter Freyther67ed34e2013-10-17 17:01:54 +020022#include <bts.h>
Holger Hans Peter Freyther17c31ce2013-08-24 18:31:27 +020023#include <tbf.h>
Holger Hans Peter Freytherd11290b2013-10-26 17:32:04 +020024#include <rlc.h>
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +020025#include <encoding.h>
Holger Hans Peter Freyther17c31ce2013-08-24 18:31:27 +020026#include <gprs_rlcmac.h>
27#include <gprs_debug.h>
Holger Hans Peter Freyther3dc56a32013-10-26 21:38:30 +020028#include <gprs_bssgp_pcu.h>
Holger Hans Peter Freyther77e05972013-11-06 19:16:43 +010029#include <decoding.h>
Holger Hans Peter Freyther17c31ce2013-08-24 18:31:27 +020030
31extern "C" {
32#include <osmocom/core/msgb.h>
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +020033#include <osmocom/core/talloc.h>
Holger Hans Peter Freyther17c31ce2013-08-24 18:31:27 +020034}
35
36#include <errno.h>
37#include <string.h>
38
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +020039extern void *tall_pcu_ctx;
40
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +020041static void tbf_timer_cb(void *_tbf);
42
Daniel Willmannca102af2014-08-08 12:14:12 +020043gprs_rlcmac_bts *gprs_rlcmac_tbf::bts_data() const
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +020044{
45 return bts->bts_data();
46}
47
Holger Hans Peter Freyther5464c9b2013-10-27 20:57:35 +010048void gprs_rlcmac_tbf::assign_imsi(const char *imsi)
Holger Hans Peter Freytherd8689282013-08-24 20:51:06 +020049{
Holger Hans Peter Freyther5464c9b2013-10-27 20:57:35 +010050 strncpy(m_imsi, imsi, sizeof(m_imsi));
51 m_imsi[sizeof(m_imsi) - 1] = '\0';
Holger Hans Peter Freytherd8689282013-08-24 20:51:06 +020052}
53
Daniel Willmanne4818152014-08-15 16:52:09 +020054void gprs_rlcmac_tbf::set_new_tbf(gprs_rlcmac_tbf *tbf)
55{
56 m_new_tbf = tbf;
57}
58
Daniel Willmann0d12a2f2014-07-10 17:44:07 +020059gprs_rlcmac_ul_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts,
Holger Hans Peter Freyther86921282013-08-24 21:26:42 +020060 int8_t use_trx, uint8_t ms_class,
61 uint32_t tlli, uint8_t ta, struct gprs_rlcmac_tbf *dl_tbf)
62{
63 uint8_t trx;
Daniel Willmann0d12a2f2014-07-10 17:44:07 +020064 struct gprs_rlcmac_ul_tbf *tbf;
Holger Hans Peter Freyther5697b4c2013-11-11 16:22:39 +010065 int8_t tfi; /* must be signed */
Holger Hans Peter Freyther86921282013-08-24 21:26:42 +020066
67#warning "Copy and paste with tbf_new_dl_assignment"
Holger Hans Peter Freytherba263682013-12-25 19:15:57 +010068 /* create new TBF, use same TRX as DL TBF */
Holger Hans Peter Freyther70ddde62013-10-26 19:17:58 +020069 tfi = bts->bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx, use_trx);
Holger Hans Peter Freyther86921282013-08-24 21:26:42 +020070 if (tfi < 0) {
Holger Hans Peter Freyther90b87ea2013-10-27 10:38:31 +010071 LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n");
Holger Hans Peter Freyther86921282013-08-24 21:26:42 +020072 /* FIXME: send reject */
73 return NULL;
74 }
75 /* use multislot class of downlink TBF */
Daniel Willmann48aa0b02014-07-16 18:54:10 +020076 tbf = tbf_alloc_ul_tbf(bts, dl_tbf, tfi, trx, ms_class, 0);
Holger Hans Peter Freyther86921282013-08-24 21:26:42 +020077 if (!tbf) {
Holger Hans Peter Freyther90b87ea2013-10-27 10:38:31 +010078 LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n");
Holger Hans Peter Freyther86921282013-08-24 21:26:42 +020079 /* FIXME: send reject */
80 return NULL;
81 }
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +010082 tbf->m_tlli = tlli;
83 tbf->m_tlli_valid = 1; /* no contention resolution */
Daniel Willmann7e994e32014-08-07 15:49:21 +020084 tbf->m_contention_resolution_done = 1;
Holger Hans Peter Freyther86921282013-08-24 21:26:42 +020085 tbf->ta = ta; /* use current TA */
Daniel Willmanneb100242014-08-08 11:43:53 +020086 tbf->set_state(GPRS_RLCMAC_ASSIGN);
Holger Hans Peter Freyther86921282013-08-24 21:26:42 +020087 tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH);
88 tbf_timer_start(tbf, 3169, bts->t3169, 0);
89
90 return tbf;
91}
Holger Hans Peter Freyther964ddb62013-10-16 17:53:23 +020092
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +020093static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf)
94{
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +020095 int ts;
96
97 if (tbf->direction == GPRS_RLCMAC_UL_TBF) {
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +010098 tbf->trx->ul_tbf[tbf->tfi()] = NULL;
Daniel Willmann17a1d5e2014-05-30 20:21:30 +020099 for (ts = 0; ts < 8; ts++)
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200100 tbf->pdch[ts] = NULL;
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200101 } else {
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100102 tbf->trx->dl_tbf[tbf->tfi()] = NULL;
Daniel Willmann17a1d5e2014-05-30 20:21:30 +0200103 for (ts = 0; ts < 8; ts++)
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200104 tbf->pdch[ts] = NULL;
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200105 }
106}
107
108void tbf_free(struct gprs_rlcmac_tbf *tbf)
109{
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200110 /* Give final measurement report */
111 gprs_rlcmac_rssi_rep(tbf);
Daniel Willmann418a4232014-08-08 11:21:04 +0200112 if (tbf->direction == GPRS_RLCMAC_DL_TBF) {
113 gprs_rlcmac_dl_tbf *dl_tbf = static_cast<gprs_rlcmac_dl_tbf *>(tbf);
114 gprs_rlcmac_lost_rep(dl_tbf);
115 }
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200116
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100117 LOGP(DRLCMAC, LOGL_INFO, "%s free\n", tbf_name(tbf));
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200118 if (tbf->ul_ass_state != GPRS_RLCMAC_UL_ASS_NONE)
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100119 LOGP(DRLCMAC, LOGL_ERROR, "%s Software error: Pending uplink "
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200120 "assignment. This may not happen, because the "
121 "assignment message never gets transmitted. Please "
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100122 "be sure not to free in this state. PLEASE FIX!\n",
123 tbf_name(tbf));
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200124 if (tbf->dl_ass_state != GPRS_RLCMAC_DL_ASS_NONE)
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100125 LOGP(DRLCMAC, LOGL_ERROR, "%s Software error: Pending downlink "
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200126 "assignment. This may not happen, because the "
127 "assignment message never gets transmitted. Please "
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100128 "be sure not to free in this state. PLEASE FIX!\n",
129 tbf_name(tbf));
Holger Hans Peter Freyther86300bb2013-10-26 18:01:35 +0200130 tbf->stop_timer();
Holger Hans Peter Freyther782f6dd2013-10-26 18:31:51 +0200131 #warning "TODO: Could/Should generate bssgp_tx_llc_discarded"
Holger Hans Peter Freyther758dc122013-11-06 20:39:45 +0100132 tbf->m_llc.clear(tbf->bts);
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200133 tbf_unlink_pdch(tbf);
Daniel Willmann1b3864f2014-07-30 13:25:19 +0200134 llist_del(&tbf->list.list);
Holger Hans Peter Freyther15877642013-10-27 09:50:15 +0100135
136 if (tbf->direction == GPRS_RLCMAC_UL_TBF)
137 tbf->bts->tbf_ul_freed();
138 else
139 tbf->bts->tbf_dl_freed();
140
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200141 LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF ends here **********\n");
142 talloc_free(tbf);
143}
144
Holger Hans Peter Freytheraa9c3262013-10-26 17:49:36 +0200145int gprs_rlcmac_tbf::update()
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200146{
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200147 struct gprs_rlcmac_tbf *ul_tbf = NULL;
Holger Hans Peter Freytheraa9c3262013-10-26 17:49:36 +0200148 struct gprs_rlcmac_bts *bts_data = bts->bts_data();
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200149 int rc;
150
151 LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF update **********\n");
152
Holger Hans Peter Freytheraa9c3262013-10-26 17:49:36 +0200153 if (direction != GPRS_RLCMAC_DL_TBF)
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200154 return -EINVAL;
155
Daniel Willmannb59d61b2014-07-02 17:58:14 +0200156 ul_tbf = bts->ul_tbf_by_tlli(m_tlli);
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200157
Holger Hans Peter Freytheraa9c3262013-10-26 17:49:36 +0200158 tbf_unlink_pdch(this);
159 rc = bts_data->alloc_algorithm(bts_data, ul_tbf, this, bts_data->alloc_algorithm_curst, 0);
Holger Hans Peter Freyther90b87ea2013-10-27 10:38:31 +0100160 /* if no resource */
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200161 if (rc < 0) {
Holger Hans Peter Freyther90b87ea2013-10-27 10:38:31 +0100162 LOGP(DRLCMAC, LOGL_ERROR, "No resource after update???\n");
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200163 return -rc;
164 }
165
166 return 0;
167}
168
169int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf)
170{
171 if (tbf->control_ts == 0xff)
172 LOGP(DRLCMAC, LOGL_INFO, "- Setting Control TS %d\n",
173 tbf->first_common_ts);
174 else if (tbf->control_ts != tbf->first_common_ts)
175 LOGP(DRLCMAC, LOGL_INFO, "- Changing Control TS %d\n",
176 tbf->first_common_ts);
177 tbf->control_ts = tbf->first_common_ts;
178
179 return 0;
180}
181
Daniel Willmanneb100242014-08-08 11:43:53 +0200182const char *gprs_rlcmac_tbf::tbf_state_name[] = {
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200183 "NULL",
184 "ASSIGN",
185 "FLOW",
186 "FINISHED",
187 "WAIT RELEASE",
188 "RELEASING",
189};
190
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200191void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T,
192 unsigned int seconds, unsigned int microseconds)
193{
194 if (!osmo_timer_pending(&tbf->timer))
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100195 LOGP(DRLCMAC, LOGL_DEBUG, "%s starting timer %u.\n",
196 tbf_name(tbf), T);
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200197 else
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100198 LOGP(DRLCMAC, LOGL_DEBUG, "%s restarting timer %u "
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200199 "while old timer %u pending \n",
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100200 tbf_name(tbf), T, tbf->T);
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200201
202 tbf->T = T;
203 tbf->num_T_exp = 0;
204
205 /* Tunning timers can be safely re-scheduled. */
206 tbf->timer.data = tbf;
207 tbf->timer.cb = &tbf_timer_cb;
208
209 osmo_timer_schedule(&tbf->timer, seconds, microseconds);
210}
211
Holger Hans Peter Freyther86300bb2013-10-26 18:01:35 +0200212void gprs_rlcmac_tbf::stop_t3191()
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200213{
Holger Hans Peter Freyther86300bb2013-10-26 18:01:35 +0200214 return stop_timer();
215}
216
217void gprs_rlcmac_tbf::stop_timer()
218{
219 if (osmo_timer_pending(&timer)) {
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100220 LOGP(DRLCMAC, LOGL_DEBUG, "%s stopping timer %u.\n",
221 tbf_name(this), T);
Holger Hans Peter Freyther86300bb2013-10-26 18:01:35 +0200222 osmo_timer_del(&timer);
Holger Hans Peter Freyther45561302013-10-16 17:55:57 +0200223 }
224}
225
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200226void gprs_rlcmac_tbf::poll_timeout()
227{
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100228 LOGP(DRLCMAC, LOGL_NOTICE, "%s poll timeout\n",
229 tbf_name(this));
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200230
231 poll_state = GPRS_RLCMAC_POLL_NONE;
232
233 if (ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) {
234 if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK))) {
235 LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
236 "PACKET CONTROL ACK for PACKET UPLINK ACK\n");
237 rlcmac_diag();
238 state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK);
239 }
240 ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE;
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200241 if (state_is(GPRS_RLCMAC_FINISHED)) {
Daniel Willmann6a16e0c2014-08-07 13:03:35 +0200242 gprs_rlcmac_ul_tbf *ul_tbf = static_cast<gprs_rlcmac_ul_tbf *>(this);
Daniel Willmann7e994e32014-08-07 15:49:21 +0200243 ul_tbf->m_n3103++;
244 if (ul_tbf->m_n3103 == ul_tbf->bts->bts_data()->n3103) {
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200245 LOGP(DRLCMAC, LOGL_NOTICE,
246 "- N3103 exceeded\n");
Daniel Willmanneb100242014-08-08 11:43:53 +0200247 ul_tbf->set_state(GPRS_RLCMAC_RELEASING);
Daniel Willmann6a16e0c2014-08-07 13:03:35 +0200248 tbf_timer_start(ul_tbf, 3169, ul_tbf->bts->bts_data()->t3169, 0);
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200249 return;
250 }
251 /* reschedule UL ack */
Daniel Willmann6a16e0c2014-08-07 13:03:35 +0200252 ul_tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_SEND_ACK;
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200253 }
254 } else if (ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) {
255 if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) {
256 LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
257 "PACKET CONTROL ACK for PACKET UPLINK "
258 "ASSIGNMENT.\n");
259 rlcmac_diag();
260 state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS);
261 }
262 ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200263 n3105++;
264 if (n3105 == bts_data()->n3105) {
265 LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
Daniel Willmanneb100242014-08-08 11:43:53 +0200266 set_state(GPRS_RLCMAC_RELEASING);
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200267 tbf_timer_start(this, 3195, bts_data()->t3195, 0);
268 return;
269 }
270 /* reschedule UL assignment */
271 ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
272 } else if (dl_ass_state == GPRS_RLCMAC_DL_ASS_WAIT_ACK) {
273 if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) {
274 LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
275 "PACKET CONTROL ACK for PACKET DOWNLINK "
276 "ASSIGNMENT.\n");
277 rlcmac_diag();
278 state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS);
279 }
280 dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200281 n3105++;
282 if (n3105 == bts->bts_data()->n3105) {
283 LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
Daniel Willmanneb100242014-08-08 11:43:53 +0200284 set_state(GPRS_RLCMAC_RELEASING);
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200285 tbf_timer_start(this, 3195, bts_data()->t3195, 0);
286 return;
287 }
288 /* reschedule DL assignment */
289 dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS;
290 } else if (direction == GPRS_RLCMAC_DL_TBF) {
Daniel Willmann6a16e0c2014-08-07 13:03:35 +0200291 gprs_rlcmac_dl_tbf *dl_tbf = static_cast<gprs_rlcmac_dl_tbf *>(this);
292
293 if (!(dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) {
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200294 LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
295 "PACKET DOWNLINK ACK.\n");
Daniel Willmann6a16e0c2014-08-07 13:03:35 +0200296 dl_tbf->rlcmac_diag();
297 dl_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK);
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200298 }
Daniel Willmann6a16e0c2014-08-07 13:03:35 +0200299 dl_tbf->n3105++;
300 if (dl_tbf->n3105 == dl_tbf->bts->bts_data()->n3105) {
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200301 LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
Daniel Willmanneb100242014-08-08 11:43:53 +0200302 dl_tbf->set_state(GPRS_RLCMAC_RELEASING);
Daniel Willmann6a16e0c2014-08-07 13:03:35 +0200303 tbf_timer_start(dl_tbf, 3195, dl_tbf->bts_data()->t3195, 0);
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200304 return;
305 }
306 /* resend IMM.ASS on CCCH on timeout */
Daniel Willmann6a16e0c2014-08-07 13:03:35 +0200307 if ((dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))
308 && !(dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) {
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200309 LOGP(DRLCMAC, LOGL_DEBUG, "Re-send dowlink assignment "
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100310 "for %s on PCH (IMSI=%s)\n",
Daniel Willmann6a16e0c2014-08-07 13:03:35 +0200311 tbf_name(dl_tbf),
Holger Hans Peter Freyther5464c9b2013-10-27 20:57:35 +0100312 m_imsi);
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200313 /* send immediate assignment */
Daniel Willmann6a16e0c2014-08-07 13:03:35 +0200314 dl_tbf->bts->snd_dl_ass(dl_tbf, 0, m_imsi);
Daniel Willmann7e994e32014-08-07 15:49:21 +0200315 dl_tbf->m_wait_confirm = 1;
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200316 }
317 } else
318 LOGP(DRLCMAC, LOGL_ERROR, "- Poll Timeout, but no event!\n");
319}
320
Daniel Willmann48aa0b02014-07-16 18:54:10 +0200321static int setup_tbf(struct gprs_rlcmac_tbf *tbf, struct gprs_rlcmac_bts *bts,
322 struct gprs_rlcmac_tbf *old_tbf, uint8_t tfi, uint8_t trx,
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200323 uint8_t ms_class, uint8_t single_slot)
324{
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200325 int rc;
326
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200327 if (trx >= 8 || tfi >= 32)
Daniel Willmann48aa0b02014-07-16 18:54:10 +0200328 return -1;
Daniel Willmann078bb712014-07-10 17:44:06 +0200329
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200330 if (!tbf)
Daniel Willmann48aa0b02014-07-16 18:54:10 +0200331 return -1;
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200332
Daniel Willmann1b3864f2014-07-30 13:25:19 +0200333 /* Back pointer for PODS llist compatibility */
334 tbf->list.back = tbf;
335
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100336 tbf->m_created_ts = time(NULL);
Holger Hans Peter Freyther9f0c1d22013-10-19 21:24:34 +0200337 tbf->bts = bts->bts;
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100338 tbf->m_tfi = tfi;
Holger Hans Peter Freyther743bafa2013-09-29 07:50:50 +0200339 tbf->trx = &bts->trx[trx];
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200340 tbf->ms_class = ms_class;
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200341 /* select algorithm */
342 rc = bts->alloc_algorithm(bts, old_tbf, tbf, bts->alloc_algorithm_curst,
343 single_slot);
Holger Hans Peter Freyther90b87ea2013-10-27 10:38:31 +0100344 /* if no resource */
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200345 if (rc < 0) {
Daniel Willmann48aa0b02014-07-16 18:54:10 +0200346 return -1;
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200347 }
348 /* assign control ts */
349 tbf->control_ts = 0xff;
350 rc = tbf_assign_control_ts(tbf);
Holger Hans Peter Freyther90b87ea2013-10-27 10:38:31 +0100351 /* if no resource */
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200352 if (rc < 0) {
Daniel Willmann48aa0b02014-07-16 18:54:10 +0200353 return -1;
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200354 }
355
356 /* set timestamp */
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200357 gettimeofday(&tbf->meas.rssi_tv, NULL);
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200358
Holger Hans Peter Freyther758dc122013-11-06 20:39:45 +0100359 tbf->m_llc.init();
Daniel Willmann48aa0b02014-07-16 18:54:10 +0200360 return 0;
361}
362
363
364struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts,
365 struct gprs_rlcmac_tbf *old_tbf, uint8_t tfi, uint8_t trx,
366 uint8_t ms_class, uint8_t single_slot)
367{
368 struct gprs_rlcmac_ul_tbf *tbf;
369 int rc;
370
371 LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n");
372 LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: TFI=%d TRX=%d "
373 "MS_CLASS=%d\n", "UL", tfi, trx, ms_class);
374
375 if (trx >= 8 || tfi >= 32)
376 return NULL;
377
378 tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
379
380 if (!tbf)
381 return NULL;
382
383 tbf->direction = GPRS_RLCMAC_UL_TBF;
384 rc = setup_tbf(tbf, bts, old_tbf, tfi, trx, ms_class, single_slot);
385 /* if no resource */
386 if (rc < 0) {
387 talloc_free(tbf);
388 return NULL;
Holger Hans Peter Freyther15877642013-10-27 09:50:15 +0100389 }
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200390
Daniel Willmann1b3864f2014-07-30 13:25:19 +0200391 llist_add(&tbf->list.list, &bts->ul_tbfs);
Daniel Willmann48aa0b02014-07-16 18:54:10 +0200392 tbf->bts->tbf_ul_created();
393
394 return tbf;
395}
396
397struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
398 struct gprs_rlcmac_tbf *old_tbf, uint8_t tfi, uint8_t trx,
399 uint8_t ms_class, uint8_t single_slot)
400{
401 struct gprs_rlcmac_dl_tbf *tbf;
402 int rc;
403
404 LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n");
405 LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: TFI=%d TRX=%d "
406 "MS_CLASS=%d\n", "DL", tfi, trx, ms_class);
407
408 if (trx >= 8 || tfi >= 32)
409 return NULL;
410
411 tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
412
413 if (!tbf)
414 return NULL;
415
416 tbf->direction = GPRS_RLCMAC_DL_TBF;
417 rc = setup_tbf(tbf, bts, old_tbf, tfi, trx, ms_class, single_slot);
418 /* if no resource */
419 if (rc < 0) {
420 talloc_free(tbf);
421 return NULL;
422 }
423
Daniel Willmann1b3864f2014-07-30 13:25:19 +0200424 llist_add(&tbf->list.list, &bts->dl_tbfs);
Daniel Willmann48aa0b02014-07-16 18:54:10 +0200425 tbf->bts->tbf_dl_created();
426
Daniel Willmann418a4232014-08-08 11:21:04 +0200427 gettimeofday(&tbf->m_bw.dl_bw_tv, NULL);
428 gettimeofday(&tbf->m_bw.dl_loss_tv, NULL);
429
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200430 return tbf;
431}
432
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +0200433static void tbf_timer_cb(void *_tbf)
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200434{
435 struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)_tbf;
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +0200436 tbf->handle_timeout();
437}
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200438
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +0200439void gprs_rlcmac_tbf::handle_timeout()
440{
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100441 LOGP(DRLCMAC, LOGL_DEBUG, "%s timer %u expired.\n",
442 tbf_name(this), T);
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200443
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +0200444 num_T_exp++;
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200445
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +0200446 switch (T) {
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200447 case 0: /* assignment */
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +0200448 if ((state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) {
449 if (state_is(GPRS_RLCMAC_ASSIGN)) {
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100450 LOGP(DRLCMAC, LOGL_NOTICE, "%s releasing due to "
451 "PACCH assignment timeout.\n", tbf_name(this));
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +0200452 tbf_free(this);
Holger Hans Peter Freyther3d0cc2f2014-01-16 10:09:42 +0100453 return;
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200454 } else
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100455 LOGP(DRLCMAC, LOGL_ERROR, "Error: %s is not "
456 "in assign state\n", tbf_name(this));
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200457 }
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +0200458 if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) {
Daniel Willmann532a4b52014-08-07 12:39:26 +0200459 gprs_rlcmac_dl_tbf *dl_tbf = static_cast<gprs_rlcmac_dl_tbf *>(this);
Daniel Willmann7e994e32014-08-07 15:49:21 +0200460 dl_tbf->m_wait_confirm = 0;
Daniel Willmann532a4b52014-08-07 12:39:26 +0200461 if (dl_tbf->state_is(GPRS_RLCMAC_ASSIGN)) {
462 tbf_assign_control_ts(dl_tbf);
Daniel Willmanncf1fae72014-05-30 17:58:01 +0200463
Daniel Willmann532a4b52014-08-07 12:39:26 +0200464 if (!dl_tbf->upgrade_to_multislot) {
Daniel Willmanncf1fae72014-05-30 17:58:01 +0200465 /* change state to FLOW, so scheduler
466 * will start transmission */
Daniel Willmanneb100242014-08-08 11:43:53 +0200467 dl_tbf->set_state(GPRS_RLCMAC_FLOW);
Daniel Willmanncf1fae72014-05-30 17:58:01 +0200468 break;
469 }
470
471 /* This tbf can be upgraded to use multiple DL
472 * timeslots and now that there is already one
473 * slot assigned send another DL assignment via
474 * PDCH. */
475
476 /* keep to flags */
Daniel Willmann532a4b52014-08-07 12:39:26 +0200477 dl_tbf->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK;
478 dl_tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH);
Daniel Willmanncf1fae72014-05-30 17:58:01 +0200479
Daniel Willmann532a4b52014-08-07 12:39:26 +0200480 dl_tbf->update();
Daniel Willmanncf1fae72014-05-30 17:58:01 +0200481
Daniel Willmann532a4b52014-08-07 12:39:26 +0200482 dl_tbf->bts->trigger_dl_ass(dl_tbf, dl_tbf, NULL);
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200483 } else
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100484 LOGP(DRLCMAC, LOGL_NOTICE, "%s Continue flow after "
Daniel Willmann532a4b52014-08-07 12:39:26 +0200485 "IMM.ASS confirm\n", tbf_name(dl_tbf));
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200486 }
487 break;
488 case 3169:
489 case 3191:
490 case 3195:
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100491 LOGP(DRLCMAC, LOGL_NOTICE, "%s T%d timeout during "
492 "transsmission\n", tbf_name(this), T);
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +0200493 rlcmac_diag();
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200494 /* fall through */
495 case 3193:
Holger Hans Peter Freyther8d0e4892013-10-27 12:42:58 +0100496 LOGP(DRLCMAC, LOGL_DEBUG,
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100497 "%s will be freed due to timeout\n", tbf_name(this));
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200498 /* free TBF */
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +0200499 tbf_free(this);
Holger Hans Peter Freyther3d0cc2f2014-01-16 10:09:42 +0100500 return;
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200501 break;
502 default:
Holger Hans Peter Freyther8d0e4892013-10-27 12:42:58 +0100503 LOGP(DRLCMAC, LOGL_ERROR,
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100504 "%s timer expired in unknown mode: %u\n", tbf_name(this), T);
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200505 }
506}
507
508int gprs_rlcmac_tbf::rlcmac_diag()
509{
510 if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)))
511 LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on CCCH\n");
512 if ((state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH)))
513 LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on PACCH\n");
514 if ((state_flags & (1 << GPRS_RLCMAC_FLAG_UL_DATA)))
515 LOGP(DRLCMAC, LOGL_NOTICE, "- Uplink data was received\n");
516 else if (direction == GPRS_RLCMAC_UL_TBF)
517 LOGP(DRLCMAC, LOGL_NOTICE, "- No uplink data received yet\n");
518 if ((state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK)))
519 LOGP(DRLCMAC, LOGL_NOTICE, "- Downlink ACK was received\n");
520 else if (direction == GPRS_RLCMAC_DL_TBF)
521 LOGP(DRLCMAC, LOGL_NOTICE, "- No downlink ACK received yet\n");
522
523 return 0;
524}
525
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200526struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn)
527{
528 struct msgb *msg;
Daniel Willmannb2886f12014-08-07 14:48:20 +0200529 struct gprs_rlcmac_dl_tbf *new_dl_tbf;
Holger Hans Peter Freyther9977e152013-11-24 22:52:10 +0100530 int poll_ass_dl = 1;
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200531
Holger Hans Peter Freyther9977e152013-11-24 22:52:10 +0100532 if (direction == GPRS_RLCMAC_DL_TBF && control_ts != first_common_ts) {
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200533 LOGP(DRLCMAC, LOGL_NOTICE, "Cannot poll for downlink "
534 "assigment, because MS cannot reply. (control TS=%d, "
535 "first common TS=%d)\n", control_ts,
536 first_common_ts);
537 poll_ass_dl = 0;
538 }
539 if (poll_ass_dl) {
540 if (poll_state != GPRS_RLCMAC_POLL_NONE) {
541 LOGP(DRLCMAC, LOGL_DEBUG, "Polling is already sheduled "
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100542 "for %s, so we must wait for downlink "
543 "assignment...\n", tbf_name(this));
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200544 return NULL;
545 }
Holger Hans Peter Freytherec80f822013-10-27 13:44:37 +0100546 if (bts->sba()->find(trx->trx_no, control_ts, (fn + 13) % 2715648)) {
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200547 LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already "
548 "scheduled for single block allocation...\n");
549 return NULL;
550 }
551 }
552
553 /* on uplink TBF we get the downlink TBF to be assigned. */
554 if (direction == GPRS_RLCMAC_UL_TBF) {
Daniel Willmannb2886f12014-08-07 14:48:20 +0200555 gprs_rlcmac_ul_tbf *ul_tbf = static_cast<gprs_rlcmac_ul_tbf *>(this);
556
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200557 /* be sure to check first, if contention resolution is done,
558 * otherwise we cannot send the assignment yet */
Daniel Willmann7e994e32014-08-07 15:49:21 +0200559 if (!ul_tbf->m_contention_resolution_done) {
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200560 LOGP(DRLCMAC, LOGL_DEBUG, "Cannot assign DL TBF now, "
561 "because contention resolution is not "
562 "finished.\n");
563 return NULL;
564 }
Daniel Willmanne4818152014-08-15 16:52:09 +0200565 }
566
567 new_dl_tbf = static_cast<gprs_rlcmac_dl_tbf *>(m_new_tbf);
568 new_dl_tbf->was_releasing = was_releasing;
Daniel Willmannb2886f12014-08-07 14:48:20 +0200569 if (!new_dl_tbf) {
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200570 LOGP(DRLCMACDL, LOGL_ERROR, "We have a schedule for downlink "
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100571 "assignment at uplink %s, but there is no downlink "
572 "TBF\n", tbf_name(this));
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200573 dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
574 return NULL;
575 }
576
577 msg = msgb_alloc(23, "rlcmac_dl_ass");
578 if (!msg)
579 return NULL;
580 bitvec *ass_vec = bitvec_alloc(23);
581 if (!ass_vec) {
582 msgb_free(msg);
583 return NULL;
584 }
585 bitvec_unhex(ass_vec,
586 "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
Daniel Willmannb2886f12014-08-07 14:48:20 +0200587 LOGP(DRLCMAC, LOGL_INFO, "%s start Packet Downlink Assignment (PACCH)\n", tbf_name(new_dl_tbf));
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200588 RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t);
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100589 Encoding::write_packet_downlink_assignment(mac_control_block, m_tfi,
Daniel Willmannb2886f12014-08-07 14:48:20 +0200590 (direction == GPRS_RLCMAC_DL_TBF), new_dl_tbf,
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200591 poll_ass_dl, bts_data()->alpha, bts_data()->gamma, -1, 0);
592 LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++\n");
593 encode_gsm_rlcmac_downlink(ass_vec, mac_control_block);
594 LOGPC(DCSN1, LOGL_NOTICE, "\n");
595 LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- TX : Packet Downlink Assignment -------------------------\n");
596 bitvec_pack(ass_vec, msgb_put(msg, 23));
597 bitvec_free(ass_vec);
598 talloc_free(mac_control_block);
599
600 if (poll_ass_dl) {
601 poll_state = GPRS_RLCMAC_POLL_SCHED;
602 poll_fn = (fn + 13) % 2715648;
603 dl_ass_state = GPRS_RLCMAC_DL_ASS_WAIT_ACK;
604 } else {
605 dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
Daniel Willmanneb100242014-08-08 11:43:53 +0200606 new_dl_tbf->set_state(GPRS_RLCMAC_FLOW);
Daniel Willmannb2886f12014-08-07 14:48:20 +0200607 tbf_assign_control_ts(new_dl_tbf);
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200608 /* stop pending assignment timer */
Daniel Willmannb2886f12014-08-07 14:48:20 +0200609 new_dl_tbf->stop_timer();
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200610
611 }
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200612
613 return msg;
614}
615
Holger Hans Peter Freytherae03f222013-10-26 21:20:51 +0200616struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn)
617{
618 struct msgb *msg;
Daniel Willmann350f64d2014-08-07 14:54:11 +0200619 struct gprs_rlcmac_ul_tbf *new_tbf;
Holger Hans Peter Freytherae03f222013-10-26 21:20:51 +0200620
Holger Hans Peter Freytherae03f222013-10-26 21:20:51 +0200621 if (poll_state != GPRS_RLCMAC_POLL_NONE) {
622 LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already "
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100623 "sheduled for %s, so we must wait for uplink "
624 "assignment...\n", tbf_name(this));
Holger Hans Peter Freytherae03f222013-10-26 21:20:51 +0200625 return NULL;
626 }
Holger Hans Peter Freytherec80f822013-10-27 13:44:37 +0100627 if (bts->sba()->find(trx->trx_no, control_ts, (fn + 13) % 2715648)) {
Holger Hans Peter Freytherae03f222013-10-26 21:20:51 +0200628 LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already scheduled for "
629 "single block allocation...\n");
630 return NULL;
631 }
Holger Hans Peter Freytherae03f222013-10-26 21:20:51 +0200632
Daniel Willmanne4818152014-08-15 16:52:09 +0200633 new_tbf = static_cast<gprs_rlcmac_ul_tbf *>(m_new_tbf);
Holger Hans Peter Freytherae03f222013-10-26 21:20:51 +0200634 if (!new_tbf) {
635 LOGP(DRLCMACUL, LOGL_ERROR, "We have a schedule for uplink "
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100636 "assignment at downlink %s, but there is no uplink "
637 "TBF\n", tbf_name(this));
Holger Hans Peter Freytherae03f222013-10-26 21:20:51 +0200638 ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
639 return NULL;
640 }
641
642 msg = msgb_alloc(23, "rlcmac_ul_ass");
643 if (!msg)
644 return NULL;
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100645 LOGP(DRLCMAC, LOGL_INFO, "%ss start Packet Uplink Assignment (PACCH)\n", tbf_name(new_tbf));
Holger Hans Peter Freytherae03f222013-10-26 21:20:51 +0200646 bitvec *ass_vec = bitvec_alloc(23);
647 if (!ass_vec) {
648 msgb_free(msg);
649 return NULL;
650 }
651 bitvec_unhex(ass_vec,
652 "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100653 Encoding::write_packet_uplink_assignment(bts_data(), ass_vec, m_tfi,
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100654 (direction == GPRS_RLCMAC_DL_TBF), m_tlli,
Holger Hans Peter Freyther9977e152013-11-24 22:52:10 +0100655 m_tlli_valid, new_tbf, 1, bts_data()->alpha,
Holger Hans Peter Freytherae03f222013-10-26 21:20:51 +0200656 bts_data()->gamma, -1);
657 bitvec_pack(ass_vec, msgb_put(msg, 23));
658 RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t);
659 LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++\n");
660 decode_gsm_rlcmac_downlink(ass_vec, mac_control_block);
661 LOGPC(DCSN1, LOGL_NOTICE, "\n");
662 LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- TX : Packet Uplink Assignment -------------------------\n");
663 bitvec_free(ass_vec);
664 talloc_free(mac_control_block);
665
Holger Hans Peter Freytherae03f222013-10-26 21:20:51 +0200666 poll_state = GPRS_RLCMAC_POLL_SCHED;
667 poll_fn = (fn + 13) % 2715648;
668 ul_ass_state = GPRS_RLCMAC_UL_ASS_WAIT_ACK;
Holger Hans Peter Freytherae03f222013-10-26 21:20:51 +0200669
670 return msg;
671}
672
Holger Hans Peter Freyther964ddb62013-10-16 17:53:23 +0200673void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_trx *trx)
674{
675 for (uint8_t tfi = 0; tfi < 32; tfi++) {
676 struct gprs_rlcmac_tbf *tbf;
677
678 tbf = trx->ul_tbf[tfi];
679 if (tbf)
680 tbf_free(tbf);
681 tbf = trx->dl_tbf[tfi];
682 if (tbf)
683 tbf_free(tbf);
684 }
685}
Holger Hans Peter Freyther4f6a4e5d2013-10-16 17:58:46 +0200686
687void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_pdch *pdch)
688{
689 for (uint8_t tfi = 0; tfi < 32; tfi++) {
690 struct gprs_rlcmac_tbf *tbf;
691
Daniel Willmann17a1d5e2014-05-30 20:21:30 +0200692 tbf = pdch->ul_tbf_by_tfi(tfi);
Holger Hans Peter Freyther4f6a4e5d2013-10-16 17:58:46 +0200693 if (tbf)
694 tbf_free(tbf);
Daniel Willmann17a1d5e2014-05-30 20:21:30 +0200695 tbf = pdch->dl_tbf_by_tfi(tfi);
Holger Hans Peter Freyther4f6a4e5d2013-10-16 17:58:46 +0200696 if (tbf)
697 tbf_free(tbf);
698 }
699}
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100700
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100701void gprs_rlcmac_tbf::tlli_mark_valid()
702{
703 m_tlli_valid = true;
704}
705
706void gprs_rlcmac_tbf::update_tlli(uint32_t tlli)
707{
708 if (tlli == m_tlli)
709 return;
710
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100711 bool changedUl = false;
712
713 /*
714 * During a Routing Area Update (due the assignment of a new
715 * P-TMSI) the tlli can change. We notice this when receiving
716 * a PACKET CONTROL ACK.
717 * When we get a TLLI change on the DL we will look if there
718 * is a UL TBF and change the tlli there as well.
719 *
720 * TODO: There could be multiple DL and UL TBFs and we should
721 * have a proper way to link all the related TBFs so we can do
722 * a group update.
723 */
724 if (m_tlli_valid && direction == GPRS_RLCMAC_DL_TBF) {
725 gprs_rlcmac_tbf *ul_tbf;
Daniel Willmannb59d61b2014-07-02 17:58:14 +0200726 ul_tbf = bts->ul_tbf_by_tlli(m_tlli);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100727
728 if (ul_tbf) {
729 ul_tbf->m_tlli = tlli;
730 changedUl = true;
731 }
732 }
733
Holger Hans Peter Freytherbc1626e2013-10-30 19:50:49 +0100734 /* update the timing advance for the new tlli */
735 bts->timing_advance()->update(m_tlli, tlli, ta);
736
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100737 LOGP(DRLCMAC, LOGL_NOTICE,
738 "%s changing tlli from TLLI=0x%08x TLLI=0x%08x ul_changed=%d\n",
739 tbf_name(this), m_tlli, tlli, changedUl);
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100740 m_tlli = tlli;
741}
742
Holger Hans Peter Freyther4c06d912013-11-25 23:05:26 +0100743int gprs_rlcmac_tbf::extract_tlli(const uint8_t *data, const size_t len)
744{
745 struct gprs_rlcmac_tbf *dl_tbf, *ul_tbf;
746 struct rlc_ul_header *rh = (struct rlc_ul_header *)data;
747 uint32_t new_tlli;
748 int rc;
749
750 /* no TLLI yet */
751 if (!rh->ti) {
752 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA TFI=%d without "
753 "TLLI, but no TLLI received yet\n", rh->tfi);
754 return 0;
755 }
756 rc = Decoding::tlli_from_ul_data(data, len, &new_tlli);
757 if (rc) {
758 bts->decode_error();
759 LOGP(DRLCMACUL, LOGL_NOTICE, "Failed to decode TLLI "
760 "of UL DATA TFI=%d.\n", rh->tfi);
761 return 0;
762 }
763 update_tlli(new_tlli);
764 LOGP(DRLCMACUL, LOGL_INFO, "Decoded premier TLLI=0x%08x of "
765 "UL DATA TFI=%d.\n", tlli(), rh->tfi);
Daniel Willmannb59d61b2014-07-02 17:58:14 +0200766 if ((dl_tbf = bts->dl_tbf_by_tlli(tlli()))) {
Holger Hans Peter Freyther4c06d912013-11-25 23:05:26 +0100767 LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
768 "TLLI=0x%08x while %s still exists. "
769 "Killing pending DL TBF\n", tlli(),
770 tbf_name(dl_tbf));
771 tbf_free(dl_tbf);
Holger Hans Peter Freyther3d0cc2f2014-01-16 10:09:42 +0100772 dl_tbf = NULL;
Holger Hans Peter Freyther4c06d912013-11-25 23:05:26 +0100773 }
Daniel Willmannb59d61b2014-07-02 17:58:14 +0200774 /* ul_tbf_by_tlli will not find your TLLI, because it is not
Holger Hans Peter Freyther4c06d912013-11-25 23:05:26 +0100775 * yet marked valid */
Daniel Willmannb59d61b2014-07-02 17:58:14 +0200776 if ((ul_tbf = bts->ul_tbf_by_tlli(tlli()))) {
Holger Hans Peter Freyther4c06d912013-11-25 23:05:26 +0100777 LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
778 "TLLI=0x%08x while %s still exists. "
779 "Killing pending UL TBF\n", tlli(),
780 tbf_name(ul_tbf));
781 tbf_free(ul_tbf);
Holger Hans Peter Freyther3d0cc2f2014-01-16 10:09:42 +0100782 ul_tbf = NULL;
Holger Hans Peter Freyther4c06d912013-11-25 23:05:26 +0100783 }
784 /* mark TLLI valid now */
785 tlli_mark_valid();
786 /* store current timing advance */
787 bts->timing_advance()->remember(tlli(), ta);
788 return 1;
789}
790
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100791const char *tbf_name(gprs_rlcmac_tbf *tbf)
792{
Daniel Willmann08e57c82014-08-15 18:11:57 +0200793 static char buf[60];
794 snprintf(buf, sizeof(buf), "TBF(TFI=%d TLLI=0x%08x DIR=%s STATE=%s)",
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100795 tbf->m_tfi, tbf->m_tlli,
Daniel Willmann08e57c82014-08-15 18:11:57 +0200796 tbf->direction == GPRS_RLCMAC_UL_TBF ? "UL" : "DL",
797 tbf->state_name()
798 );
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100799 buf[sizeof(buf) - 1] = '\0';
800 return buf;
801}
Holger Hans Peter Freyther758dc122013-11-06 20:39:45 +0100802
Holger Hans Peter Freyther7a5f3c22013-11-26 13:08:12 +0100803void gprs_rlcmac_tbf::rotate_in_list()
804{
Daniel Willmann1b3864f2014-07-30 13:25:19 +0200805 llist_del(&list.list);
Holger Hans Peter Freyther7a5f3c22013-11-26 13:08:12 +0100806 if (direction == GPRS_RLCMAC_UL_TBF)
Daniel Willmann1b3864f2014-07-30 13:25:19 +0200807 llist_add(&list.list, &bts->bts_data()->ul_tbfs);
Holger Hans Peter Freyther7a5f3c22013-11-26 13:08:12 +0100808 else
Daniel Willmann1b3864f2014-07-30 13:25:19 +0200809 llist_add(&list.list, &bts->bts_data()->dl_tbfs);
Holger Hans Peter Freyther7a5f3c22013-11-26 13:08:12 +0100810}
Holger Hans Peter Freyther8f399de2013-12-25 20:22:35 +0100811
812uint8_t gprs_rlcmac_tbf::tsc() const
813{
814 return trx->pdch[first_ts].tsc;
815}
Daniel Willmannafa72f52014-01-15 17:06:19 +0100816
817void tbf_print_vty_info(struct vty *vty, llist_head *ltbf)
818{
Daniel Willmann1b3864f2014-07-30 13:25:19 +0200819 gprs_rlcmac_tbf *tbf = llist_pods_entry(ltbf, gprs_rlcmac_tbf);
Daniel Willmannafa72f52014-01-15 17:06:19 +0100820
Daniel Willmann772415f2014-01-15 17:06:51 +0100821 vty_out(vty, "TBF: TFI=%d TLLI=0x%08x (%s) DIR=%s IMSI=%s%s", tbf->tfi(),
Daniel Willmannafa72f52014-01-15 17:06:19 +0100822 tbf->tlli(), tbf->is_tlli_valid() ? "valid" : "invalid",
823 tbf->direction == GPRS_RLCMAC_UL_TBF ? "UL" : "DL",
824 tbf->imsi(), VTY_NEWLINE);
Daniel Willmann80367aa2014-01-15 17:40:28 +0100825 vty_out(vty, " created=%lu state=%08x 1st_TS=%d 1st_cTS=%d ctrl_TS=%d "
Daniel Willmannafa72f52014-01-15 17:06:19 +0100826 "MS_CLASS=%d%s",
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100827 tbf->created_ts(), tbf->state_flags, tbf->first_ts,
Daniel Willmann80367aa2014-01-15 17:40:28 +0100828 tbf->first_common_ts, tbf->control_ts, tbf->ms_class,
829 VTY_NEWLINE);
Daniel Willmannafa72f52014-01-15 17:06:19 +0100830 vty_out(vty, " TS_alloc=");
831 for (int i = 0; i < 8; i++) {
832 if (tbf->pdch[i])
833 vty_out(vty, "%d ", i);
834 }
Daniel Willmann772415f2014-01-15 17:06:51 +0100835 vty_out(vty, " CS=%d%s%s", tbf->cs, VTY_NEWLINE, VTY_NEWLINE);
Daniel Willmannafa72f52014-01-15 17:06:19 +0100836}