Fix: Change T200 of LAPDm if SAPI 0 and SAPI 3 share bandwidth on SDCCH
[osmocom-bb.git] / src / host / layer23 / src / mobile / gsm48_rr.c
blob36488606c62b1dfc8409aeb14d72ca7e45ab4656
1 /*
2 * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
4 * All Rights Reserved
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.
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.
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.
22 /* Very short description of some of the procedures:
24 * A radio ressource request causes sendig a channel request on RACH.
25 * After receiving of an immediate assignment the link will be establised.
26 * After the link is established, the dedicated mode is entered and confirmed.
28 * A Paging request also triggers the channel request as above...
29 * After the link is established, the dedicated mode is entered and indicated.
31 * During dedicated mode, messages are transferred.
33 * When an assignment command or a handover command is received, the current
34 * link is released. After release, the new channel is activated and the
35 * link is established again. After link is establised, pending messages from
36 * radio ressource are sent.
38 * When the assignment or handover fails, the old channel is activate and the
39 * link is established again. Also pending messages are sent.
43 /* Testing delayed (immediate) assigment / handover
45 * When enabled, the starting time will be set by given frames in the future.
46 * If a starting time is given by the network, this time is ignored.
48 //#define TEST_STARTING_TIMER 140
50 /* Testing if frequency modification works correctly "after time".
52 * When enabled, the starting time will be set in the future.
53 * A wrong channel is defined "before time", so noise is received until
54 * starting time elapses.
55 * If a starting time is given by the network, this time is ignored.
56 * Also channel definitions "before time" are ignored.
58 * NOTE: TEST_STARTING_TIMER MUST be defined also.
60 //#define TEST_FREQUENCY_MOD
62 #include <stdint.h>
63 #include <errno.h>
64 #include <stdio.h>
65 #include <string.h>
66 #include <stdlib.h>
67 #include <arpa/inet.h>
69 #include <osmocom/core/msgb.h>
70 #include <osmocom/core/utils.h>
71 #include <osmocom/gsm/rsl.h>
72 #include <osmocom/gsm/gsm48.h>
73 #include <osmocom/core/bitvec.h>
75 #include <osmocom/bb/common/osmocom_data.h>
76 #include <osmocom/bb/common/l1l2_interface.h>
77 #include <osmocom/bb/common/l23_app.h>
78 #include <osmocom/bb/common/logging.h>
79 #include <osmocom/bb/common/networks.h>
80 #include <osmocom/bb/common/l1ctl.h>
81 #include <osmocom/bb/mobile/vty.h>
83 #include <l1ctl_proto.h>
85 static void start_rr_t_meas(struct gsm48_rrlayer *rr, int sec, int micro);
86 static void stop_rr_t_starting(struct gsm48_rrlayer *rr);
87 static void stop_rr_t3124(struct gsm48_rrlayer *rr);
88 static int gsm48_rcv_rsl(struct osmocom_ms *ms, struct msgb *msg);
89 static int gsm48_rr_dl_est(struct osmocom_ms *ms);
90 static int gsm48_rr_tx_meas_rep(struct osmocom_ms *ms);
91 static int gsm48_rr_set_mode(struct osmocom_ms *ms, uint8_t chan_nr,
92 uint8_t mode);
93 static int gsm48_rr_rel_cnf(struct osmocom_ms *ms, struct msgb *msg);
96 * support
99 #define MIN(a, b) ((a < b) ? a : b)
101 /* decode "Power Command" (10.5.2.28) and (10.5.2.28a) */
102 static int gsm48_decode_power_cmd_acc(struct gsm48_power_cmd *pc,
103 uint8_t *power_level, uint8_t *atc)
105 *power_level = pc->power_level;
106 if (atc) /* only in case of 10.5.2.28a */
107 *atc = pc->atc;
109 return 0;
112 /* 10.5.2.38 decode Starting time IE */
113 static int gsm48_decode_start_time(struct gsm48_rr_cd *cd,
114 struct gsm48_start_time *st)
116 cd->start = 1;
117 cd->start_tm.t1 = st->t1;
118 cd->start_tm.t2 = st->t2;
119 cd->start_tm.t3 = (st->t3_high << 3) | st->t3_low;
120 cd->start_tm.fn = gsm_gsmtime2fn(&cd->start_tm);
122 return 0;
125 /* decode "BA Range" (10.5.2.1a) */
126 static int gsm48_decode_ba_range(const uint8_t *ba, uint8_t ba_len,
127 uint32_t *range, uint8_t *ranges, int max_ranges)
129 /* ba = pointer to IE without IE type and length octets
130 * ba_len = number of octets
131 * range = pointer to store decoded range
132 * ranges = number of ranges decoded
133 * max_ranges = maximum number of decoded ranges that can be stored
135 uint16_t lower, higher;
136 int i, n, required_octets;
138 /* find out how much ba ranges will be decoded */
139 n = *ba++;
140 ba_len --;
141 required_octets = 5 * (n >> 1) + 3 * (n & 1);
142 if (required_octets > ba_len) {
143 LOGP(DRR, LOGL_NOTICE, "BA range IE too short: %d ranges "
144 "require %d octets, but only %d octets remain.\n",
145 n, required_octets, ba_len);
146 *ranges = 0;
147 return -EINVAL;
149 if (max_ranges > n)
150 LOGP(DRR, LOGL_NOTICE, "BA range %d exceed the maximum number "
151 "of ranges supported by this mobile (%d).\n",
152 n, max_ranges);
153 n = max_ranges;
155 /* decode ranges */
156 for (i = 0; i < n; i++) {
157 if (!(i & 1)) {
158 /* decode even range number */
159 lower = *ba++ << 2;
160 lower |= (*ba >> 6);
161 higher = (*ba++ & 0x3f) << 4;
162 higher |= *ba >> 4;
163 } else {
164 lower = (*ba++ & 0x0f) << 6;
165 lower |= *ba >> 2;
166 higher = (*ba++ & 0x03) << 8;
167 higher |= *ba++;
168 /* decode odd range number */
170 *range++ = (higher << 16) | lower;
172 *ranges = n;
174 return 0;
177 /* decode "Cell Description" (10.5.2.2) */
178 static int gsm48_decode_cell_desc(struct gsm48_cell_desc *cd, uint16_t *arfcn,
179 uint8_t *ncc, uint8_t *bcc)
181 *arfcn = (cd->arfcn_hi << 8) + cd->arfcn_lo;
182 *ncc = cd->ncc;
183 *bcc = cd->bcc;
185 return 0;
188 /* decode "Synchronization Indication" (10.5.2.39) */
189 static int gsm48_decode_sync_ind(struct gsm48_rrlayer *rr,
190 struct gsm48_sync_ind *si)
192 rr->hando_sync_ind = si->si;
193 rr->hando_rot = si->rot;
194 rr->hando_nci = si->nci;
196 return 0;
199 /* 3.1.4.3 set sequence number and increment */
200 static int gsm48_apply_v_sd(struct gsm48_rrlayer *rr, struct msgb *msg)
202 struct gsm48_hdr *gh = msgb_l3(msg);
203 uint8_t pdisc = gh->proto_discr & 0x0f;
204 uint8_t v_sd;
206 switch (pdisc) {
207 case GSM48_PDISC_MM:
208 case GSM48_PDISC_CC:
209 case GSM48_PDISC_NC_SS:
210 /* all thre pdiscs share the same V(SD) */
211 pdisc = GSM48_PDISC_MM;
212 // fall through
213 case GSM48_PDISC_GROUP_CC:
214 case GSM48_PDISC_BCAST_CC:
215 case GSM48_PDISC_PDSS1:
216 case GSM48_PDISC_PDSS2:
217 /* extract v_sd(pdisc) */
218 v_sd = (rr->v_sd >> pdisc) & 1;
220 /* replace bit 7 vy v_sd */
221 gh->msg_type &= 0xbf;
222 gh->msg_type |= (v_sd << 6);
224 /* increment V(SD) */
225 rr->v_sd ^= (1 << pdisc);
226 LOGP(DRR, LOGL_INFO, "Using and incrementing V(SD) = %d "
227 "(pdisc %x)\n", v_sd, pdisc);
228 break;
229 case GSM48_PDISC_RR:
230 case GSM48_PDISC_SMS:
231 /* no V(VSD) is required */
232 break;
233 default:
234 LOGP(DRR, LOGL_ERROR, "Error, V(SD) of pdisc %x not handled\n",
235 pdisc);
236 return -ENOTSUP;
239 return 0;
242 /* set channel mode if supported, or return error cause */
243 static uint8_t gsm48_rr_check_mode(struct osmocom_ms *ms, uint8_t chan_nr,
244 uint8_t mode)
246 struct gsm_settings *set = &ms->settings;
247 uint8_t ch_type, ch_subch, ch_ts;
249 /* only complain if we use TCH/F or TCH/H */
250 rsl_dec_chan_nr(chan_nr, &ch_type, &ch_subch, &ch_ts);
251 if (ch_type != RSL_CHAN_Bm_ACCHs
252 && ch_type != RSL_CHAN_Lm_ACCHs)
253 return 0;
255 switch (mode) {
256 case GSM48_CMODE_SIGN:
257 LOGP(DRR, LOGL_INFO, "Mode: signalling\n");
258 break;
259 case GSM48_CMODE_SPEECH_V1:
260 if (ch_type == RSL_CHAN_Bm_ACCHs) {
261 if (!set->full_v1) {
262 LOGP(DRR, LOGL_NOTICE, "Not supporting "
263 "full-rate speech V1\n");
264 return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
266 LOGP(DRR, LOGL_INFO, "Mode: full-rate speech V1\n");
267 } else {
268 if (!set->half_v1) {
269 LOGP(DRR, LOGL_NOTICE, "Not supporting "
270 "half-rate speech V1\n");
271 return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
273 LOGP(DRR, LOGL_INFO, "Mode: half-rate speech V1\n");
275 break;
276 case GSM48_CMODE_SPEECH_EFR:
277 if (ch_type == RSL_CHAN_Bm_ACCHs) {
278 if (!set->full_v2) {
279 LOGP(DRR, LOGL_NOTICE, "Not supporting "
280 "full-rate speech V2\n");
281 return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
283 LOGP(DRR, LOGL_INFO, "Mode: full-rate speech V2\n");
284 } else {
285 LOGP(DRR, LOGL_NOTICE, "Not supporting "
286 "half-rate speech V2\n");
287 return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
289 break;
290 case GSM48_CMODE_SPEECH_AMR:
291 if (ch_type == RSL_CHAN_Bm_ACCHs) {
292 if (!set->full_v3) {
293 LOGP(DRR, LOGL_NOTICE, "Not supporting "
294 "full-rate speech V3\n");
295 return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
297 LOGP(DRR, LOGL_INFO, "Mode: full-rate speech V3\n");
298 } else {
299 if (!set->half_v3) {
300 LOGP(DRR, LOGL_NOTICE, "Not supporting "
301 "half-rate speech V3\n");
302 return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
304 LOGP(DRR, LOGL_INFO, "Mode: half-rate speech V3\n");
306 break;
307 default:
308 LOGP(DRR, LOGL_ERROR, "Mode 0x%02x not supported!\n", mode);
309 return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
312 return 0;
315 /* apply new "alter_delay" in dedicated mode */
316 int gsm48_rr_alter_delay(struct osmocom_ms *ms)
318 struct gsm48_rrlayer *rr = &ms->rrlayer;
319 struct gsm_settings *set = &rr->ms->settings;
321 if (rr->state != GSM48_RR_ST_DEDICATED)
322 return -EINVAL;
323 l1ctl_tx_param_req(ms, rr->cd_now.ind_ta - set->alter_delay,
324 (set->alter_tx_power) ? set->alter_tx_power_value
325 : rr->cd_now.ind_tx_power);
327 return 0;
331 * state transition
334 const char *gsm48_rr_state_names[] = {
335 "idle",
336 "connection pending",
337 "dedicated",
338 "release pending",
341 static void new_rr_state(struct gsm48_rrlayer *rr, int state)
343 if (state < 0 || state >=
344 (sizeof(gsm48_rr_state_names) / sizeof(char *)))
345 return;
347 /* must check against equal state */
348 if (rr->state == state) {
349 LOGP(DRR, LOGL_INFO, "equal state ? %s\n",
350 gsm48_rr_state_names[rr->state]);
351 return;
354 LOGP(DRR, LOGL_INFO, "new state %s -> %s\n",
355 gsm48_rr_state_names[rr->state], gsm48_rr_state_names[state]);
357 /* abort handover, in case of release of dedicated mode */
358 if (rr->state == GSM48_RR_ST_DEDICATED) {
359 /* disable handover / assign state */
360 rr->modify_state = GSM48_RR_MOD_NONE;
361 /* stop start_time_timer */
362 stop_rr_t_starting(rr);
363 /* stop handover timer */
364 stop_rr_t3124(rr);
367 rr->state = state;
369 if (state == GSM48_RR_ST_IDLE) {
370 struct msgb *msg, *nmsg;
371 struct gsm322_msg *em;
373 /* release dedicated mode, if any */
374 l1ctl_tx_dm_rel_req(rr->ms);
375 rr->ms->meas.rl_fail = 0;
376 rr->dm_est = 0;
377 l1ctl_tx_reset_req(rr->ms, L1CTL_RES_T_FULL);
378 /* free establish message, if any */
379 rr->rr_est_req = 0;
380 if (rr->rr_est_msg) {
381 msgb_free(rr->rr_est_msg);
382 rr->rr_est_msg = NULL;
384 /* free all pending messages */
385 while((msg = msgb_dequeue(&rr->downqueue)))
386 msgb_free(msg);
387 /* clear all descriptions of last channel */
388 memset(&rr->cd_now, 0, sizeof(rr->cd_now));
389 /* reset ciphering */
390 rr->cipher_on = 0;
391 /* reset audio mode */
392 /* tell cell selection process to return to idle mode
393 * NOTE: this must be sent unbuffered, because it will
394 * leave camping state, so it locks against subsequent
395 * establishment of dedicated channel, before the
396 * cell selection process returned to camping state
397 * again. (after cell reselection)
399 nmsg = gsm322_msgb_alloc(GSM322_EVENT_RET_IDLE);
400 if (!nmsg)
401 return;
402 /* return to same cell after LOC.UPD. */
403 if (rr->est_cause == RR_EST_CAUSE_LOC_UPD) {
404 em = (struct gsm322_msg *) nmsg->data;
405 em->same_cell = 1;
407 gsm322_c_event(rr->ms, nmsg);
408 msgb_free(nmsg);
409 /* reset any BA range */
410 rr->ba_ranges = 0;
414 const char *gsm48_sapi3_state_names[] = {
415 "idle",
416 "wait establishment",
417 "established",
418 "wait release",
421 static void new_sapi3_state(struct gsm48_rrlayer *rr, int state)
423 if (state < 0 || state >=
424 (sizeof(gsm48_sapi3_state_names) / sizeof(char *)))
425 return;
427 LOGP(DRR, LOGL_INFO, "new SAPI 3 link state %s -> %s\n",
428 gsm48_sapi3_state_names[rr->sapi3_state],
429 gsm48_sapi3_state_names[state]);
431 rr->sapi3_state = state;
435 * messages
438 /* names of RR-SAP */
439 static const struct value_string gsm48_rr_msg_names[] = {
440 { GSM48_RR_EST_REQ, "RR_EST_REQ" },
441 { GSM48_RR_EST_IND, "RR_EST_IND" },
442 { GSM48_RR_EST_CNF, "RR_EST_CNF" },
443 { GSM48_RR_REL_IND, "RR_REL_IND" },
444 { GSM48_RR_SYNC_IND, "RR_SYNC_IND" },
445 { GSM48_RR_DATA_REQ, "RR_DATA_REQ" },
446 { GSM48_RR_DATA_IND, "RR_DATA_IND" },
447 { GSM48_RR_UNIT_DATA_IND, "RR_UNIT_DATA_IND" },
448 { GSM48_RR_ABORT_REQ, "RR_ABORT_REQ" },
449 { GSM48_RR_ABORT_IND, "RR_ABORT_IND" },
450 { GSM48_RR_ACT_REQ, "RR_ACT_REQ" },
451 { 0, NULL }
454 const char *get_rr_name(int value)
456 return get_value_string(gsm48_rr_msg_names, value);
459 /* allocate GSM 04.08 layer 3 message */
460 struct msgb *gsm48_l3_msgb_alloc(void)
462 struct msgb *msg;
464 msg = msgb_alloc_headroom(L3_ALLOC_SIZE+L3_ALLOC_HEADROOM,
465 L3_ALLOC_HEADROOM, "GSM 04.08 L3");
466 if (!msg)
467 return NULL;
468 msg->l3h = msg->data;
470 return msg;
473 /* allocate GSM 04.06 layer 2 RSL message */
474 struct msgb *gsm48_rsl_msgb_alloc(void)
476 struct msgb *msg;
478 msg = msgb_alloc_headroom(RSL_ALLOC_SIZE+RSL_ALLOC_HEADROOM,
479 RSL_ALLOC_HEADROOM, "GSM 04.06 RSL");
480 if (!msg)
481 return NULL;
482 msg->l2h = msg->data;
484 return msg;
487 /* allocate GSM 04.08 message (RR-SAP) */
488 struct msgb *gsm48_rr_msgb_alloc(int msg_type)
490 struct msgb *msg;
491 struct gsm48_rr_hdr *rrh;
493 msg = msgb_alloc_headroom(RR_ALLOC_SIZE+RR_ALLOC_HEADROOM,
494 RR_ALLOC_HEADROOM, "GSM 04.08 RR");
495 if (!msg)
496 return NULL;
498 rrh = (struct gsm48_rr_hdr *) msgb_put(msg, sizeof(*rrh));
499 rrh->msg_type = msg_type;
501 return msg;
504 /* queue message (RR-SAP) */
505 int gsm48_rr_upmsg(struct osmocom_ms *ms, struct msgb *msg)
507 struct gsm48_mmlayer *mm = &ms->mmlayer;
509 msgb_enqueue(&mm->rr_upqueue, msg);
511 return 0;
514 /* push rsl header and send (RSL-SAP) */
515 static int gsm48_send_rsl(struct osmocom_ms *ms, uint8_t msg_type,
516 struct msgb *msg, uint8_t link_id)
518 struct gsm48_rrlayer *rr = &ms->rrlayer;
520 if (!msg->l3h) {
521 LOGP(DRR, LOGL_ERROR, "FIX l3h\n");
522 return -EINVAL;
524 rsl_rll_push_l3(msg, msg_type, rr->cd_now.chan_nr, link_id, 1);
526 return lapdm_rslms_recvmsg(msg, &ms->lapdm_channel);
529 /* push rsl header without L3 info and send (RSL-SAP) */
530 static int gsm48_send_rsl_nol3(struct osmocom_ms *ms, uint8_t msg_type,
531 struct msgb *msg, uint8_t link_id)
533 struct gsm48_rrlayer *rr = &ms->rrlayer;
535 rsl_rll_push_hdr(msg, msg_type, rr->cd_now.chan_nr,
536 link_id, 1);
538 return lapdm_rslms_recvmsg(msg, &ms->lapdm_channel);
541 /* enqueue messages (RSL-SAP) */
542 static int rcv_rsl(struct msgb *msg, struct lapdm_entity *le, void *l3ctx)
544 struct osmocom_ms *ms = l3ctx;
545 struct gsm48_rrlayer *rr = &ms->rrlayer;
547 msgb_enqueue(&rr->rsl_upqueue, msg);
549 return 0;
552 /* dequeue messages (RSL-SAP) */
553 int gsm48_rsl_dequeue(struct osmocom_ms *ms)
555 struct gsm48_rrlayer *rr = &ms->rrlayer;
556 struct msgb *msg;
557 int work = 0;
559 while ((msg = msgb_dequeue(&rr->rsl_upqueue))) {
560 /* msg is freed there */
561 gsm48_rcv_rsl(ms, msg);
562 work = 1; /* work done */
565 return work;
568 int gsm48_rr_start_monitor(struct osmocom_ms *ms)
570 ms->rrlayer.monitor = 1;
572 return 0;
575 int gsm48_rr_stop_monitor(struct osmocom_ms *ms)
577 ms->rrlayer.monitor = 0;
579 return 0;
582 /* release L3 link in both directions in case of main link release */
583 static int gsm48_release_sapi3_link(struct osmocom_ms *ms)
585 struct gsm48_rrlayer *rr = &ms->rrlayer;
586 struct gsm48_rr_hdr *nrrh;
587 struct msgb *nmsg;
588 uint8_t *mode;
590 if (rr->sapi3_state == GSM48_RR_SAPI3ST_IDLE)
591 return 0;
593 LOGP(DRR, LOGL_INFO, "Main signallin link is down, so release SAPI 3 "
594 "link locally.\n");
596 new_sapi3_state(rr, GSM48_RR_SAPI3ST_IDLE);
598 /* disconnect the SAPI 3 signalling link */
599 nmsg = gsm48_l3_msgb_alloc();
600 if (!nmsg)
601 return -ENOMEM;
602 mode = msgb_put(nmsg, 2);
603 mode[0] = RSL_IE_RELEASE_MODE;
604 mode[1] = 1; /* local release */
605 gsm48_send_rsl_nol3(ms, RSL_MT_REL_REQ, nmsg, rr->sapi3_link_id);
607 /* send inication to upper layer */
608 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
609 if (!nmsg)
610 return -ENOMEM;
611 nrrh = (struct gsm48_rr_hdr *)nmsg->data;
612 nrrh->cause = RR_REL_CAUSE_NORMAL;
613 nrrh->sapi = rr->sapi3_link_id & 7;
614 gsm48_rr_upmsg(ms, nmsg);
616 return 0;
620 * timers handling
623 /* special timer to monitor measurements */
624 static void timeout_rr_meas(void *arg)
626 struct gsm48_rrlayer *rr = arg;
627 struct gsm322_cellsel *cs = &rr->ms->cellsel;
628 struct rx_meas_stat *meas = &rr->ms->meas;
629 struct gsm_settings *set = &rr->ms->settings;
630 int rxlev, berr, snr;
631 uint8_t ch_type, ch_subch, ch_ts;
632 char text[256];
634 /* don't monitor if no cell is selcted or if we scan neighbour cells */
635 if (!cs->selected || cs->neighbour) {
636 sprintf(text, "MON: not camping on serving cell");
637 goto restart;
638 } else if (!meas->frames) {
639 sprintf(text, "MON: no cell info");
640 } else {
641 rxlev = (meas->rxlev + meas->frames / 2) / meas->frames;
642 berr = (meas->berr + meas->frames / 2) / meas->frames;
643 snr = (meas->snr + meas->frames / 2) / meas->frames;
644 sprintf(text, "MON: f=%d lev=%s snr=%2d ber=%3d "
645 "LAI=%s %s %04x ID=%04x", cs->sel_arfcn,
646 gsm_print_rxlev(rxlev), berr, snr,
647 gsm_print_mcc(cs->sel_mcc),
648 gsm_print_mnc(cs->sel_mnc), cs->sel_lac, cs->sel_id);
649 if (rr->state == GSM48_RR_ST_DEDICATED) {
650 rsl_dec_chan_nr(rr->cd_now.chan_nr, &ch_type,
651 &ch_subch, &ch_ts);
652 sprintf(text + strlen(text), " TA=%d pwr=%d TS=%d",
653 rr->cd_now.ind_ta - set->alter_delay,
654 (set->alter_tx_power) ? set->alter_tx_power_value
655 : rr->cd_now.ind_tx_power, ch_ts);
656 if (ch_type == RSL_CHAN_SDCCH8_ACCH
657 || ch_type == RSL_CHAN_SDCCH4_ACCH)
658 sprintf(text + strlen(text), "/%d", ch_subch);
659 } else
660 gsm322_meas(rr->ms, rxlev);
662 LOGP(DRR, LOGL_INFO, "%s\n", text);
663 if (rr->monitor)
664 vty_notify(rr->ms, "%s\n", text);
666 if (rr->dm_est)
667 gsm48_rr_tx_meas_rep(rr->ms);
669 restart:
670 meas->frames = meas->snr = meas->berr = meas->rxlev = 0;
671 start_rr_t_meas(rr, 1, 0);
674 /* special timer to assign / handover when starting time is reached */
675 static void timeout_rr_t_starting(void *arg)
677 struct gsm48_rrlayer *rr = arg;
678 struct msgb *nmsg;
680 LOGP(DRR, LOGL_INFO, "starting timer has fired\n");
682 /* open channel when starting timer of IMM.ASS has fired */
683 if (rr->modify_state == GSM48_RR_MOD_IMM_ASS) {
684 rr->modify_state = GSM48_RR_MOD_NONE;
685 gsm48_rr_dl_est(rr->ms);
686 return;
689 /* start suspension of current link */
690 LOGP(DRR, LOGL_INFO, "request suspension of data link\n");
691 nmsg = gsm48_l3_msgb_alloc();
692 if (!nmsg)
693 return;
694 gsm48_send_rsl(rr->ms, RSL_MT_SUSP_REQ, nmsg, 0);
696 /* release SAPI 3 link, if exits
697 * FIXME: suspend and resume afterward */
698 gsm48_release_sapi3_link(rr->ms);
701 /* special timer to ensure that UA is sent before disconnecting channel */
702 static void timeout_rr_t_rel_wait(void *arg)
704 struct gsm48_rrlayer *rr = arg;
706 LOGP(DRR, LOGL_INFO, "L2 release timer has fired, done waiting\n");
708 /* return to idle now */
709 new_rr_state(rr, GSM48_RR_ST_IDLE);
712 /* 3.4.13.1.1: Timeout of T3110 */
713 static void timeout_rr_t3110(void *arg)
715 struct gsm48_rrlayer *rr = arg;
716 struct osmocom_ms *ms = rr->ms;
717 struct msgb *nmsg;
718 uint8_t *mode;
720 LOGP(DRR, LOGL_INFO, "timer T3110 has fired, release locally\n");
722 new_rr_state(rr, GSM48_RR_ST_REL_PEND);
724 /* disconnect the main signalling link */
725 nmsg = gsm48_l3_msgb_alloc();
726 if (!nmsg)
727 return;
728 mode = msgb_put(nmsg, 2);
729 mode[0] = RSL_IE_RELEASE_MODE;
730 mode[1] = 1; /* local release */
731 gsm48_send_rsl_nol3(ms, RSL_MT_REL_REQ, nmsg, 0);
733 /* release SAPI 3 link, if exits */
734 gsm48_release_sapi3_link(ms);
736 return;
739 static void timeout_rr_t3122(void *arg)
741 LOGP(DRR, LOGL_INFO, "timer T3122 has fired\n");
744 static void timeout_rr_t3124(void *arg)
746 LOGP(DRR, LOGL_INFO, "timer T3124 has fired\n");
749 static void timeout_rr_t3126(void *arg)
751 struct gsm48_rrlayer *rr = arg;
752 struct osmocom_ms *ms = rr->ms;
754 LOGP(DRR, LOGL_INFO, "timer T3126 has fired\n");
755 if (rr->rr_est_req) {
756 struct msgb *msg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
757 struct gsm48_rr_hdr *rrh;
759 LOGP(DSUM, LOGL_INFO, "Requesting channel failed\n");
760 if (!msg)
761 return;
762 rrh = (struct gsm48_rr_hdr *)msg->data;
763 rrh->cause = RR_REL_CAUSE_RA_FAILURE;
764 gsm48_rr_upmsg(ms, msg);
767 new_rr_state(rr, GSM48_RR_ST_IDLE);
770 static void start_rr_t_meas(struct gsm48_rrlayer *rr, int sec, int micro)
772 rr->t_meas.cb = timeout_rr_meas;
773 rr->t_meas.data = rr;
774 osmo_timer_schedule(&rr->t_meas, sec, micro);
777 static void start_rr_t_rel_wait(struct gsm48_rrlayer *rr, int sec, int micro)
779 LOGP(DRR, LOGL_INFO, "starting T_rel_wait with %d.%03d seconds\n", sec,
780 micro / 1000);
781 rr->t_rel_wait.cb = timeout_rr_t_rel_wait;
782 rr->t_rel_wait.data = rr;
783 osmo_timer_schedule(&rr->t_rel_wait, sec, micro);
786 static void start_rr_t_starting(struct gsm48_rrlayer *rr, int sec, int micro)
788 LOGP(DRR, LOGL_INFO, "starting T_starting with %d.%03d seconds\n", sec,
789 micro / 1000);
790 rr->t_starting.cb = timeout_rr_t_starting;
791 rr->t_starting.data = rr;
792 osmo_timer_schedule(&rr->t_starting, sec, micro);
795 static void start_rr_t3110(struct gsm48_rrlayer *rr, int sec, int micro)
797 LOGP(DRR, LOGL_INFO, "starting T3110 with %d.%03d seconds\n", sec,
798 micro / 1000);
799 rr->t3110.cb = timeout_rr_t3110;
800 rr->t3110.data = rr;
801 osmo_timer_schedule(&rr->t3110, sec, micro);
804 static void start_rr_t3122(struct gsm48_rrlayer *rr, int sec, int micro)
806 LOGP(DRR, LOGL_INFO, "starting T3122 with %d.%03d seconds\n", sec,
807 micro / 1000);
808 rr->t3122.cb = timeout_rr_t3122;
809 rr->t3122.data = rr;
810 osmo_timer_schedule(&rr->t3122, sec, micro);
813 static void start_rr_t3124(struct gsm48_rrlayer *rr, int sec, int micro)
815 LOGP(DRR, LOGL_INFO, "starting T3124 with %d.%03d seconds\n", sec,
816 micro / 1000);
817 rr->t3124.cb = timeout_rr_t3124;
818 rr->t3124.data = rr;
819 osmo_timer_schedule(&rr->t3124, sec, micro);
822 static void start_rr_t3126(struct gsm48_rrlayer *rr, int sec, int micro)
824 LOGP(DRR, LOGL_INFO, "starting T3126 with %d.%03d seconds\n", sec,
825 micro / 1000);
826 rr->t3126.cb = timeout_rr_t3126;
827 rr->t3126.data = rr;
828 osmo_timer_schedule(&rr->t3126, sec, micro);
831 static void stop_rr_t_meas(struct gsm48_rrlayer *rr)
833 if (osmo_timer_pending(&rr->t_meas)) {
834 LOGP(DRR, LOGL_INFO, "stopping pending timer T_meas\n");
835 osmo_timer_del(&rr->t_meas);
839 static void stop_rr_t_starting(struct gsm48_rrlayer *rr)
841 if (osmo_timer_pending(&rr->t_starting)) {
842 LOGP(DRR, LOGL_INFO, "stopping pending timer T_starting\n");
843 osmo_timer_del(&rr->t_starting);
847 static void stop_rr_t_rel_wait(struct gsm48_rrlayer *rr)
849 if (osmo_timer_pending(&rr->t_rel_wait)) {
850 LOGP(DRR, LOGL_INFO, "stopping pending timer T_rel_wait\n");
851 osmo_timer_del(&rr->t_rel_wait);
855 static void stop_rr_t3110(struct gsm48_rrlayer *rr)
857 if (osmo_timer_pending(&rr->t3110)) {
858 LOGP(DRR, LOGL_INFO, "stopping pending timer T3110\n");
859 osmo_timer_del(&rr->t3110);
863 static void stop_rr_t3122(struct gsm48_rrlayer *rr)
865 if (osmo_timer_pending(&rr->t3122)) {
866 LOGP(DRR, LOGL_INFO, "stopping pending timer T3122\n");
867 osmo_timer_del(&rr->t3122);
871 static void stop_rr_t3124(struct gsm48_rrlayer *rr)
873 if (osmo_timer_pending(&rr->t3124)) {
874 LOGP(DRR, LOGL_INFO, "stopping pending timer T3124\n");
875 osmo_timer_del(&rr->t3124);
879 static void stop_rr_t3126(struct gsm48_rrlayer *rr)
881 if (osmo_timer_pending(&rr->t3126)) {
882 LOGP(DRR, LOGL_INFO, "stopping pending timer T3126\n");
883 osmo_timer_del(&rr->t3126);
888 * status
891 /* send rr status request */
892 static int gsm48_rr_tx_rr_status(struct osmocom_ms *ms, uint8_t cause)
894 struct msgb *nmsg;
895 struct gsm48_hdr *gh;
896 struct gsm48_rr_status *st;
898 LOGP(DRR, LOGL_INFO, "RR STATUS (cause #%d)\n", cause);
900 nmsg = gsm48_l3_msgb_alloc();
901 if (!nmsg)
902 return -ENOMEM;
903 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
904 st = (struct gsm48_rr_status *) msgb_put(nmsg, sizeof(*st));
906 gh->proto_discr = GSM48_PDISC_RR;
907 gh->msg_type = GSM48_MT_RR_CIPH_M_COMPL;
909 /* rr cause */
910 st->rr_cause = cause;
912 return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg, 0);
916 * ciphering
919 /* send chiperhing mode complete */
920 static int gsm48_rr_tx_cip_mode_cpl(struct osmocom_ms *ms, uint8_t cr)
922 struct gsm_settings *set = &ms->settings;
923 struct msgb *nmsg;
924 struct gsm48_hdr *gh;
925 struct gsm48_rr_hdr *nrrh;
926 uint8_t buf[11], *tlv;
928 LOGP(DRR, LOGL_INFO, "CIPHERING MODE COMPLETE (cr %d)\n", cr);
930 nmsg = gsm48_l3_msgb_alloc();
931 if (!nmsg)
932 return -ENOMEM;
933 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
935 gh->proto_discr = GSM48_PDISC_RR;
936 gh->msg_type = GSM48_MT_RR_CIPH_M_COMPL;
938 /* MI */
939 if (cr) {
940 gsm48_generate_mid_from_imsi(buf, set->imeisv);
941 /* alter MI type */
942 buf[2] = (buf[2] & ~GSM_MI_TYPE_MASK) | GSM_MI_TYPE_IMEISV;
943 tlv = msgb_put(nmsg, 2 + buf[1]);
944 memcpy(tlv, buf, 2 + buf[1]);
947 gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg, 0);
949 /* send RR_SYNC_IND(ciphering) */
950 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_SYNC_IND);
951 if (!nmsg)
952 return -ENOMEM;
953 nrrh = (struct gsm48_rr_hdr *)nmsg->data;
954 nrrh->cause = RR_SYNC_CAUSE_CIPHERING;
955 return gsm48_rr_upmsg(ms, nmsg);
958 /* receive ciphering mode command */
959 static int gsm48_rr_rx_cip_mode_cmd(struct osmocom_ms *ms, struct msgb *msg)
961 struct gsm48_rrlayer *rr = &ms->rrlayer;
962 struct gsm_subscriber *subscr = &ms->subscr;
963 struct gsm_settings *set = &ms->settings;
964 struct gsm48_hdr *gh = msgb_l3(msg);
965 struct gsm48_cip_mode_cmd *cm = (struct gsm48_cip_mode_cmd *)gh->data;
966 int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*cm);
967 uint8_t sc, alg_id, cr;
969 if (payload_len < 0) {
970 LOGP(DRR, LOGL_NOTICE, "Short read of CIPHERING MODE COMMAND "
971 "message.\n");
972 return gsm48_rr_tx_rr_status(ms,
973 GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
976 /* cipher mode setting */
977 sc = cm->sc;
978 alg_id = cm->alg_id;
979 /* cipher mode response */
980 cr = cm->cr;
982 if (!sc)
983 LOGP(DRR, LOGL_INFO, "CIPHERING MODE COMMAND (sc=%u, cr=%u)\n",
984 sc, cr);
985 else
986 LOGP(DRR, LOGL_INFO, "CIPHERING MODE COMMAND (sc=%u, "
987 "algo=A5/%d cr=%u)\n", sc, alg_id + 1, cr);
989 /* 3.4.7.2 */
990 if (rr->cipher_on && sc) {
991 LOGP(DRR, LOGL_NOTICE, "chiphering already applied\n");
992 return gsm48_rr_tx_rr_status(ms,
993 GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
996 /* check if we actually support this cipher */
997 if (sc && ((alg_id == GSM_CIPHER_A5_1 && !set->a5_1)
998 || (alg_id == GSM_CIPHER_A5_2 && !set->a5_2)
999 || (alg_id == GSM_CIPHER_A5_3 && !set->a5_3)
1000 || (alg_id == GSM_CIPHER_A5_4 && !set->a5_4)
1001 || (alg_id == GSM_CIPHER_A5_5 && !set->a5_5)
1002 || (alg_id == GSM_CIPHER_A5_6 && !set->a5_6)
1003 || (alg_id == GSM_CIPHER_A5_7 && !set->a5_7))) {
1004 LOGP(DRR, LOGL_NOTICE, "algo not supported\n");
1005 return gsm48_rr_tx_rr_status(ms,
1006 GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
1009 /* check if we have no key */
1010 if (sc && subscr->key_seq == 7) {
1011 LOGP(DRR, LOGL_NOTICE, "no key available\n");
1012 return gsm48_rr_tx_rr_status(ms,
1013 GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
1016 /* change to ciphering */
1017 rr->cipher_on = sc;
1018 rr->cipher_type = alg_id;
1019 if (rr->cipher_on)
1020 l1ctl_tx_crypto_req(ms, rr->cipher_type + 1, subscr->key, 8);
1021 else
1022 l1ctl_tx_crypto_req(ms, 0, NULL, 0);
1024 /* response (using the new mode) */
1025 return gsm48_rr_tx_cip_mode_cpl(ms, cr);
1029 * classmark
1032 /* Encode "Classmark 3" (10.5.1.7) */
1033 static int gsm48_rr_enc_cm3(struct osmocom_ms *ms, uint8_t *buf, uint8_t *len)
1035 struct gsm_support *sup = &ms->support;
1036 struct gsm_settings *set = &ms->settings;
1037 struct bitvec bv;
1039 memset(&bv, 0, sizeof(bv));
1040 bv.data = buf;
1041 bv.data_len = 12;
1043 /* spare bit */
1044 bitvec_set_bit(&bv, 0);
1045 /* band 3 supported */
1046 if (set->dcs)
1047 bitvec_set_bit(&bv, ONE);
1048 else
1049 bitvec_set_bit(&bv, ZERO);
1050 /* band 2 supported */
1051 if (set->e_gsm || set->r_gsm)
1052 bitvec_set_bit(&bv, ONE);
1053 else
1054 bitvec_set_bit(&bv, ZERO);
1055 /* band 1 supported */
1056 if (set->p_gsm && !(set->e_gsm || set->r_gsm))
1057 bitvec_set_bit(&bv, ONE);
1058 else
1059 bitvec_set_bit(&bv, ZERO);
1060 /* a5 bits */
1061 if (set->a5_7)
1062 bitvec_set_bit(&bv, ONE);
1063 else
1064 bitvec_set_bit(&bv, ZERO);
1065 if (set->a5_6)
1066 bitvec_set_bit(&bv, ONE);
1067 else
1068 bitvec_set_bit(&bv, ZERO);
1069 if (set->a5_5)
1070 bitvec_set_bit(&bv, ONE);
1071 else
1072 bitvec_set_bit(&bv, ZERO);
1073 if (set->a5_4)
1074 bitvec_set_bit(&bv, ONE);
1075 else
1076 bitvec_set_bit(&bv, ZERO);
1077 /* radio capability */
1078 if (!set->dcs && !set->p_gsm && !(set->e_gsm || set->r_gsm)) {
1079 /* Fig. 10.5.7 / TS 24.0008: none of dcs, p, e, r */
1080 } else
1081 if (set->dcs && !set->p_gsm && !(set->e_gsm || set->r_gsm)) {
1082 /* dcs only */
1083 bitvec_set_uint(&bv, 0, 4);
1084 bitvec_set_uint(&bv, set->class_dcs, 4);
1085 } else
1086 if (set->dcs && (set->p_gsm || (set->e_gsm || set->r_gsm))) {
1087 /* dcs */
1088 bitvec_set_uint(&bv, set->class_dcs, 4);
1089 /* low band */
1090 bitvec_set_uint(&bv, set->class_900, 4);
1091 } else {
1092 /* low band only */
1093 bitvec_set_uint(&bv, 0, 4);
1094 bitvec_set_uint(&bv, set->class_900, 4);
1096 /* r support */
1097 if (set->r_gsm) {
1098 bitvec_set_bit(&bv, ONE);
1099 bitvec_set_uint(&bv, set->class_900, 3);
1100 } else {
1101 bitvec_set_bit(&bv, ZERO);
1103 /* multi slot support */
1104 if (sup->ms_sup) {
1105 bitvec_set_bit(&bv, ONE);
1106 bitvec_set_uint(&bv, sup->ms_sup, 5);
1107 } else {
1108 bitvec_set_bit(&bv, ZERO);
1110 /* ucs2 treatment */
1111 if (sup->ucs2_treat) {
1112 bitvec_set_bit(&bv, ONE);
1113 } else {
1114 bitvec_set_bit(&bv, ZERO);
1116 /* support extended measurements */
1117 if (sup->ext_meas) {
1118 bitvec_set_bit(&bv, ONE);
1119 } else {
1120 bitvec_set_bit(&bv, ZERO);
1122 /* support measurement capability */
1123 if (sup->meas_cap) {
1124 bitvec_set_bit(&bv, ONE);
1125 bitvec_set_uint(&bv, sup->sms_val, 4);
1126 bitvec_set_uint(&bv, sup->sm_val, 4);
1127 } else {
1128 bitvec_set_bit(&bv, ZERO);
1130 /* positioning method capability */
1131 if (sup->loc_serv) {
1132 bitvec_set_bit(&bv, ONE);
1133 bitvec_set_bit(&bv, sup->e_otd_ass == 1);
1134 bitvec_set_bit(&bv, sup->e_otd_based == 1);
1135 bitvec_set_bit(&bv, sup->gps_ass == 1);
1136 bitvec_set_bit(&bv, sup->gps_based == 1);
1137 bitvec_set_bit(&bv, sup->gps_conv == 1);
1138 } else {
1139 bitvec_set_bit(&bv, ZERO);
1141 /* The following bits are described in TS 24.008 */
1142 /* EDGE multi slot support */
1143 if (set->edge_ms_sup) {
1144 bitvec_set_bit(&bv, ONE);
1145 bitvec_set_uint(&bv, set->edge_ms_sup, 5);
1146 } else {
1147 bitvec_set_bit(&bv, ZERO);
1149 /* EDGE support */
1150 if (set->edge_psk_sup) {
1151 bitvec_set_bit(&bv, ONE);
1152 bitvec_set_bit(&bv, set->edge_psk_uplink == 1);
1153 if (set->p_gsm || (set->e_gsm || set->r_gsm)) {
1154 bitvec_set_bit(&bv, ONE);
1155 bitvec_set_uint(&bv, set->class_900_edge, 2);
1156 } else {
1157 bitvec_set_bit(&bv, ZERO);
1159 if (set->dcs || set->pcs) {
1160 bitvec_set_bit(&bv, ONE);
1161 bitvec_set_uint(&bv, set->class_dcs_pcs_edge, 2);
1162 } else {
1163 bitvec_set_bit(&bv, ZERO);
1165 } else {
1166 bitvec_set_bit(&bv, ZERO);
1168 /* GSM 400 Bands */
1169 if (set->gsm_480 || set->gsm_450) {
1170 bitvec_set_bit(&bv, ONE);
1171 bitvec_set_bit(&bv, set->gsm_480 == 1);
1172 bitvec_set_bit(&bv, set->gsm_450 == 1);
1173 bitvec_set_uint(&bv, set->class_400, 4);
1174 } else {
1175 bitvec_set_bit(&bv, ZERO);
1177 /* GSM 850 Band */
1178 if (set->gsm_850) {
1179 bitvec_set_bit(&bv, ONE);
1180 bitvec_set_uint(&bv, set->class_850, 4);
1181 } else {
1182 bitvec_set_bit(&bv, ZERO);
1184 /* PCS Band */
1185 if (set->pcs) {
1186 bitvec_set_bit(&bv, ONE);
1187 bitvec_set_uint(&bv, set->class_pcs, 4);
1188 } else {
1189 bitvec_set_bit(&bv, ZERO);
1191 /* RAT Capability */
1192 bitvec_set_bit(&bv, set->umts_fdd == 1);
1193 bitvec_set_bit(&bv, set->umts_tdd == 1);
1194 bitvec_set_bit(&bv, set->cdma_2000 == 1);
1195 /* DTM */
1196 if (set->dtm) {
1197 bitvec_set_bit(&bv, ONE);
1198 bitvec_set_uint(&bv, set->class_dtm, 2);
1199 bitvec_set_bit(&bv, set->dtm_mac == 1);
1200 bitvec_set_bit(&bv, set->dtm_egprs == 1);
1201 } else {
1202 bitvec_set_bit(&bv, ZERO);
1204 /* info: The max number of bits are about 80. */
1206 /* partitial bytes will be completed */
1207 *len = (bv.cur_bit + 7) >> 3;
1208 bitvec_spare_padding(&bv, (*len * 8) - 1);
1210 return 0;
1213 /* encode classmark 2 */
1214 int gsm48_rr_enc_cm2(struct osmocom_ms *ms, struct gsm48_classmark2 *cm,
1215 uint16_t arfcn)
1217 struct gsm_support *sup = &ms->support;
1218 struct gsm_settings *set = &ms->settings;
1220 cm->pwr_lev = gsm48_current_pwr_lev(set, arfcn);
1221 cm->a5_1 = !set->a5_1;
1222 cm->es_ind = sup->es_ind;
1223 cm->rev_lev = sup->rev_lev;
1224 cm->fc = (set->r_gsm || set->e_gsm);
1225 cm->vgcs = sup->vgcs;
1226 cm->vbs = sup->vbs;
1227 cm->sm_cap = set->sms_ptp;
1228 cm->ss_scr = sup->ss_ind;
1229 cm->ps_cap = sup->ps_cap;
1230 cm->a5_2 = set->a5_2;
1231 cm->a5_3 = set->a5_3;
1232 cm->cmsp = sup->cmsp;
1233 cm->solsa = sup->solsa;
1234 cm->lcsva_cap = sup->lcsva;
1236 return 0;
1239 /* send classmark change */
1240 static int gsm48_rr_tx_cm_change(struct osmocom_ms *ms)
1242 struct gsm_support *sup = &ms->support;
1243 struct gsm_settings *set = &ms->settings;
1244 struct gsm48_rrlayer *rr = &ms->rrlayer;
1245 struct msgb *nmsg;
1246 struct gsm48_hdr *gh;
1247 struct gsm48_cm_change *cc;
1248 uint8_t cm3[14], *tlv;
1250 LOGP(DRR, LOGL_INFO, "CLASSMARK CHANGE\n");
1252 nmsg = gsm48_l3_msgb_alloc();
1253 if (!nmsg)
1254 return -ENOMEM;
1255 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1256 cc = (struct gsm48_cm_change *) msgb_put(nmsg, sizeof(*cc));
1258 gh->proto_discr = GSM48_PDISC_RR;
1259 gh->msg_type = GSM48_MT_RR_CLSM_CHG;
1261 /* classmark 2 */
1262 cc->cm2_len = sizeof(cc->cm2);
1263 gsm48_rr_enc_cm2(ms, &cc->cm2, rr->cd_now.arfcn);
1265 /* classmark 3 */
1266 if (set->dcs || set->pcs || set->e_gsm || set->r_gsm || set->gsm_850
1267 || set->a5_7 || set->a5_6 || set->a5_5 || set->a5_4
1268 || sup->ms_sup
1269 || sup->ucs2_treat
1270 || sup->ext_meas || sup->meas_cap
1271 || sup->loc_serv) {
1272 cc->cm2.cm3 = 1;
1273 cm3[0] = GSM48_IE_CLASSMARK3;
1274 gsm48_rr_enc_cm3(ms, cm3 + 2, &cm3[1]);
1275 tlv = msgb_put(nmsg, 2 + cm3[1]);
1276 memcpy(tlv, cm3, 2 + cm3[1]);
1279 return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg, 0);
1282 /* receiving classmark enquiry */
1283 static int gsm48_rr_rx_cm_enq(struct osmocom_ms *ms, struct msgb *msg)
1285 /* send classmark */
1286 return gsm48_rr_tx_cm_change(ms);
1290 * random access
1293 /* start random access */
1294 static int gsm48_rr_chan_req(struct osmocom_ms *ms, int cause, int paging,
1295 int paging_mi_type)
1297 struct gsm_settings *set = &ms->settings;
1298 struct gsm48_rrlayer *rr = &ms->rrlayer;
1299 struct gsm322_cellsel *cs = &ms->cellsel;
1300 struct gsm48_sysinfo *s = cs->si;
1301 struct msgb *nmsg;
1302 struct gsm48_rr_hdr *nrrh;
1303 uint8_t chan_req_val, chan_req_mask;
1304 int rc;
1306 LOGP(DSUM, LOGL_INFO, "Establish radio link due to %s request\n",
1307 (paging) ? "paging" : "mobility management");
1309 /* ignore paging, if not camping */
1310 if (paging
1311 && (!cs->selected || (cs->state != GSM322_C3_CAMPED_NORMALLY
1312 && cs->state != GSM322_C7_CAMPED_ANY_CELL))) {
1313 LOGP(DRR, LOGL_INFO, "Paging, but not camping, ignore.\n");
1314 return -EINVAL;
1317 /* ignore channel request while not camping on a cell */
1318 if (!cs->selected) {
1319 LOGP(DRR, LOGL_INFO, "Channel request rejected, we did not "
1320 "properly select the serving cell.\n");
1322 goto rel_ind;
1325 /* tell cell selection process to leave idle mode
1326 * NOTE: this must be sent unbuffered, because the state may not
1327 * change until idle mode is left
1329 nmsg = gsm322_msgb_alloc(GSM322_EVENT_LEAVE_IDLE);
1330 if (!nmsg)
1331 return -ENOMEM;
1332 rc = gsm322_c_event(ms, nmsg);
1333 msgb_free(nmsg);
1334 if (rc) {
1335 if (paging)
1336 return rc;
1337 LOGP(DRR, LOGL_INFO, "Failed to leave IDLE mode.\n");
1338 goto undefined;
1341 /* 3.3.1.1.2 */
1342 new_rr_state(rr, GSM48_RR_ST_CONN_PEND);
1344 /* set assignment state */
1345 rr->wait_assign = 0;
1347 /* number of retransmissions (with first transmission) */
1348 rr->n_chan_req = s->max_retrans + 1;
1350 /* generate CHAN REQ (9.1.8) */
1351 switch (cause) {
1352 case RR_EST_CAUSE_EMERGENCY:
1353 /* 101xxxxx */
1354 chan_req_mask = 0x1f;
1355 chan_req_val = 0xa0;
1356 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (Emergency call)\n",
1357 chan_req_val);
1358 break;
1359 case RR_EST_CAUSE_REESTAB_TCH_F:
1360 chan_req_mask = 0x1f;
1361 chan_req_val = 0xc0;
1362 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (re-establish "
1363 "TCH/F)\n", chan_req_val);
1364 break;
1365 case RR_EST_CAUSE_REESTAB_TCH_H:
1366 if (s->neci) {
1367 chan_req_mask = 0x03;
1368 chan_req_val = 0x68;
1369 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x "
1370 "(re-establish TCH/H with NECI)\n",
1371 chan_req_val);
1372 } else {
1373 chan_req_mask = 0x1f;
1374 chan_req_val = 0xc0;
1375 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x "
1376 "(re-establish TCH/H no NECI)\n", chan_req_val);
1378 break;
1379 case RR_EST_CAUSE_REESTAB_2_TCH_H:
1380 if (s->neci) {
1381 chan_req_mask = 0x03;
1382 chan_req_val = 0x6c;
1383 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x "
1384 "(re-establish TCH/H+TCH/H with NECI)\n",
1385 chan_req_val);
1386 } else {
1387 chan_req_mask = 0x1f;
1388 chan_req_val = 0xc0;
1389 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x "
1390 "(re-establish TCH/H+TCH/H no NECI)\n",
1391 chan_req_val);
1393 break;
1394 case RR_EST_CAUSE_ANS_PAG_ANY:
1395 chan_req_mask = 0x1f;
1396 chan_req_val = 0x80;
1397 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (PAGING "
1398 "Any channel)\n", chan_req_val);
1399 break;
1400 case RR_EST_CAUSE_ANS_PAG_SDCCH:
1401 chan_req_mask = 0x0f;
1402 chan_req_val = 0x10;
1403 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (PAGING SDCCH)\n",
1404 chan_req_val);
1405 break;
1406 case RR_EST_CAUSE_ANS_PAG_TCH_F:
1407 switch (set->ch_cap) {
1408 case GSM_CAP_SDCCH:
1409 chan_req_mask = 0x0f;
1410 chan_req_val = 0x10;
1411 break;
1412 case GSM_CAP_SDCCH_TCHF:
1413 chan_req_mask = 0x1f;
1414 chan_req_val = 0x80;
1415 break;
1416 default:
1417 chan_req_mask = 0x0f;
1418 chan_req_val = 0x20;
1419 break;
1421 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (PAGING TCH/F)\n",
1422 chan_req_val);
1423 break;
1424 case RR_EST_CAUSE_ANS_PAG_TCH_ANY:
1425 switch (set->ch_cap) {
1426 case GSM_CAP_SDCCH:
1427 chan_req_mask = 0x0f;
1428 chan_req_val = 0x10;
1429 break;
1430 case GSM_CAP_SDCCH_TCHF:
1431 chan_req_mask = 0x1f;
1432 chan_req_val = 0x80;
1433 break;
1434 default:
1435 chan_req_mask = 0x0f;
1436 chan_req_val = 0x30;
1437 break;
1439 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (PAGING TCH/H or "
1440 "TCH/F)\n", chan_req_val);
1441 break;
1442 case RR_EST_CAUSE_ORIG_TCHF:
1443 /* ms supports no dual rate */
1444 chan_req_mask = 0x1f;
1445 chan_req_val = 0xe0;
1446 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (Orig TCH/F)\n",
1447 chan_req_val);
1448 break;
1449 case RR_EST_CAUSE_LOC_UPD:
1450 if (s->neci) {
1451 chan_req_mask = 0x0f;
1452 chan_req_val = 0x00;
1453 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (Location "
1454 "Update with NECI)\n", chan_req_val);
1455 } else {
1456 chan_req_mask = 0x1f;
1457 chan_req_val = 0x00;
1458 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (Location "
1459 "Update no NECI)\n", chan_req_val);
1461 break;
1462 case RR_EST_CAUSE_OTHER_SDCCH:
1463 if (s->neci) {
1464 chan_req_mask = 0x0f;
1465 chan_req_val = 0x10;
1466 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (OHTER "
1467 "with NECI)\n", chan_req_val);
1468 } else {
1469 chan_req_mask = 0x1f;
1470 chan_req_val = 0xe0;
1471 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (OTHER "
1472 "no NECI)\n", chan_req_val);
1474 break;
1475 default:
1476 if (!rr->rr_est_req) /* no request from MM */
1477 return -EINVAL;
1479 LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: with unknown "
1480 "establishment cause: %d\n", cause);
1481 undefined:
1482 LOGP(DSUM, LOGL_INFO, "Requesting channel failed\n");
1484 rel_ind:
1485 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
1486 if (!nmsg)
1487 return -ENOMEM;
1488 nrrh = (struct gsm48_rr_hdr *)nmsg->data;
1489 nrrh->cause = RR_REL_CAUSE_UNDEFINED;
1490 gsm48_rr_upmsg(ms, nmsg);
1491 new_rr_state(rr, GSM48_RR_ST_IDLE);
1492 return -EINVAL;
1495 /* store value, mask and history */
1496 rr->chan_req_val = chan_req_val;
1497 rr->chan_req_mask = chan_req_mask;
1498 rr->cr_hist[2].valid = 0;
1499 rr->cr_hist[1].valid = 0;
1500 rr->cr_hist[0].valid = 0;
1502 /* store establishment cause, so 'choose cell' selects the last cell
1503 * after location updating */
1504 rr->est_cause = cause;
1506 /* store paging mobile identity type, if we respond to paging */
1507 rr->paging_mi_type = paging_mi_type;
1509 /* if channel is already active somehow */
1510 if (cs->ccch_state == GSM322_CCCH_ST_DATA)
1511 return gsm48_rr_tx_rand_acc(ms, NULL);
1513 return 0;
1516 /* send first/next channel request in conn pend state */
1517 int gsm48_rr_tx_rand_acc(struct osmocom_ms *ms, struct msgb *msg)
1519 struct gsm48_rrlayer *rr = &ms->rrlayer;
1520 struct gsm322_cellsel *cs = &ms->cellsel;
1521 struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
1522 struct gsm_settings *set = &ms->settings;
1523 struct msgb *nmsg;
1524 struct abis_rsl_cchan_hdr *ncch;
1525 int slots;
1526 uint8_t chan_req;
1527 uint8_t tx_power;
1529 /* already assigned */
1530 if (rr->wait_assign == 2)
1531 return 0;
1533 /* store frame number */
1534 if (msg) {
1535 struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
1536 struct gsm48_req_ref *ref =
1537 (struct gsm48_req_ref *) (ch->data + 1);
1539 if (msgb_l2len(msg) < sizeof(*ch) + sizeof(*ref)) {
1540 LOGP(DRR, LOGL_ERROR, "CHAN_CNF too slort\n");
1541 return -EINVAL;
1544 /* shift history and store */
1545 memcpy(&(rr->cr_hist[2]), &(rr->cr_hist[1]),
1546 sizeof(struct gsm48_cr_hist));
1547 memcpy(&(rr->cr_hist[1]), &(rr->cr_hist[0]),
1548 sizeof(struct gsm48_cr_hist));
1549 rr->cr_hist[0].valid = 1;
1550 rr->cr_hist[0].ref.ra = rr->cr_ra;
1551 rr->cr_hist[0].ref.t1 = ref->t1;
1552 rr->cr_hist[0].ref.t2 = ref->t2;
1553 rr->cr_hist[0].ref.t3_low = ref->t3_low;
1554 rr->cr_hist[0].ref.t3_high = ref->t3_high;
1557 if (cs->ccch_state != GSM322_CCCH_ST_DATA) {
1558 LOGP(DRR, LOGL_INFO, "CCCH channel activation failed.\n");
1559 fail:
1560 if (rr->rr_est_req) {
1561 struct msgb *msg =
1562 gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
1563 struct gsm48_rr_hdr *rrh;
1565 LOGP(DSUM, LOGL_INFO, "Requesting channel failed\n");
1566 if (!msg)
1567 return -ENOMEM;
1568 rrh = (struct gsm48_rr_hdr *)msg->data;
1569 rrh->cause = RR_REL_CAUSE_RA_FAILURE;
1570 gsm48_rr_upmsg(ms, msg);
1573 new_rr_state(rr, GSM48_RR_ST_IDLE);
1575 return 0;
1578 if (!s || !s->si3 || !s->tx_integer) {
1579 LOGP(DRR, LOGL_NOTICE, "Not enough SYSINFO\n");
1580 goto fail;
1583 if (rr->state == GSM48_RR_ST_IDLE) {
1584 LOGP(DRR, LOGL_INFO, "MM already released RR.\n");
1586 return 0;
1589 LOGP(DRR, LOGL_INFO, "RANDOM ACCESS (requests left %d)\n",
1590 rr->n_chan_req);
1592 if (!rr->n_chan_req) {
1593 LOGP(DRR, LOGL_INFO, "Done with sending RANDOM ACCESS "
1594 "bursts\n");
1595 if (!osmo_timer_pending(&rr->t3126))
1596 start_rr_t3126(rr, 5, 0); /* TODO improve! */
1597 return 0;
1599 rr->n_chan_req--;
1601 if (rr->wait_assign == 0) {
1602 /* first random acces, without delay of slots */
1603 slots = 0;
1604 rr->wait_assign = 1;
1605 } else {
1606 /* subsequent random acces, with slots from table 3.1 */
1607 switch(s->tx_integer) {
1608 case 3: case 8: case 14: case 50:
1609 if (s->ccch_conf != 1) /* not combined CCCH */
1610 slots = 55;
1611 else
1612 slots = 41;
1613 break;
1614 case 4: case 9: case 16:
1615 if (s->ccch_conf != 1)
1616 slots = 76;
1617 else
1618 slots = 52;
1619 break;
1620 case 5: case 10: case 20:
1621 if (s->ccch_conf != 1)
1622 slots = 109;
1623 else
1624 slots = 58;
1625 break;
1626 case 6: case 11: case 25:
1627 if (s->ccch_conf != 1)
1628 slots = 163;
1629 else
1630 slots = 86;
1631 break;
1632 default:
1633 if (s->ccch_conf != 1)
1634 slots = 217;
1635 else
1636 slots = 115;
1637 break;
1641 chan_req = random();
1642 chan_req &= rr->chan_req_mask;
1643 chan_req |= rr->chan_req_val;
1645 LOGP(DRR, LOGL_INFO, "RANDOM ACCESS (Tx-integer %d combined %s "
1646 "S(lots) %d ra 0x%02x)\n", s->tx_integer,
1647 (s->ccch_conf == 1) ? "yes": "no", slots, chan_req);
1649 slots = (random() % s->tx_integer) + slots;
1651 /* (re)send CHANNEL RQD with new randiom */
1652 nmsg = gsm48_rsl_msgb_alloc();
1653 if (!nmsg)
1654 return -ENOMEM;
1655 ncch = (struct abis_rsl_cchan_hdr *) msgb_put(nmsg, sizeof(*ncch)
1656 + 4 + 2 + 2);
1657 rsl_init_cchan_hdr(ncch, RSL_MT_CHAN_RQD);
1658 ncch->chan_nr = RSL_CHAN_RACH;
1659 ncch->data[0] = RSL_IE_REQ_REFERENCE;
1660 ncch->data[1] = chan_req;
1661 ncch->data[2] = (slots >> 8) | ((s->ccch_conf == 1) << 7);
1662 ncch->data[3] = slots;
1663 ncch->data[4] = RSL_IE_ACCESS_DELAY;
1664 ncch->data[5] = set->alter_delay; /* (-)=earlier (+)=later */
1665 ncch->data[6] = RSL_IE_MS_POWER;
1666 if (set->alter_tx_power) {
1667 tx_power = set->alter_tx_power_value;
1668 LOGP(DRR, LOGL_INFO, "Use alternative tx-power %d (%d dBm)\n",
1669 tx_power,
1670 ms_pwr_dbm(gsm_arfcn2band(cs->arfcn), tx_power));
1671 } else {
1672 tx_power = s->ms_txpwr_max_cch;
1673 /* power offset in case of DCS1800 */
1674 if (s->po && (cs->arfcn & 1023) >= 512
1675 && (cs->arfcn & 1023) <= 885) {
1676 LOGP(DRR, LOGL_INFO, "Use MS-TXPWR-MAX-CCH power value "
1677 "%d (%d dBm) with offset %d dBm\n", tx_power,
1678 ms_pwr_dbm(gsm_arfcn2band(cs->arfcn), tx_power),
1679 s->po_value * 2);
1680 /* use reserved bits 7,8 for offset (+ X * 2dB) */
1681 tx_power |= s->po_value << 6;
1682 } else
1683 LOGP(DRR, LOGL_INFO, "Use MS-TXPWR-MAX-CCH power value "
1684 "%d (%d dBm)\n", tx_power,
1685 ms_pwr_dbm(gsm_arfcn2band(cs->arfcn),
1686 tx_power));
1688 ncch->data[7] = tx_power;
1690 /* set initial indications */
1691 rr->cd_now.ind_tx_power = s->ms_txpwr_max_cch;
1692 rr->cd_now.ind_ta = set->alter_delay;
1694 /* store ra until confirmed, then copy it with time into cr_hist */
1695 rr->cr_ra = chan_req;
1697 return lapdm_rslms_recvmsg(nmsg, &ms->lapdm_channel);
1701 * system information
1704 /* send sysinfo event to other layers */
1705 static int gsm48_new_sysinfo(struct osmocom_ms *ms, uint8_t type)
1707 struct gsm48_sysinfo *s = ms->cellsel.si;
1708 struct gsm322_cellsel *cs = &ms->cellsel;
1709 struct msgb *nmsg;
1710 struct gsm322_msg *em;
1712 /* update list of measurements, if BA(SACCH) is complete and new */
1713 if (s
1714 && (type == GSM48_MT_RR_SYSINFO_5
1715 || type == GSM48_MT_RR_SYSINFO_5bis
1716 || type == GSM48_MT_RR_SYSINFO_5ter)
1717 && s->si5
1718 && (!s->nb_ext_ind_si5 || s->si5bis)) {
1719 struct gsm48_rr_meas *rrmeas = &ms->rrlayer.meas;
1720 int n = 0, i, refer_pcs;
1722 LOGP(DRR, LOGL_NOTICE, "Complete set of SI5* for BA(%d)\n",
1723 s->nb_ba_ind_si5);
1724 rrmeas->nc_num = 0;
1725 refer_pcs = gsm_refer_pcs(cs->arfcn, s);
1727 /* collect channels from freq list (1..1023,0) */
1728 for (i = 1; i <= 1024; i++) {
1729 if ((s->freq[i & 1023].mask & FREQ_TYPE_REP)) {
1730 if (n == 32) {
1731 LOGP(DRR, LOGL_NOTICE, "SI5* report "
1732 "exceeds 32 BCCHs\n");
1733 break;
1735 if (refer_pcs && i >= 512 && i <= 810)
1736 rrmeas->nc_arfcn[n] = i | ARFCN_PCS;
1737 else
1738 rrmeas->nc_arfcn[n] = i & 1023;
1739 rrmeas->nc_rxlev[n] = -128;
1740 LOGP(DRR, LOGL_NOTICE, "SI5* report arfcn %s\n",
1741 gsm_print_arfcn(rrmeas->nc_arfcn[n]));
1742 n++;
1745 rrmeas->nc_num = n;
1748 /* send sysinfo event to other layers */
1749 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SYSINFO);
1750 if (!nmsg)
1751 return -ENOMEM;
1752 em = (struct gsm322_msg *) nmsg->data;
1753 em->sysinfo = type;
1754 gsm322_cs_sendmsg(ms, nmsg);
1756 /* if not camping, we don't care about SI */
1757 if (ms->cellsel.neighbour
1758 || (ms->cellsel.state != GSM322_C3_CAMPED_NORMALLY
1759 && ms->cellsel.state != GSM322_C7_CAMPED_ANY_CELL))
1760 return 0;
1762 /* send timer info to location update process */
1763 nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_SYSINFO);
1764 if (!nmsg)
1765 return -ENOMEM;
1766 gsm48_mmevent_msg(ms, nmsg);
1768 return 0;
1771 /* receive "SYSTEM INFORMATION 1" message (9.1.31) */
1772 static int gsm48_rr_rx_sysinfo1(struct osmocom_ms *ms, struct msgb *msg)
1774 struct gsm48_system_information_type_1 *si = msgb_l3(msg);
1775 struct gsm48_sysinfo *s = ms->cellsel.si;
1776 int payload_len = msgb_l3len(msg) - sizeof(*si);
1778 if (!s) {
1779 LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 1 "
1780 "ignored\n");
1781 return -EINVAL;
1784 if (payload_len < 0) {
1785 LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 1 "
1786 "message.\n");
1787 return -EINVAL;
1790 if (!memcmp(si, s->si1_msg, MIN(msgb_l3len(msg), sizeof(s->si1_msg))))
1791 return 0;
1793 gsm48_decode_sysinfo1(s, si, msgb_l3len(msg));
1795 LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 1\n");
1797 return gsm48_new_sysinfo(ms, si->header.system_information);
1800 /* receive "SYSTEM INFORMATION 2" message (9.1.32) */
1801 static int gsm48_rr_rx_sysinfo2(struct osmocom_ms *ms, struct msgb *msg)
1803 struct gsm48_system_information_type_2 *si = msgb_l3(msg);
1804 struct gsm48_sysinfo *s = ms->cellsel.si;
1805 int payload_len = msgb_l3len(msg) - sizeof(*si);
1807 if (!s) {
1808 LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 2 "
1809 "ignored\n");
1810 return -EINVAL;
1813 if (payload_len < 0) {
1814 LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 2 "
1815 "message.\n");
1816 return -EINVAL;
1819 if (!memcmp(si, s->si2_msg, MIN(msgb_l3len(msg), sizeof(s->si2_msg))))
1820 return 0;
1822 gsm48_decode_sysinfo2(s, si, msgb_l3len(msg));
1824 LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2\n");
1826 return gsm48_new_sysinfo(ms, si->header.system_information);
1829 /* receive "SYSTEM INFORMATION 2bis" message (9.1.33) */
1830 static int gsm48_rr_rx_sysinfo2bis(struct osmocom_ms *ms, struct msgb *msg)
1832 struct gsm48_system_information_type_2bis *si = msgb_l3(msg);
1833 struct gsm48_sysinfo *s = ms->cellsel.si;
1834 int payload_len = msgb_l3len(msg) - sizeof(*si);
1836 if (!s) {
1837 LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 2bis"
1838 " ignored\n");
1839 return -EINVAL;
1842 if (payload_len < 0) {
1843 LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 2bis "
1844 "message.\n");
1845 return -EINVAL;
1848 if (!memcmp(si, s->si2b_msg, MIN(msgb_l3len(msg), sizeof(s->si2b_msg))))
1849 return 0;
1851 gsm48_decode_sysinfo2bis(s, si, msgb_l3len(msg));
1853 LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2bis\n");
1855 return gsm48_new_sysinfo(ms, si->header.system_information);
1858 /* receive "SYSTEM INFORMATION 2ter" message (9.1.34) */
1859 static int gsm48_rr_rx_sysinfo2ter(struct osmocom_ms *ms, struct msgb *msg)
1861 struct gsm48_system_information_type_2ter *si = msgb_l3(msg);
1862 struct gsm48_sysinfo *s = ms->cellsel.si;
1863 int payload_len = msgb_l3len(msg) - sizeof(*si);
1865 if (!s) {
1866 LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 2ter"
1867 " ignored\n");
1868 return -EINVAL;
1871 if (payload_len < 0) {
1872 LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 2ter "
1873 "message.\n");
1874 return -EINVAL;
1877 if (!memcmp(si, s->si2t_msg, MIN(msgb_l3len(msg), sizeof(s->si2t_msg))))
1878 return 0;
1880 gsm48_decode_sysinfo2ter(s, si, msgb_l3len(msg));
1882 LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2ter\n");
1884 return gsm48_new_sysinfo(ms, si->header.system_information);
1887 /* receive "SYSTEM INFORMATION 3" message (9.1.35) */
1888 static int gsm48_rr_rx_sysinfo3(struct osmocom_ms *ms, struct msgb *msg)
1890 struct gsm48_system_information_type_3 *si = msgb_l3(msg);
1891 struct gsm322_cellsel *cs = &ms->cellsel;
1892 struct gsm48_sysinfo *s = cs->si;
1893 int payload_len = msgb_l3len(msg) - sizeof(*si);
1895 if (!s) {
1896 LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 3 "
1897 "ignored\n");
1898 return -EINVAL;
1901 if (payload_len < 0) {
1902 LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 3 "
1903 "message.\n");
1904 return -EINVAL;
1907 if (!memcmp(si, s->si3_msg, MIN(msgb_l3len(msg), sizeof(s->si3_msg))))
1908 return 0;
1910 gsm48_decode_sysinfo3(s, si, msgb_l3len(msg));
1912 if (cs->ccch_mode == CCCH_MODE_NONE) {
1913 cs->ccch_mode = (s->ccch_conf == 1) ? CCCH_MODE_COMBINED :
1914 CCCH_MODE_NON_COMBINED;
1915 LOGP(DRR, LOGL_NOTICE, "Changing CCCH_MODE to %d\n",
1916 cs->ccch_mode);
1917 l1ctl_tx_ccch_mode_req(ms, cs->ccch_mode);
1920 return gsm48_new_sysinfo(ms, si->header.system_information);
1923 /* receive "SYSTEM INFORMATION 4" message (9.1.36) */
1924 static int gsm48_rr_rx_sysinfo4(struct osmocom_ms *ms, struct msgb *msg)
1926 /* NOTE: pseudo length is not in this structure, so we skip */
1927 struct gsm48_system_information_type_4 *si = msgb_l3(msg);
1928 struct gsm48_sysinfo *s = ms->cellsel.si;
1929 int payload_len = msgb_l3len(msg) - sizeof(*si);
1931 if (!s) {
1932 LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 4 "
1933 "ignored\n");
1934 return -EINVAL;
1937 if (payload_len < 0) {
1938 LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 4 "
1939 "message.\n");
1940 return -EINVAL;
1943 if (!memcmp(si, s->si4_msg, MIN(msgb_l3len(msg), sizeof(s->si4_msg))))
1944 return 0;
1946 gsm48_decode_sysinfo4(s, si, msgb_l3len(msg));
1948 LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 4 (mcc %s mnc %s "
1949 "lac 0x%04x)\n", gsm_print_mcc(s->mcc),
1950 gsm_print_mnc(s->mnc), s->lac);
1952 return gsm48_new_sysinfo(ms, si->header.system_information);
1955 /* receive "SYSTEM INFORMATION 5" message (9.1.37) */
1956 static int gsm48_rr_rx_sysinfo5(struct osmocom_ms *ms, struct msgb *msg)
1958 /* NOTE: pseudo length is not in this structure, so we skip */
1959 struct gsm48_system_information_type_5 *si = msgb_l3(msg) + 1;
1960 struct gsm48_sysinfo *s = ms->cellsel.si;
1961 int payload_len = msgb_l3len(msg) - sizeof(*si) - 1;
1963 if (!s) {
1964 LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 5 "
1965 "ignored\n");
1966 return -EINVAL;
1969 if (payload_len < 0) {
1970 LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 5 "
1971 "message.\n");
1972 return -EINVAL;
1975 if (!memcmp(si, s->si5_msg, MIN(msgb_l3len(msg), sizeof(s->si5_msg))))
1976 return 0;
1978 gsm48_decode_sysinfo5(s, si, msgb_l3len(msg));
1980 LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 5\n");
1982 return gsm48_new_sysinfo(ms, si->system_information);
1985 /* receive "SYSTEM INFORMATION 5bis" message (9.1.38) */
1986 static int gsm48_rr_rx_sysinfo5bis(struct osmocom_ms *ms, struct msgb *msg)
1988 /* NOTE: pseudo length is not in this structure, so we skip */
1989 struct gsm48_system_information_type_5bis *si = msgb_l3(msg) + 1;
1990 struct gsm48_sysinfo *s = ms->cellsel.si;
1991 int payload_len = msgb_l3len(msg) - sizeof(*si) - 1;
1993 if (!s) {
1994 LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 5bis"
1995 " ignored\n");
1996 return -EINVAL;
1999 if (payload_len < 0) {
2000 LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 5bis "
2001 "message.\n");
2002 return -EINVAL;
2005 if (!memcmp(si, s->si5b_msg, MIN(msgb_l3len(msg),
2006 sizeof(s->si5b_msg))))
2007 return 0;
2009 gsm48_decode_sysinfo5bis(s, si, msgb_l3len(msg));
2011 LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 5bis\n");
2013 return gsm48_new_sysinfo(ms, si->system_information);
2016 /* receive "SYSTEM INFORMATION 5ter" message (9.1.39) */
2017 static int gsm48_rr_rx_sysinfo5ter(struct osmocom_ms *ms, struct msgb *msg)
2019 /* NOTE: pseudo length is not in this structure, so we skip */
2020 struct gsm48_system_information_type_5ter *si = msgb_l3(msg) + 1;
2021 struct gsm48_sysinfo *s = ms->cellsel.si;
2022 int payload_len = msgb_l3len(msg) - sizeof(*si) - 1;
2024 if (!s) {
2025 LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 5ter"
2026 " ignored\n");
2027 return -EINVAL;
2030 if (payload_len < 0) {
2031 LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 5ter "
2032 "message.\n");
2033 return -EINVAL;
2036 if (!memcmp(si, s->si5t_msg, MIN(msgb_l3len(msg),
2037 sizeof(s->si5t_msg))))
2038 return 0;
2040 gsm48_decode_sysinfo5ter(s, si, msgb_l3len(msg));
2042 LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 5ter\n");
2044 return gsm48_new_sysinfo(ms, si->system_information);
2047 /* receive "SYSTEM INFORMATION 6" message (9.1.39) */
2048 static int gsm48_rr_rx_sysinfo6(struct osmocom_ms *ms, struct msgb *msg)
2050 /* NOTE: pseudo length is not in this structure, so we skip */
2051 struct gsm48_system_information_type_6 *si = msgb_l3(msg) + 1;
2052 struct gsm48_sysinfo *s = ms->cellsel.si;
2053 struct rx_meas_stat *meas = &ms->meas;
2054 int payload_len = msgb_l3len(msg) - sizeof(*si) - 1;
2056 if (!s) {
2057 LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 6 "
2058 "ignored\n");
2059 return -EINVAL;
2062 if (payload_len < 0) {
2063 LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 6 "
2064 "message.\n");
2065 return -EINVAL;
2068 if (!memcmp(si, s->si6_msg, MIN(msgb_l3len(msg), sizeof(s->si6_msg))))
2069 return 0;
2071 gsm48_decode_sysinfo6(s, si, msgb_l3len(msg));
2073 LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 6 (mcc %s mnc %s "
2074 "lac 0x%04x SACCH-timeout %d)\n", gsm_print_mcc(s->mcc),
2075 gsm_print_mnc(s->mnc), s->lac, s->sacch_radio_link_timeout);
2077 meas->rl_fail = meas->s = s->sacch_radio_link_timeout;
2078 LOGP(DRR, LOGL_INFO, "using (new) SACCH timeout %d\n", meas->rl_fail);
2080 return gsm48_new_sysinfo(ms, si->system_information);
2084 * paging
2087 /* paging channel request */
2088 static int gsm48_rr_chan2cause[4] = {
2089 RR_EST_CAUSE_ANS_PAG_ANY,
2090 RR_EST_CAUSE_ANS_PAG_SDCCH,
2091 RR_EST_CAUSE_ANS_PAG_TCH_F,
2092 RR_EST_CAUSE_ANS_PAG_TCH_ANY
2095 /* given LV of mobile identity is checked agains ms */
2096 static uint8_t gsm_match_mi(struct osmocom_ms *ms, uint8_t *mi)
2098 struct gsm322_cellsel *cs = &ms->cellsel;
2099 char imsi[16];
2100 uint32_t tmsi;
2101 uint8_t mi_type;
2103 if (mi[0] < 1)
2104 return 0;
2105 mi_type = mi[1] & GSM_MI_TYPE_MASK;
2106 switch (mi_type) {
2107 case GSM_MI_TYPE_TMSI:
2108 if (mi[0] < 5)
2109 return 0;
2110 memcpy(&tmsi, mi+2, 4);
2111 if (ms->subscr.tmsi == ntohl(tmsi)
2112 && ms->subscr.mcc == cs->sel_mcc
2113 && ms->subscr.mnc == cs->sel_mnc
2114 && ms->subscr.lac == cs->sel_lac) {
2115 LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n",
2116 ntohl(tmsi));
2118 return mi_type;
2119 } else
2120 LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
2121 ntohl(tmsi));
2122 break;
2123 case GSM_MI_TYPE_IMSI:
2124 gsm48_mi_to_string(imsi, sizeof(imsi), mi + 1, mi[0]);
2125 if (!strcmp(imsi, ms->subscr.imsi)) {
2126 LOGP(DPAG, LOGL_INFO, " IMSI %s matches\n", imsi);
2128 return mi_type;
2129 } else
2130 LOGP(DPAG, LOGL_INFO, " IMSI %s (not for us)\n", imsi);
2131 break;
2132 default:
2133 LOGP(DPAG, LOGL_NOTICE, "Paging with unsupported MI type %d.\n",
2134 mi_type);
2137 return 0;
2140 /* 9.1.22 PAGING REQUEST 1 message received */
2141 static int gsm48_rr_rx_pag_req_1(struct osmocom_ms *ms, struct msgb *msg)
2143 struct gsm48_rrlayer *rr = &ms->rrlayer;
2144 struct gsm322_cellsel *cs = &ms->cellsel;
2145 struct gsm48_paging1 *pa = msgb_l3(msg);
2146 int payload_len = msgb_l3len(msg) - sizeof(*pa);
2147 int chan_1, chan_2;
2148 uint8_t *mi, mi_type;
2150 /* empty paging request */
2151 if (payload_len >= 2 && (pa->data[1] & GSM_MI_TYPE_MASK) == 0)
2152 return 0;
2154 /* 3.3.1.1.2: ignore paging while not camping on a cell */
2155 if (rr->state != GSM48_RR_ST_IDLE || !cs->selected
2156 || (cs->state != GSM322_C3_CAMPED_NORMALLY
2157 && cs->state != GSM322_C7_CAMPED_ANY_CELL)
2158 || cs->neighbour) {
2159 LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping.\n");
2161 return 0;
2163 LOGP(DPAG, LOGL_INFO, "PAGING REQUEST 1\n");
2165 if (payload_len < 2) {
2166 short_read:
2167 LOGP(DRR, LOGL_NOTICE, "Short read of PAGING REQUEST 1 "
2168 "message.\n");
2170 return -EINVAL;
2173 /* channel needed */
2174 chan_1 = pa->cneed1;
2175 chan_2 = pa->cneed2;
2176 /* first MI */
2177 mi = pa->data;
2178 if (payload_len < mi[0] + 1)
2179 goto short_read;
2180 if ((mi_type = gsm_match_mi(ms, mi)) > 0)
2181 return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1,
2182 mi_type);
2183 /* second MI */
2184 payload_len -= mi[0] + 1;
2185 mi = pa->data + mi[0] + 1;
2186 if (payload_len < 2)
2187 return 0;
2188 if (mi[0] != GSM48_IE_MOBILE_ID)
2189 return 0;
2190 if (payload_len < mi[1] + 2)
2191 goto short_read;
2192 if ((mi_type = gsm_match_mi(ms, mi + 1)) > 0)
2193 return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1,
2194 mi_type);
2196 return 0;
2199 /* 9.1.23 PAGING REQUEST 2 message received */
2200 static int gsm48_rr_rx_pag_req_2(struct osmocom_ms *ms, struct msgb *msg)
2202 struct gsm48_rrlayer *rr = &ms->rrlayer;
2203 struct gsm322_cellsel *cs = &ms->cellsel;
2204 struct gsm48_paging2 *pa = msgb_l3(msg);
2205 int payload_len = msgb_l3len(msg) - sizeof(*pa);
2206 uint8_t *mi, mi_type;
2207 int chan_1, chan_2, chan_3;
2209 /* 3.3.1.1.2: ignore paging while not camping on a cell */
2210 if (rr->state != GSM48_RR_ST_IDLE || !cs->selected
2211 || (cs->state != GSM322_C3_CAMPED_NORMALLY
2212 && cs->state != GSM322_C7_CAMPED_ANY_CELL)
2213 || cs->neighbour) {
2214 LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping.\n");
2216 return 0;
2218 LOGP(DPAG, LOGL_INFO, "PAGING REQUEST 2\n");
2220 if (payload_len < 0) {
2221 short_read:
2222 LOGP(DRR, LOGL_NOTICE, "Short read of PAGING REQUEST 2 "
2223 "message .\n");
2225 return -EINVAL;
2228 /* channel needed */
2229 chan_1 = pa->cneed1;
2230 chan_2 = pa->cneed2;
2231 /* first MI */
2232 if (ms->subscr.tmsi == ntohl(pa->tmsi1)
2233 && ms->subscr.mcc == cs->sel_mcc
2234 && ms->subscr.mnc == cs->sel_mnc
2235 && ms->subscr.lac == cs->sel_lac) {
2236 LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi1));
2237 return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1,
2238 GSM_MI_TYPE_TMSI);
2239 } else
2240 LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
2241 ntohl(pa->tmsi1));
2242 /* second MI */
2243 if (ms->subscr.tmsi == ntohl(pa->tmsi2)
2244 && ms->subscr.mcc == cs->sel_mcc
2245 && ms->subscr.mnc == cs->sel_mnc
2246 && ms->subscr.lac == cs->sel_lac) {
2247 LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi2));
2248 return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1,
2249 GSM_MI_TYPE_TMSI);
2250 } else
2251 LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
2252 ntohl(pa->tmsi2));
2253 /* third MI */
2254 mi = pa->data;
2255 if (payload_len < 2)
2256 return 0;
2257 if (mi[0] != GSM48_IE_MOBILE_ID)
2258 return 0;
2259 if (payload_len < mi[1] + 2 + 1) /* must include "channel needed" */
2260 goto short_read;
2261 chan_3 = mi[mi[1] + 2] & 0x03; /* channel needed */
2262 if ((mi_type = gsm_match_mi(ms, mi + 1)) > 0)
2263 return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_3], 1,
2264 mi_type);
2266 return 0;
2269 /* 9.1.24 PAGING REQUEST 3 message received */
2270 static int gsm48_rr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg)
2272 struct gsm48_rrlayer *rr = &ms->rrlayer;
2273 struct gsm322_cellsel *cs = &ms->cellsel;
2274 struct gsm48_paging3 *pa = msgb_l3(msg);
2275 int payload_len = msgb_l3len(msg) - sizeof(*pa);
2276 int chan_1, chan_2, chan_3, chan_4;
2278 /* 3.3.1.1.2: ignore paging while not camping on a cell */
2279 if (rr->state != GSM48_RR_ST_IDLE || !cs->selected
2280 || (cs->state != GSM322_C3_CAMPED_NORMALLY
2281 && cs->state != GSM322_C7_CAMPED_ANY_CELL)
2282 || cs->neighbour) {
2283 LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping.\n");
2285 return 0;
2287 LOGP(DPAG, LOGL_INFO, "PAGING REQUEST 3\n");
2289 if (payload_len < 0) { /* must include "channel needed", part of *pa */
2290 LOGP(DRR, LOGL_NOTICE, "Short read of PAGING REQUEST 3 "
2291 "message .\n");
2293 return -EINVAL;
2296 /* channel needed */
2297 chan_1 = pa->cneed1;
2298 chan_2 = pa->cneed2;
2299 chan_3 = pa->cneed3;
2300 chan_4 = pa->cneed4;
2301 /* first MI */
2302 if (ms->subscr.tmsi == ntohl(pa->tmsi1)
2303 && ms->subscr.mcc == cs->sel_mcc
2304 && ms->subscr.mnc == cs->sel_mnc
2305 && ms->subscr.lac == cs->sel_lac) {
2306 LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi1));
2307 return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1,
2308 GSM_MI_TYPE_TMSI);
2309 } else
2310 LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
2311 ntohl(pa->tmsi1));
2312 /* second MI */
2313 if (ms->subscr.tmsi == ntohl(pa->tmsi2)
2314 && ms->subscr.mcc == cs->sel_mcc
2315 && ms->subscr.mnc == cs->sel_mnc
2316 && ms->subscr.lac == cs->sel_lac) {
2317 LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi2));
2318 return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1,
2319 GSM_MI_TYPE_TMSI);
2320 } else
2321 LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
2322 ntohl(pa->tmsi2));
2323 /* thrid MI */
2324 if (ms->subscr.tmsi == ntohl(pa->tmsi3)
2325 && ms->subscr.mcc == cs->sel_mcc
2326 && ms->subscr.mnc == cs->sel_mnc
2327 && ms->subscr.lac == cs->sel_lac) {
2328 LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi3));
2329 return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_3], 1,
2330 GSM_MI_TYPE_TMSI);
2331 } else
2332 LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
2333 ntohl(pa->tmsi3));
2334 /* fourth MI */
2335 if (ms->subscr.tmsi == ntohl(pa->tmsi4)
2336 && ms->subscr.mcc == cs->sel_mcc
2337 && ms->subscr.mnc == cs->sel_mnc
2338 && ms->subscr.lac == cs->sel_lac) {
2339 LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi4));
2340 return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_4], 1,
2341 GSM_MI_TYPE_TMSI);
2342 } else
2343 LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
2344 ntohl(pa->tmsi4));
2346 return 0;
2350 * (immediate) assignment
2353 /* match request reference agains request history */
2354 static int gsm48_match_ra(struct osmocom_ms *ms, struct gsm48_req_ref *ref)
2356 struct gsm48_rrlayer *rr = &ms->rrlayer;
2357 int i;
2358 uint8_t ia_t1, ia_t2, ia_t3;
2359 uint8_t cr_t1, cr_t2, cr_t3;
2361 for (i = 0; i < 3; i++) {
2362 /* filter confirmed RACH requests only */
2363 if (rr->cr_hist[i].valid && ref->ra == rr->cr_hist[i].ref.ra) {
2364 ia_t1 = ref->t1;
2365 ia_t2 = ref->t2;
2366 ia_t3 = (ref->t3_high << 3) | ref->t3_low;
2367 ref = &rr->cr_hist[i].ref;
2368 cr_t1 = ref->t1;
2369 cr_t2 = ref->t2;
2370 cr_t3 = (ref->t3_high << 3) | ref->t3_low;
2371 if (ia_t1 == cr_t1 && ia_t2 == cr_t2
2372 && ia_t3 == cr_t3) {
2373 LOGP(DRR, LOGL_INFO, "request %02x matches "
2374 "(fn=%d,%d,%d)\n", ref->ra, ia_t1,
2375 ia_t2, ia_t3);
2376 return 1;
2377 } else
2378 LOGP(DRR, LOGL_INFO, "request %02x matches "
2379 "but not frame number (IMM.ASS "
2380 "fn=%d,%d,%d != RACH fn=%d,%d,%d)\n",
2381 ref->ra, ia_t1, ia_t2, ia_t3,
2382 cr_t1, cr_t2, cr_t3);
2386 return 0;
2389 /* 9.1.18 IMMEDIATE ASSIGNMENT is received */
2390 static int gsm48_rr_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg)
2392 struct gsm48_rrlayer *rr = &ms->rrlayer;
2393 struct gsm48_imm_ass *ia = msgb_l3(msg);
2394 struct gsm322_cellsel *cs = &ms->cellsel;
2395 struct gsm48_sysinfo *s = cs->si;
2396 int ma_len = msgb_l3len(msg) - sizeof(*ia);
2397 uint8_t ch_type, ch_subch, ch_ts;
2398 struct gsm48_rr_cd cd;
2399 #ifndef TEST_STARTING_TIMER
2400 uint8_t *st, st_len;
2401 #endif
2403 /* ignore imm.ass. while not camping on a cell */
2404 if (!cs->selected || cs->neighbour || !s) {
2405 LOGP(DRR, LOGL_INFO, "IMMEDIATED ASSGINMENT ignored, we are "
2406 "have not proper selected the serving cell.\n");
2408 return 0;
2411 memset(&cd, 0, sizeof(cd));
2412 cd.ind_tx_power = rr->cd_now.ind_tx_power;
2414 if (ma_len < 0 /* mobile allocation IE must be included */
2415 || ia->mob_alloc_len > ma_len) { /* short read of IE */
2416 LOGP(DRR, LOGL_NOTICE, "Short read of IMMEDIATE ASSIGNMENT "
2417 "message.\n");
2418 return -EINVAL;
2420 if (ia->mob_alloc_len > 8) {
2421 LOGP(DRR, LOGL_NOTICE, "Moble allocation in IMMEDIATE "
2422 "ASSIGNMENT too large.\n");
2423 return -EINVAL;
2426 /* starting time */
2427 #ifdef TEST_STARTING_TIMER
2428 cd.start = 1;
2429 cd.start_tm.fn = (ms->meas.last_fn + TEST_STARTING_TIMER) % 42432;
2430 LOGP(DRR, LOGL_INFO, " TESTING: starting time ahead\n");
2431 #else
2432 st_len = ma_len - ia->mob_alloc_len;
2433 st = ia->mob_alloc + ia->mob_alloc_len;
2434 if (st_len >= 3 && st[0] == GSM48_IE_START_TIME)
2435 gsm48_decode_start_time(&cd, (struct gsm48_start_time *)(st+1));
2436 #endif
2438 /* decode channel description */
2439 LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT:\n");
2440 cd.chan_nr = ia->chan_desc.chan_nr;
2441 rsl_dec_chan_nr(cd.chan_nr, &ch_type, &ch_subch, &ch_ts);
2442 if (ia->chan_desc.h0.h) {
2443 cd.h = 1;
2444 gsm48_decode_chan_h1(&ia->chan_desc, &cd.tsc, &cd.maio,
2445 &cd.hsn);
2446 LOGP(DRR, LOGL_INFO, " (ta %d/%dm ra 0x%02x chan_nr 0x%02x "
2447 "MAIO %u HSN %u TS %u SS %u TSC %u)\n",
2448 ia->timing_advance,
2449 ia->timing_advance * GSM_TA_CM / 100,
2450 ia->req_ref.ra, ia->chan_desc.chan_nr, cd.maio,
2451 cd.hsn, ch_ts, ch_subch, cd.tsc);
2452 } else {
2453 cd.h = 0;
2454 gsm48_decode_chan_h0(&ia->chan_desc, &cd.tsc, &cd.arfcn);
2455 if (gsm_refer_pcs(cs->arfcn, s))
2456 cd.arfcn |= ARFCN_PCS;
2457 LOGP(DRR, LOGL_INFO, " (ta %d/%dm ra 0x%02x chan_nr 0x%02x "
2458 "ARFCN %s TS %u SS %u TSC %u)\n",
2459 ia->timing_advance,
2460 ia->timing_advance * GSM_TA_CM / 100,
2461 ia->req_ref.ra, ia->chan_desc.chan_nr,
2462 gsm_print_arfcn(cd.arfcn), ch_ts, ch_subch, cd.tsc);
2465 /* 3.3.1.1.2: ignore assignment while idle */
2466 if (rr->state != GSM48_RR_ST_CONN_PEND || rr->wait_assign == 0) {
2467 LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
2468 return 0;
2471 if (rr->wait_assign == 2) {
2472 LOGP(DRR, LOGL_INFO, "Ignoring, channel already assigned.\n");
2473 return 0;
2476 /* request ref */
2477 if (gsm48_match_ra(ms, &ia->req_ref)) {
2478 /* channel description */
2479 memcpy(&rr->cd_now, &cd, sizeof(rr->cd_now));
2480 /* timing advance */
2481 rr->cd_now.ind_ta = ia->timing_advance;
2482 /* mobile allocation */
2483 memcpy(&rr->cd_now.mob_alloc_lv, &ia->mob_alloc_len,
2484 ia->mob_alloc_len + 1);
2485 rr->wait_assign = 2;
2486 /* reset scheduler */
2487 LOGP(DRR, LOGL_INFO, "resetting scheduler\n");
2488 l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED);
2490 return gsm48_rr_dl_est(ms);
2492 LOGP(DRR, LOGL_INFO, "Request, but not for us.\n");
2494 return 0;
2497 /* 9.1.19 IMMEDIATE ASSIGNMENT EXTENDED is received */
2498 static int gsm48_rr_rx_imm_ass_ext(struct osmocom_ms *ms, struct msgb *msg)
2500 struct gsm48_rrlayer *rr = &ms->rrlayer;
2501 struct gsm322_cellsel *cs = &ms->cellsel;
2502 struct gsm48_sysinfo *s = cs->si;
2503 struct gsm48_imm_ass_ext *ia = msgb_l3(msg);
2504 int ma_len = msgb_l3len(msg) - sizeof(*ia);
2505 uint8_t ch_type, ch_subch, ch_ts;
2506 struct gsm48_rr_cd cd1, cd2;
2507 #ifndef TEST_STARTING_TIMER
2508 uint8_t *st, st_len;
2509 #endif
2511 /* ignore imm.ass.ext while not camping on a cell */
2512 if (!cs->selected || cs->neighbour || !s) {
2513 LOGP(DRR, LOGL_INFO, "IMMEDIATED ASSGINMENT ignored, we are "
2514 "have not proper selected the serving cell.\n");
2516 return 0;
2519 memset(&cd1, 0, sizeof(cd1));
2520 cd1.ind_tx_power = rr->cd_now.ind_tx_power;
2521 memset(&cd2, 0, sizeof(cd2));
2522 cd2.ind_tx_power = rr->cd_now.ind_tx_power;
2524 if (ma_len < 0 /* mobile allocation IE must be included */
2525 || ia->mob_alloc_len > ma_len) { /* short read of IE */
2526 LOGP(DRR, LOGL_NOTICE, "Short read of IMMEDIATE ASSIGNMENT "
2527 "EXTENDED message.\n");
2528 return -EINVAL;
2530 if (ia->mob_alloc_len > 4) {
2531 LOGP(DRR, LOGL_NOTICE, "Moble allocation in IMMEDIATE "
2532 "ASSIGNMENT EXTENDED too large.\n");
2533 return -EINVAL;
2536 #ifdef TEST_STARTING_TIMER
2537 cd1.start = 1;
2538 cd2.start_tm.fn = (ms->meas.last_fn + TEST_STARTING_TIMER) % 42432;
2539 memcpy(&cd2, &cd1, sizeof(cd2));
2540 LOGP(DRR, LOGL_INFO, " TESTING: starting time ahead\n");
2541 #else
2542 /* starting time */
2543 st_len = ma_len - ia->mob_alloc_len;
2544 st = ia->mob_alloc + ia->mob_alloc_len;
2545 if (st_len >= 3 && st[0] == GSM48_IE_START_TIME) {
2546 gsm48_decode_start_time(&cd1,
2547 (struct gsm48_start_time *)(st+1));
2548 memcpy(&cd2, &cd1, sizeof(cd2));
2550 #endif
2552 /* decode channel description */
2553 LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT EXTENDED:\n");
2554 cd1.chan_nr = ia->chan_desc1.chan_nr;
2555 rsl_dec_chan_nr(cd1.chan_nr, &ch_type, &ch_subch, &ch_ts);
2556 if (ia->chan_desc1.h0.h) {
2557 cd1.h = 1;
2558 gsm48_decode_chan_h1(&ia->chan_desc1, &cd1.tsc, &cd1.maio,
2559 &cd1.hsn);
2560 LOGP(DRR, LOGL_INFO, " assignment 1 (ta %d/%dm ra 0x%02x "
2561 "chan_nr 0x%02x MAIO %u HSN %u TS %u SS %u TSC %u)\n",
2562 ia->timing_advance1,
2563 ia->timing_advance1 * GSM_TA_CM / 100,
2564 ia->req_ref1.ra, ia->chan_desc1.chan_nr, cd1.maio,
2565 cd1.hsn, ch_ts, ch_subch, cd1.tsc);
2566 } else {
2567 cd1.h = 0;
2568 gsm48_decode_chan_h0(&ia->chan_desc1, &cd1.tsc, &cd1.arfcn);
2569 if (gsm_refer_pcs(cs->arfcn, s))
2570 cd1.arfcn |= ARFCN_PCS;
2571 LOGP(DRR, LOGL_INFO, " assignment 1 (ta %d/%dm ra 0x%02x "
2572 "chan_nr 0x%02x ARFCN %s TS %u SS %u TSC %u)\n",
2573 ia->timing_advance1,
2574 ia->timing_advance1 * GSM_TA_CM / 100,
2575 ia->req_ref1.ra, ia->chan_desc1.chan_nr,
2576 gsm_print_arfcn(cd1.arfcn), ch_ts, ch_subch, cd1.tsc);
2578 cd2.chan_nr = ia->chan_desc2.chan_nr;
2579 rsl_dec_chan_nr(cd2.chan_nr, &ch_type, &ch_subch, &ch_ts);
2580 if (ia->chan_desc2.h0.h) {
2581 cd2.h = 1;
2582 gsm48_decode_chan_h1(&ia->chan_desc2, &cd2.tsc, &cd2.maio,
2583 &cd2.hsn);
2584 LOGP(DRR, LOGL_INFO, " assignment 2 (ta %d/%dm ra 0x%02x "
2585 "chan_nr 0x%02x MAIO %u HSN %u TS %u SS %u TSC %u)\n",
2586 ia->timing_advance2,
2587 ia->timing_advance2 * GSM_TA_CM / 100,
2588 ia->req_ref2.ra, ia->chan_desc2.chan_nr, cd2.maio,
2589 cd2.hsn, ch_ts, ch_subch, cd2.tsc);
2590 } else {
2591 cd2.h = 0;
2592 gsm48_decode_chan_h0(&ia->chan_desc2, &cd2.tsc, &cd2.arfcn);
2593 if (gsm_refer_pcs(cs->arfcn, s))
2594 cd2.arfcn |= ARFCN_PCS;
2595 LOGP(DRR, LOGL_INFO, " assignment 2 (ta %d/%dm ra 0x%02x "
2596 "chan_nr 0x%02x ARFCN %s TS %u SS %u TSC %u)\n",
2597 ia->timing_advance2,
2598 ia->timing_advance2 * GSM_TA_CM / 100,
2599 ia->req_ref2.ra, ia->chan_desc2.chan_nr,
2600 gsm_print_arfcn(cd2.arfcn), ch_ts, ch_subch, cd2.tsc);
2603 /* 3.3.1.1.2: ignore assignment while idle */
2604 if (rr->state != GSM48_RR_ST_CONN_PEND || rr->wait_assign == 0) {
2605 LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
2606 return 0;
2609 if (rr->wait_assign == 2) {
2610 LOGP(DRR, LOGL_INFO, "Ignoring, channel already assigned.\n");
2611 return 0;
2614 /* request ref 1 */
2615 if (gsm48_match_ra(ms, &ia->req_ref1)) {
2616 /* channel description */
2617 memcpy(&rr->cd_now, &cd1, sizeof(rr->cd_now));
2618 /* timing advance */
2619 rr->cd_now.ind_ta = ia->timing_advance1;
2620 /* mobile allocation */
2621 memcpy(&rr->cd_now.mob_alloc_lv, &ia->mob_alloc_len,
2622 ia->mob_alloc_len + 1);
2623 rr->wait_assign = 2;
2624 /* reset scheduler */
2625 LOGP(DRR, LOGL_INFO, "resetting scheduler\n");
2626 l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED);
2628 return gsm48_rr_dl_est(ms);
2630 /* request ref 2 */
2631 if (gsm48_match_ra(ms, &ia->req_ref2)) {
2632 /* channel description */
2633 memcpy(&rr->cd_now, &cd2, sizeof(rr->cd_now));
2634 /* timing advance */
2635 rr->cd_now.ind_ta = ia->timing_advance2;
2636 /* mobile allocation */
2637 memcpy(&rr->cd_now.mob_alloc_lv, &ia->mob_alloc_len,
2638 ia->mob_alloc_len + 1);
2639 rr->wait_assign = 2;
2640 /* reset scheduler */
2641 LOGP(DRR, LOGL_INFO, "resetting scheduler\n");
2642 l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED);
2644 return gsm48_rr_dl_est(ms);
2646 LOGP(DRR, LOGL_INFO, "Request, but not for us.\n");
2648 return 0;
2651 /* 9.1.20 IMMEDIATE ASSIGNMENT REJECT is received */
2652 static int gsm48_rr_rx_imm_ass_rej(struct osmocom_ms *ms, struct msgb *msg)
2654 struct gsm48_rrlayer *rr = &ms->rrlayer;
2655 struct gsm48_imm_ass_rej *ia = msgb_l3(msg);
2656 int payload_len = msgb_l3len(msg) - sizeof(*ia);
2657 int i;
2658 struct gsm48_req_ref *req_ref;
2659 uint8_t t3122_value;
2661 /* 3.3.1.1.2: ignore assignment while idle */
2662 if (rr->state != GSM48_RR_ST_CONN_PEND || rr->wait_assign == 0)
2663 return 0;
2665 if (rr->wait_assign == 2) {
2666 return 0;
2669 if (payload_len < 0) {
2670 LOGP(DRR, LOGL_NOTICE, "Short read of IMMEDIATE ASSIGNMENT "
2671 "REJECT message.\n");
2672 return -EINVAL;
2675 for (i = 0; i < 4; i++) {
2676 /* request reference */
2677 req_ref = (struct gsm48_req_ref *)
2678 (((uint8_t *)&ia->req_ref1) + i * 4);
2679 LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT REJECT "
2680 "(ref 0x%02x)\n", req_ref->ra);
2681 if (gsm48_match_ra(ms, req_ref)) {
2682 /* wait indication */
2683 t3122_value = *(((uint8_t *)&ia->wait_ind1) + i * 4);
2684 if (t3122_value)
2685 start_rr_t3122(rr, t3122_value, 0);
2686 /* start timer 3126 if not already */
2687 if (!osmo_timer_pending(&rr->t3126))
2688 start_rr_t3126(rr, 5, 0); /* TODO improve! */
2689 /* stop assignmnet requests */
2690 rr->n_chan_req = 0;
2692 /* wait until timer 3126 expires, then release
2693 * or wait for channel assignment */
2694 return 0;
2698 return 0;
2701 /* 9.1.1 ADDITIONAL ASSIGMENT is received */
2702 static int gsm48_rr_rx_add_ass(struct osmocom_ms *ms, struct msgb *msg)
2704 struct gsm48_hdr *gh = msgb_l3(msg);
2705 struct gsm48_add_ass *aa = (struct gsm48_add_ass *)gh->data;
2706 int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*aa);
2707 struct tlv_parsed tp;
2709 if (payload_len < 0) {
2710 LOGP(DRR, LOGL_NOTICE, "Short read of ADDITIONAL ASSIGNMENT "
2711 "message.\n");
2712 return gsm48_rr_tx_rr_status(ms,
2713 GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2715 tlv_parse(&tp, &gsm48_rr_att_tlvdef, aa->data, payload_len, 0, 0);
2717 return gsm48_rr_tx_rr_status(ms, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2721 * measturement reports
2724 static int gsm48_rr_tx_meas_rep(struct osmocom_ms *ms)
2726 struct gsm48_rrlayer *rr = &ms->rrlayer;
2727 struct gsm48_sysinfo *s = ms->cellsel.si;
2728 struct rx_meas_stat *meas = &rr->ms->meas;
2729 struct gsm48_rr_meas *rrmeas = &rr->meas;
2730 struct msgb *nmsg;
2731 struct gsm48_hdr *gh;
2732 struct gsm48_meas_res *mr;
2733 uint8_t serv_rxlev_full = 0, serv_rxlev_sub = 0, serv_rxqual_full = 0,
2734 serv_rxqual_sub = 0;
2735 uint8_t ta, tx_power;
2736 uint8_t rep_ba = 0, rep_valid = 0, meas_valid = 0, multi_rep = 0;
2737 uint8_t n = 0, rxlev_nc[6], bsic_nc[6], bcch_f_nc[6];
2739 /* just in case! */
2740 if (!s)
2741 return -EINVAL;
2743 /* check if SI5* is completely received, check BA-IND */
2744 if (s->si5
2745 && (!s->nb_ext_ind_si5 || s->si5bis)) {
2746 rep_ba = s->nb_ba_ind_si5;
2747 if ((s->si5bis && s->nb_ext_ind_si5
2748 && s->nb_ba_ind_si5bis != rep_ba)
2749 || (s->si5ter && s->nb_ba_ind_si5ter != rep_ba)) {
2750 LOGP(DRR, LOGL_NOTICE, "BA-IND missmatch on SI5*");
2751 } else
2752 rep_valid = 1;
2755 /* check for valid measurements, any frame must exist */
2756 if (meas->frames) {
2757 meas_valid = 1;
2758 serv_rxlev_full = serv_rxlev_sub =
2759 (meas->rxlev + (meas->frames / 2)) / meas->frames;
2760 serv_rxqual_full = serv_rxqual_sub = 0; // FIXME
2763 memset(&rxlev_nc, 0, sizeof(rxlev_nc));
2764 memset(&bsic_nc, 0, sizeof(bsic_nc));
2765 memset(&bcch_f_nc, 0, sizeof(bcch_f_nc));
2766 if (rep_valid) {
2767 int8_t strongest, current;
2768 uint8_t ncc;
2769 int i, index;
2771 /* multiband reporting, if not: 0 = normal reporting */
2772 if (s->si5ter)
2773 multi_rep = s->nb_multi_rep_si5ter;
2775 /* get 6 strongest measurements */
2776 // FIXME: multiband report
2777 strongest = 127; /* infinite */
2778 for (n = 0; n < 6; n++) {
2779 current = -128; /* -infinite */
2780 index = 0;
2781 for (i = 0; i < rrmeas->nc_num; i++) {
2782 /* only check if NCC is permitted */
2783 ncc = rrmeas->nc_bsic[i] >> 3;
2784 if ((s->nb_ncc_permitted_si6 & (1 << ncc))
2785 && rrmeas->nc_rxlev[i] > current
2786 && rrmeas->nc_rxlev[i] < strongest) {
2787 current = rrmeas->nc_rxlev[i];
2788 index = i;
2791 if (current == -128) /* no more found */
2792 break;
2793 rxlev_nc[n] = rrmeas->nc_rxlev[index] + 110;
2794 bsic_nc[n] = rrmeas->nc_bsic[index];
2795 bcch_f_nc[n] = index;
2799 nmsg = gsm48_l3_msgb_alloc();
2800 if (!nmsg)
2801 return -ENOMEM;
2803 /* use indicated tx-power and TA (not the altered ones) */
2804 tx_power = rr->cd_now.ind_tx_power;
2805 // FIXME: degrade power to the max supported level
2806 ta = rr->cd_now.ind_ta;
2808 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
2809 mr = (struct gsm48_meas_res *) msgb_put(nmsg, sizeof(*mr));
2811 gh->proto_discr = GSM48_PDISC_RR;
2812 gh->msg_type = GSM48_MT_RR_MEAS_REP;
2814 /* measurement results */
2815 mr->rxlev_full = serv_rxlev_full;
2816 mr->rxlev_sub = serv_rxlev_sub;
2817 mr->rxqual_full = serv_rxqual_full;
2818 mr->rxqual_sub = serv_rxqual_sub;
2819 mr->dtx_used = 0; // FIXME: no DTX yet
2820 mr->ba_used = rep_ba;
2821 mr->meas_valid = !meas_valid; /* 0 = valid */
2822 if (rep_valid) {
2823 mr->no_nc_n_hi = n >> 2;
2824 mr->no_nc_n_lo = n & 3;
2825 } else {
2826 /* no results for serving cells */
2827 mr->no_nc_n_hi = 1;
2828 mr->no_nc_n_lo = 3;
2830 mr->rxlev_nc1 = rxlev_nc[0];
2831 mr->rxlev_nc2_hi = rxlev_nc[1] >> 1;
2832 mr->rxlev_nc2_lo = rxlev_nc[1] & 1;
2833 mr->rxlev_nc3_hi = rxlev_nc[2] >> 2;
2834 mr->rxlev_nc3_lo = rxlev_nc[2] & 3;
2835 mr->rxlev_nc4_hi = rxlev_nc[3] >> 3;
2836 mr->rxlev_nc4_lo = rxlev_nc[3] & 7;
2837 mr->rxlev_nc5_hi = rxlev_nc[4] >> 4;
2838 mr->rxlev_nc5_lo = rxlev_nc[4] & 15;
2839 mr->rxlev_nc6_hi = rxlev_nc[5] >> 5;
2840 mr->rxlev_nc6_lo = rxlev_nc[5] & 31;
2841 mr->bsic_nc1_hi = bsic_nc[0] >> 3;
2842 mr->bsic_nc1_lo = bsic_nc[0] & 7;
2843 mr->bsic_nc2_hi = bsic_nc[1] >> 4;
2844 mr->bsic_nc2_lo = bsic_nc[1] & 15;
2845 mr->bsic_nc3_hi = bsic_nc[2] >> 5;
2846 mr->bsic_nc3_lo = bsic_nc[2] & 31;
2847 mr->bsic_nc4 = bsic_nc[3];
2848 mr->bsic_nc5 = bsic_nc[4];
2849 mr->bsic_nc6 = bsic_nc[5];
2850 mr->bcch_f_nc1 = bcch_f_nc[0];
2851 mr->bcch_f_nc2 = bcch_f_nc[1];
2852 mr->bcch_f_nc3 = bcch_f_nc[2];
2853 mr->bcch_f_nc4 = bcch_f_nc[3];
2854 mr->bcch_f_nc5_hi = bcch_f_nc[4] >> 1;
2855 mr->bcch_f_nc5_lo = bcch_f_nc[4] & 1;
2856 mr->bcch_f_nc6_hi = bcch_f_nc[5] >> 2;
2857 mr->bcch_f_nc6_lo = bcch_f_nc[5] & 3;
2859 LOGP(DRR, LOGL_INFO, "MEAS REP: pwr=%d TA=%d meas-invalid=%d "
2860 "rxlev-full=%d rxlev-sub=%d rxqual-full=%d rxqual-sub=%d "
2861 "dtx %d ba %d no-ncell-n %d\n", tx_power, ta, mr->meas_valid,
2862 mr->rxlev_full - 110, mr->rxlev_sub - 110,
2863 mr->rxqual_full, mr->rxqual_sub, mr->dtx_used, mr->ba_used,
2864 (mr->no_nc_n_hi << 2) | mr->no_nc_n_lo);
2866 msgb_tv16_push(nmsg, RSL_IE_L3_INFO,
2867 nmsg->tail - (uint8_t *)msgb_l3(nmsg));
2868 msgb_push(nmsg, 2 + 2);
2869 nmsg->data[0] = RSL_IE_TIMING_ADVANCE;
2870 nmsg->data[1] = ta;
2871 nmsg->data[2] = RSL_IE_MS_POWER;
2872 nmsg->data[3] = tx_power;
2873 rsl_rll_push_hdr(nmsg, RSL_MT_UNIT_DATA_REQ, rr->cd_now.chan_nr,
2874 0x40, 1);
2876 return lapdm_rslms_recvmsg(nmsg, &ms->lapdm_channel);
2880 * link establishment and release
2883 /* process "Loss Of Signal" */
2884 int gsm48_rr_los(struct osmocom_ms *ms)
2886 struct gsm48_rrlayer *rr = &ms->rrlayer;
2887 uint8_t *mode;
2888 struct msgb *nmsg;
2889 struct gsm48_rr_hdr *nrrh;
2891 LOGP(DSUM, LOGL_INFO, "Radio link lost signal\n");
2893 /* stop T3211 if running */
2894 stop_rr_t3110(rr);
2896 switch(rr->state) {
2897 case GSM48_RR_ST_CONN_PEND:
2898 LOGP(DRR, LOGL_INFO, "LOS during RACH request\n");
2900 /* stop pending RACH timer */
2901 stop_rr_t3126(rr);
2902 break;
2903 case GSM48_RR_ST_DEDICATED:
2904 LOGP(DRR, LOGL_INFO, "LOS during dedicated mode, release "
2905 "locally\n");
2907 new_rr_state(rr, GSM48_RR_ST_REL_PEND);
2909 /* release message */
2910 rel_local:
2911 nmsg = gsm48_l3_msgb_alloc();
2912 if (!nmsg)
2913 return -ENOMEM;
2914 mode = msgb_put(nmsg, 2);
2915 mode[0] = RSL_IE_RELEASE_MODE;
2916 mode[1] = 1; /* local release */
2917 /* start release */
2918 gsm48_send_rsl_nol3(ms, RSL_MT_REL_REQ, nmsg, 0);
2919 /* release SAPI 3 link, if exits */
2920 gsm48_release_sapi3_link(ms);
2921 return 0;
2922 case GSM48_RR_ST_REL_PEND:
2923 LOGP(DRR, LOGL_INFO, "LOS during RR release procedure, release "
2924 "locally\n");
2926 /* stop pending RACH timer */
2927 stop_rr_t3110(rr);
2929 /* release locally */
2930 goto rel_local;
2931 default:
2932 /* this should not happen */
2933 LOGP(DRR, LOGL_ERROR, "LOS in IDLE state, ignoring\n");
2934 return -EINVAL;
2937 /* send inication to upper layer */
2938 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
2939 if (!nmsg)
2940 return -ENOMEM;
2941 nrrh = (struct gsm48_rr_hdr *)nmsg->data;
2942 nrrh->cause = RR_REL_CAUSE_LOST_SIGNAL;
2943 gsm48_rr_upmsg(ms, nmsg);
2945 /* return idle */
2946 new_rr_state(rr, GSM48_RR_ST_IDLE);
2947 return 0;
2950 /* activation of channel in dedicated mode */
2951 static int gsm48_rr_activate_channel(struct osmocom_ms *ms,
2952 struct gsm48_rr_cd *cd, uint16_t *ma, uint8_t ma_len)
2954 struct gsm_subscriber *subscr = &ms->subscr;
2955 struct gsm48_rrlayer *rr = &ms->rrlayer;
2956 struct gsm_settings *set = &ms->settings;
2957 struct gsm48_sysinfo *s = ms->cellsel.si;
2958 struct rx_meas_stat *meas = &ms->meas;
2959 uint8_t ch_type, ch_subch, ch_ts;
2960 uint8_t timeout = 64;
2962 /* setting (new) timing advance */
2963 LOGP(DRR, LOGL_INFO, "setting indicated TA %d (actual TA %d)\n",
2964 cd->ind_ta, cd->ind_ta - set->alter_delay);
2965 l1ctl_tx_param_req(ms, cd->ind_ta - set->alter_delay,
2966 (set->alter_tx_power) ? set->alter_tx_power_value
2967 : cd->ind_tx_power);
2969 /* reset measurement and link timeout */
2970 meas->ds_fail = 0;
2971 if (s) {
2972 if (s->sacch_radio_link_timeout) {
2973 timeout = s->sacch_radio_link_timeout;
2974 LOGP(DRR, LOGL_INFO, "using last SACCH timeout %d\n",
2975 timeout);
2976 } else if (s->bcch_radio_link_timeout) {
2977 timeout = s->bcch_radio_link_timeout;
2978 LOGP(DRR, LOGL_INFO, "using last BCCH timeout %d\n",
2979 timeout);
2982 meas->rl_fail = meas->s = timeout;
2984 /* setting initial (invalid) measurement report, resetting SI5* */
2985 if (s) {
2986 memset(s->si5_msg, 0, sizeof(s->si5_msg));
2987 memset(s->si5b_msg, 0, sizeof(s->si5b_msg));
2988 memset(s->si5t_msg, 0, sizeof(s->si5t_msg));
2990 meas->frames = meas->snr = meas->berr = meas->rxlev = 0;
2991 rr->meas.nc_num = 0;
2992 stop_rr_t_meas(rr);
2993 start_rr_t_meas(rr, 1, 0);
2994 gsm48_rr_tx_meas_rep(ms);
2996 /* establish */
2997 LOGP(DRR, LOGL_INFO, "establishing channel in dedicated mode\n");
2998 rsl_dec_chan_nr(cd->chan_nr, &ch_type, &ch_subch, &ch_ts);
2999 LOGP(DRR, LOGL_INFO, " Channel type %d, subch %d, ts %d, mode %d, "
3000 "audio-mode %d, cipher %d\n", ch_type, ch_subch, ch_ts,
3001 cd->mode, rr->audio_mode, rr->cipher_type + 1);
3002 if (cd->h)
3003 l1ctl_tx_dm_est_req_h1(ms, cd->maio, cd->hsn,
3004 ma, ma_len, cd->chan_nr, cd->tsc, cd->mode,
3005 rr->audio_mode);
3006 else
3007 l1ctl_tx_dm_est_req_h0(ms, cd->arfcn, cd->chan_nr, cd->tsc,
3008 cd->mode, rr->audio_mode);
3009 rr->dm_est = 1;
3011 /* old SI 5/6 are not valid on a new dedicated channel */
3012 s->si5 = s->si5bis = s->si5ter = s->si6 = 0;
3014 if (rr->cipher_on)
3015 l1ctl_tx_crypto_req(ms, rr->cipher_type + 1, subscr->key, 8);
3017 return 0;
3020 /* frequency change of channel "after time" */
3021 static int gsm48_rr_channel_after_time(struct osmocom_ms *ms,
3022 struct gsm48_rr_cd *cd, uint16_t *ma, uint8_t ma_len, uint16_t fn)
3024 struct gsm_subscriber *subscr = &ms->subscr;
3025 struct gsm48_rrlayer *rr = &ms->rrlayer;
3027 if (cd->h)
3028 l1ctl_tx_dm_freq_req_h1(ms, cd->maio, cd->hsn,
3029 ma, ma_len, cd->tsc, fn);
3030 else
3031 l1ctl_tx_dm_freq_req_h0(ms, cd->arfcn, cd->tsc, fn);
3033 if (rr->cipher_on)
3034 l1ctl_tx_crypto_req(ms, rr->cipher_type + 1, subscr->key, 8);
3036 gsm48_rr_set_mode(ms, cd->chan_nr, cd->mode);
3038 return 0;
3041 /* render list of hopping channels from channel description elements */
3042 static int gsm48_rr_render_ma(struct osmocom_ms *ms, struct gsm48_rr_cd *cd,
3043 uint16_t *ma, uint8_t *ma_len)
3045 struct gsm322_cellsel *cs = &ms->cellsel;
3046 struct gsm48_sysinfo *s = cs->si;
3047 struct gsm_settings *set = &ms->settings;
3048 int i, pcs, index;
3049 uint16_t arfcn;
3051 pcs = gsm_refer_pcs(cs->arfcn, s) ? ARFCN_PCS : 0;
3053 /* no hopping (no MA), channel description is valid */
3054 if (!cd->h) {
3055 *ma_len = 0;
3056 return 0;
3059 /* decode mobile allocation */
3060 if (cd->mob_alloc_lv[0]) {
3061 struct gsm_sysinfo_freq *freq = s->freq;
3063 LOGP(DRR, LOGL_INFO, "decoding mobile allocation\n");
3065 if (cd->cell_desc_lv[0]) {
3066 LOGP(DRR, LOGL_INFO, "using cell channel descr.\n");
3067 if (cd->cell_desc_lv[0] != 16) {
3068 LOGP(DRR, LOGL_ERROR, "cell channel descr. "
3069 "has invalid lenght\n");
3070 return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
3072 gsm48_decode_freq_list(freq, cd->cell_desc_lv + 1, 16,
3073 0xce, FREQ_TYPE_SERV);
3076 gsm48_decode_mobile_alloc(freq, cd->mob_alloc_lv + 1,
3077 cd->mob_alloc_lv[0], ma, ma_len, 0);
3078 if (*ma_len < 1) {
3079 LOGP(DRR, LOGL_NOTICE, "mobile allocation with no "
3080 "frequency available\n");
3081 return GSM48_RR_CAUSE_NO_CELL_ALLOC_A;
3084 } else
3085 /* decode frequency list */
3086 if (cd->freq_list_lv[0]) {
3087 struct gsm_sysinfo_freq f[1024];
3088 int j = 0;
3090 LOGP(DRR, LOGL_INFO, "decoding frequency list\n");
3092 /* get bitmap */
3093 if (gsm48_decode_freq_list(f, cd->freq_list_lv + 1,
3094 cd->freq_list_lv[0], 0xce, FREQ_TYPE_SERV)) {
3095 LOGP(DRR, LOGL_NOTICE, "frequency list invalid\n");
3096 return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
3099 /* collect channels from bitmap (1..1023,0) */
3100 for (i = 1; i <= 1024; i++) {
3101 if ((f[i & 1023].mask & FREQ_TYPE_SERV)) {
3102 LOGP(DRR, LOGL_INFO, "Listed ARFCN #%d: %s\n",
3103 j, gsm_print_arfcn((i & 1023) | pcs));
3104 if (j == 64) {
3105 LOGP(DRR, LOGL_NOTICE, "frequency list "
3106 "exceeds 64 entries!\n");
3107 return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
3109 ma[j++] = i & 1023;
3112 *ma_len = j;
3113 } else
3114 /* decode frequency channel sequence */
3115 if (cd->freq_seq_lv[0]) {
3116 int j = 0, inc;
3118 LOGP(DRR, LOGL_INFO, "decoding frequency channel sequence\n");
3120 if (cd->freq_seq_lv[0] != 9) {
3121 LOGP(DRR, LOGL_NOTICE, "invalid frequency channel "
3122 "sequence\n");
3123 return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
3125 arfcn = cd->freq_seq_lv[1] & 0x7f;
3126 LOGP(DRR, LOGL_INFO, "Listed Sequence ARFCN #%d: %s\n", j,
3127 gsm_print_arfcn(arfcn | pcs));
3128 ma[j++] = arfcn;
3129 for (i = 0; i < 16; i++) {
3130 if ((i & 1))
3131 inc = cd->freq_seq_lv[2 + (i >> 1)] & 0x0f;
3132 else
3133 inc = cd->freq_seq_lv[2 + (i >> 1)] >> 4;
3134 if (inc) {
3135 arfcn += inc;
3136 LOGP(DRR, LOGL_INFO, "Listed Sequence ARFCN "
3137 "#%d: %s\n", j,
3138 gsm_print_arfcn(i | pcs));
3139 ma[j++] = arfcn;
3140 } else
3141 arfcn += 15;
3143 *ma_len = j;
3144 } else {
3145 LOGP(DRR, LOGL_NOTICE, "hopping, but nothing that tells us "
3146 "a sequence\n");
3147 return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
3150 /* convert to band_arfcn and check for unsported frequency */
3151 for (i = 0; i < *ma_len; i++) {
3152 arfcn = ma[i] | pcs;
3153 ma[i] = arfcn;
3154 index = arfcn2index(arfcn);
3155 if (!(set->freq_map[index >> 3] & (1 << (index & 7)))) {
3156 LOGP(DRR, LOGL_NOTICE, "Hopping ARFCN %s not "
3157 "supported\n", gsm_print_arfcn(arfcn));
3158 return GSM48_RR_CAUSE_FREQ_NOT_IMPL;
3162 return 0;
3165 /* activate link and send establish request */
3166 static int gsm48_rr_dl_est(struct osmocom_ms *ms)
3168 struct gsm48_rrlayer *rr = &ms->rrlayer;
3169 struct gsm322_cellsel *cs = &ms->cellsel;
3170 struct gsm_subscriber *subscr = &ms->subscr;
3171 struct msgb *nmsg;
3172 struct gsm48_hdr *gh;
3173 struct gsm48_pag_rsp *pr;
3174 uint8_t mi[11];
3175 uint16_t ma[64];
3176 uint8_t ma_len;
3178 /* 3.3.1.1.3.1 */
3179 stop_rr_t3126(rr);
3181 /* check if we have to change channel at starting time (we delay) */
3182 if (rr->cd_now.start) {
3183 int32_t now, start, diff;
3184 uint32_t start_mili = 0;
3186 /* how much time do we have left? */
3187 now = ms->meas.last_fn % 42432;
3188 start = rr->cd_now.start_tm.fn % 42432;
3189 diff = start - now;
3190 if (diff < 0)
3191 diff += 42432;
3192 LOGP(DRR, LOGL_INFO, " (Tnow %d Tstart %d diff %d)\n",
3193 now, start, diff);
3194 start_mili = (uint32_t)diff * 19580 / 42432 * 10;
3195 if (diff >= 32024 || !start_mili) {
3196 LOGP(DRR, LOGL_INFO, " -> Start time already "
3197 "elapsed\n");
3198 rr->cd_now.start = 0;
3199 } else {
3200 LOGP(DRR, LOGL_INFO, " -> Start time is %d ms in the "
3201 "future\n", start_mili);
3204 #ifndef TEST_FREQUENCY_MOD
3205 /* schedule start of IMM.ASS */
3206 rr->modify_state = GSM48_RR_MOD_IMM_ASS;
3207 start_rr_t_starting(rr, start_mili / 1000,
3208 (start_mili % 1000) * 1000);
3209 /* when timer fires, start time is already elapsed */
3210 rr->cd_now.start = 0;
3212 return 0;
3213 #endif
3216 /* get hopping sequence, if required */
3217 if (gsm48_rr_render_ma(ms, &rr->cd_now, ma, &ma_len))
3218 return -EINVAL;
3220 /* clear all sequence numbers for all possible PDs */
3221 rr->v_sd = 0;
3223 /* send DL_EST_REQ */
3224 if (rr->rr_est_msg) {
3225 LOGP(DRR, LOGL_INFO, "sending establish message\n");
3227 /* use queued message */
3228 nmsg = rr->rr_est_msg;
3229 rr->rr_est_msg = 0;
3231 /* set sequence number and increment */
3232 gsm48_apply_v_sd(rr, nmsg);
3233 } else {
3234 /* create paging response */
3235 nmsg = gsm48_l3_msgb_alloc();
3236 if (!nmsg)
3237 return -ENOMEM;
3238 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
3239 gh->proto_discr = GSM48_PDISC_RR;
3240 gh->msg_type = GSM48_MT_RR_PAG_RESP;
3241 pr = (struct gsm48_pag_rsp *) msgb_put(nmsg, sizeof(*pr));
3242 /* key sequence */
3243 pr->key_seq = gsm_subscr_get_key_seq(ms, subscr);
3244 /* classmark 2 */
3245 pr->cm2_len = sizeof(pr->cm2);
3246 gsm48_rr_enc_cm2(ms, &pr->cm2, rr->cd_now.arfcn);
3247 /* mobile identity */
3248 if (ms->subscr.tmsi != 0xffffffff
3249 && ms->subscr.mcc == cs->sel_mcc
3250 && ms->subscr.mnc == cs->sel_mnc
3251 && ms->subscr.lac == cs->sel_lac
3252 && rr->paging_mi_type == GSM_MI_TYPE_TMSI) {
3253 gsm48_generate_mid_from_tmsi(mi, subscr->tmsi);
3254 LOGP(DRR, LOGL_INFO, "sending paging response with "
3255 "TMSI\n");
3256 } else if (subscr->imsi[0]) {
3257 gsm48_generate_mid_from_imsi(mi, subscr->imsi);
3258 LOGP(DRR, LOGL_INFO, "sending paging response with "
3259 "IMSI\n");
3260 } else {
3261 mi[1] = 1;
3262 mi[2] = 0xf0 | GSM_MI_TYPE_NONE;
3263 LOGP(DRR, LOGL_INFO, "sending paging response without "
3264 "TMSI/IMSI\n");
3266 msgb_put(nmsg, 1 + mi[1]);
3267 memcpy(pr->data, mi + 1, 1 + mi[1]);
3270 #ifdef TEST_FREQUENCY_MOD
3271 LOGP(DRR, LOGL_INFO, " TESTING: frequency modify IMM.ASS\n");
3272 memcpy(&rr->cd_before, &rr->cd_now, sizeof(rr->cd_before));
3273 rr->cd_before.h = 0;
3274 rr->cd_before.arfcn = 0;
3275 /* activate channel */
3276 gsm48_rr_activate_channel(ms, &rr->cd_before, ma, ma_len);
3277 /* render channel "after time" */
3278 gsm48_rr_render_ma(ms, &rr->cd_now, ma, &ma_len);
3279 /* schedule change of channel */
3280 gsm48_rr_channel_after_time(ms, &rr->cd_now, ma, ma_len,
3281 rr->cd_now.start_tm.fn);
3282 #else
3283 /* activate channel */
3284 gsm48_rr_activate_channel(ms, &rr->cd_now, ma, ma_len);
3285 #endif
3287 /* set T200 of SAPI 0 */
3288 ms->lapdm_channel.lapdm_dcch.datalink[DL_SAPI0].dl.t200_sec =
3289 T200_DCCH;
3290 ms->lapdm_channel.lapdm_dcch.datalink[DL_SAPI0].dl.t200_usec = 0;
3292 /* start establishmnet */
3293 return gsm48_send_rsl(ms, RSL_MT_EST_REQ, nmsg, 0);
3296 /* the link is established */
3297 static int gsm48_rr_estab_cnf(struct osmocom_ms *ms, struct msgb *msg)
3299 struct gsm48_rrlayer *rr = &ms->rrlayer;
3300 uint8_t *mode;
3301 struct msgb *nmsg;
3303 /* if MM has releases before confirm, we start release */
3304 if (rr->state == GSM48_RR_ST_REL_PEND) {
3305 LOGP(DRR, LOGL_INFO, "MM already released RR.\n");
3306 /* release message */
3307 nmsg = gsm48_l3_msgb_alloc();
3308 if (!nmsg)
3309 return -ENOMEM;
3310 mode = msgb_put(nmsg, 2);
3311 mode[0] = RSL_IE_RELEASE_MODE;
3312 mode[1] = 0; /* normal release */
3313 /* start release */
3314 return gsm48_send_rsl_nol3(ms, RSL_MT_REL_REQ, nmsg, 0);
3317 /* 3.3.1.1.4 */
3318 new_rr_state(rr, GSM48_RR_ST_DEDICATED);
3320 /* send confirm to upper layer */
3321 nmsg = gsm48_rr_msgb_alloc(
3322 (rr->rr_est_req) ? GSM48_RR_EST_CNF : GSM48_RR_EST_IND);
3323 if (!nmsg)
3324 return -ENOMEM;
3325 return gsm48_rr_upmsg(ms, nmsg);
3328 /* the link is released in pending state (by l2) */
3329 static int gsm48_rr_rel_ind(struct osmocom_ms *ms, struct msgb *msg)
3331 struct gsm48_rrlayer *rr = &ms->rrlayer;
3332 struct msgb *nmsg;
3333 struct gsm48_rr_hdr *nrrh;
3335 /* switch back to old channel, if modify/ho failed */
3336 switch (rr->modify_state) {
3337 case GSM48_RR_MOD_ASSIGN:
3338 case GSM48_RR_MOD_HANDO:
3339 /* channel is deactivate there */
3340 return gsm48_rr_rel_cnf(ms, msg);
3341 case GSM48_RR_MOD_ASSIGN_RESUME:
3342 case GSM48_RR_MOD_HANDO_RESUME:
3343 rr->modify_state = GSM48_RR_MOD_NONE;
3344 break;
3347 LOGP(DSUM, LOGL_INFO, "Radio link is released\n");
3349 /* send inication to upper layer */
3350 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
3351 if (!nmsg)
3352 return -ENOMEM;
3353 nrrh = (struct gsm48_rr_hdr *)nmsg->data;
3354 nrrh->cause = RR_REL_CAUSE_NORMAL;
3355 gsm48_rr_upmsg(ms, nmsg);
3357 /* start release timer, so UA will be transmitted */
3358 start_rr_t_rel_wait(rr, 1, 500000);
3360 /* pending release */
3361 new_rr_state(rr, GSM48_RR_ST_REL_PEND);
3363 /* also release SAPI 3 link, if exists */
3364 gsm48_release_sapi3_link(ms);
3366 return 0;
3369 /* 9.1.7 CHANNEL RELEASE is received */
3370 static int gsm48_rr_rx_chan_rel(struct osmocom_ms *ms, struct msgb *msg)
3372 struct gsm48_rrlayer *rr = &ms->rrlayer;
3373 struct gsm48_hdr *gh = msgb_l3(msg);
3374 struct gsm48_chan_rel *cr = (struct gsm48_chan_rel *)gh->data;
3375 int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*cr);
3376 struct tlv_parsed tp;
3377 struct msgb *nmsg;
3378 uint8_t *mode;
3380 if (payload_len < 0) {
3381 LOGP(DRR, LOGL_NOTICE, "Short read of CHANNEL RELEASE "
3382 "message.\n");
3383 return gsm48_rr_tx_rr_status(ms,
3384 GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
3386 tlv_parse(&tp, &gsm48_rr_att_tlvdef, cr->data, payload_len, 0, 0);
3388 LOGP(DRR, LOGL_INFO, "channel release request with cause 0x%02x\n",
3389 cr->rr_cause);
3391 /* BA range */
3392 if (TLVP_PRESENT(&tp, GSM48_IE_BA_RANGE)) {
3393 gsm48_decode_ba_range(TLVP_VAL(&tp, GSM48_IE_BA_RANGE),
3394 *(TLVP_VAL(&tp, GSM48_IE_BA_RANGE) - 1), rr->ba_range,
3395 &rr->ba_ranges,
3396 sizeof(rr->ba_range) / sizeof(rr->ba_range[0]));
3397 /* NOTE: the ranges are kept until IDLE state is returned
3398 * (see new_rr_state)
3402 new_rr_state(rr, GSM48_RR_ST_REL_PEND);
3404 /* start T3110, so that two DISCs can be sent due to T200 timeout */
3405 start_rr_t3110(rr, 1, 500000);
3407 /* disconnect the main signalling link */
3408 nmsg = gsm48_l3_msgb_alloc();
3409 if (!nmsg)
3410 return -ENOMEM;
3411 mode = msgb_put(nmsg, 2);
3412 mode[0] = RSL_IE_RELEASE_MODE;
3413 mode[1] = 0; /* normal release */
3414 gsm48_send_rsl_nol3(ms, RSL_MT_REL_REQ, nmsg, 0);
3416 /* release SAPI 3 link, if exits */
3417 gsm48_release_sapi3_link(ms);
3418 return 0;
3422 * frequency redefition, chanel mode modify, assignment, and handover
3425 /* set channel mode in case of TCH */
3426 static int gsm48_rr_set_mode(struct osmocom_ms *ms, uint8_t chan_nr,
3427 uint8_t mode)
3429 struct gsm48_rrlayer *rr = &ms->rrlayer;
3430 uint8_t ch_type, ch_subch, ch_ts;
3432 /* only apply mode to TCH/F or TCH/H */
3433 rsl_dec_chan_nr(chan_nr, &ch_type, &ch_subch, &ch_ts);
3434 if (ch_type != RSL_CHAN_Bm_ACCHs
3435 && ch_type != RSL_CHAN_Lm_ACCHs)
3436 return -ENOTSUP;
3438 /* setting (new) timing advance */
3439 LOGP(DRR, LOGL_INFO, "setting TCH mode to %d, audio mode to %d\n",
3440 mode, rr->audio_mode);
3441 l1ctl_tx_tch_mode_req(ms, mode, rr->audio_mode);
3443 return 0;
3446 /* 9.1.13 FREQUENCY REDEFINITION is received */
3447 static int gsm48_rr_rx_frq_redef(struct osmocom_ms *ms, struct msgb *msg)
3449 struct gsm48_rrlayer *rr = &ms->rrlayer;
3450 struct gsm322_cellsel *cs = &ms->cellsel;
3451 struct gsm48_sysinfo *s = cs->si;
3452 struct gsm48_frq_redef *fr = msgb_l3(msg);
3453 int mob_al_len = msgb_l3len(msg) - sizeof(*fr);
3454 uint8_t ch_type, ch_subch, ch_ts;
3455 struct gsm48_rr_cd cd;
3456 uint8_t cause;
3457 uint8_t *st;
3458 uint16_t ma[64];
3459 uint8_t ma_len;
3461 memcpy(&cd, &rr->cd_now, sizeof(cd));
3463 if (mob_al_len < 0 /* mobile allocation IE must be included */
3464 || fr->mob_alloc_len + 2 > mob_al_len) { /* short read of IE */
3465 LOGP(DRR, LOGL_NOTICE, "Short read of FREQUENCY REDEFINITION "
3466 "message.\n");
3467 return -EINVAL;
3469 if (fr->mob_alloc_len > 8) {
3470 LOGP(DRR, LOGL_NOTICE, "Moble allocation in FREQUENCY "
3471 "REDEFINITION too large.\n");
3472 return -EINVAL;
3475 /* decode channel description */
3476 LOGP(DRR, LOGL_INFO, "FREQUENCY REDEFINITION:\n");
3477 cd.chan_nr = fr->chan_desc.chan_nr;
3478 rsl_dec_chan_nr(cd.chan_nr, &ch_type, &ch_subch, &ch_ts);
3479 if (fr->chan_desc.h0.h) {
3480 cd.h = 1;
3481 gsm48_decode_chan_h1(&fr->chan_desc, &cd.tsc, &cd.maio,
3482 &cd.hsn);
3483 LOGP(DRR, LOGL_INFO, " (MAIO %u HSN %u TS %u SS %u TSC %u)\n",
3484 cd.maio, cd.hsn, ch_ts, ch_subch, cd.tsc);
3485 } else {
3486 cd.h = 0;
3487 gsm48_decode_chan_h0(&fr->chan_desc, &cd.tsc, &cd.arfcn);
3488 if (gsm_refer_pcs(cs->arfcn, s))
3489 cd.arfcn |= ARFCN_PCS;
3490 LOGP(DRR, LOGL_INFO, " (ARFCN %s TS %u SS %u TSC %u)\n",
3491 gsm_print_arfcn(cd.arfcn), ch_ts, ch_subch, cd.tsc);
3494 /* mobile allocation */
3495 memcpy(rr->cd_now.mob_alloc_lv, &fr->mob_alloc_len,
3496 fr->mob_alloc_len + 1);
3498 /* starting time */
3499 st = fr->mob_alloc + fr->mob_alloc_len;
3500 gsm48_decode_start_time(&cd, (struct gsm48_start_time *)(st+1));
3502 /* cell channel description */
3503 if (mob_al_len >= fr->mob_alloc_len + 2 + 17
3504 && fr->mob_alloc[fr->mob_alloc_len + 2] == GSM48_IE_CELL_CH_DESC) {
3505 const uint8_t *v = fr->mob_alloc + fr->mob_alloc_len + 2 + 1;
3507 LOGP(DRR, LOGL_INFO, " using cell channel description)\n");
3508 cd.cell_desc_lv[0] = 16;
3509 memcpy(cd.cell_desc_lv + 1, v, 17);
3512 /* render channel "after time" */
3513 cause = gsm48_rr_render_ma(ms, &rr->cd_now, ma, &ma_len);
3514 if (cause)
3515 return gsm48_rr_tx_rr_status(ms, cause);
3517 /* update to new channel data */
3518 memcpy(&rr->cd_now, &cd, sizeof(rr->cd_now));
3520 /* schedule change of channel */
3521 gsm48_rr_channel_after_time(ms, &rr->cd_now, ma, ma_len,
3522 rr->cd_now.start_tm.fn);
3524 rr->cd_now.start = 0;
3526 return 0;
3529 /* 9.1.6 sending CHANNEL MODE MODIFY ACKNOWLEDGE */
3530 static int gsm48_rr_tx_chan_modify_ack(struct osmocom_ms *ms,
3531 struct gsm48_chan_desc *cd, uint8_t mode)
3533 struct msgb *nmsg;
3534 struct gsm48_hdr *gh;
3535 struct gsm48_chan_mode_modify *cm;
3537 LOGP(DRR, LOGL_INFO, "CHAN.MODE.MOD ACKNOWLEDGE\n");
3539 nmsg = gsm48_l3_msgb_alloc();
3540 if (!nmsg)
3541 return -ENOMEM;
3542 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
3543 cm = (struct gsm48_chan_mode_modify *) msgb_put(nmsg, sizeof(*cm));
3545 gh->proto_discr = GSM48_PDISC_RR;
3546 gh->msg_type = GSM48_MT_RR_CHAN_MODE_MODIF_ACK;
3548 /* CD */
3549 memcpy(&cm->chan_desc, cd, sizeof(struct gsm48_chan_desc));
3550 /* mode */
3551 cm->mode = mode;
3553 return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg, 0);
3556 /* 9.1.5 CHANNEL MODE MODIFY is received */
3557 static int gsm48_rr_rx_chan_modify(struct osmocom_ms *ms, struct msgb *msg)
3559 struct gsm48_rrlayer *rr = &ms->rrlayer;
3560 struct gsm322_cellsel *cs = &ms->cellsel;
3561 struct gsm48_sysinfo *s = cs->si;
3562 struct gsm48_hdr *gh = msgb_l3(msg);
3563 struct gsm48_chan_mode_modify *cm =
3564 (struct gsm48_chan_mode_modify *)gh->data;
3565 int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*cm);
3566 struct gsm48_rr_cd *cd = &rr->cd_now;
3567 uint8_t ch_type, ch_subch, ch_ts;
3568 uint8_t cause;
3570 LOGP(DRR, LOGL_INFO, "CHANNEL MODE MODIFY\n");
3573 if (payload_len < 0) {
3574 LOGP(DRR, LOGL_NOTICE, "Short read of CHANNEL MODE MODIFY "
3575 "message.\n");
3576 return gsm48_rr_tx_rr_status(ms,
3577 GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
3580 /* decode channel description */
3581 cd->chan_nr = cm->chan_desc.chan_nr;
3582 rsl_dec_chan_nr(cd->chan_nr, &ch_type, &ch_subch, &ch_ts);
3583 if (cm->chan_desc.h0.h) {
3584 cd->h = 1;
3585 gsm48_decode_chan_h1(&cm->chan_desc, &cd->tsc, &cd->maio,
3586 &cd->hsn);
3587 LOGP(DRR, LOGL_INFO, " (chan_nr 0x%02x MAIO %u HSN %u TS %u "
3588 "SS %u TSC %u mode %u)\n", cm->chan_desc.chan_nr,
3589 cd->maio, cd->hsn, ch_ts, ch_subch, cd->tsc, cm->mode);
3590 } else {
3591 cd->h = 0;
3592 gsm48_decode_chan_h0(&cm->chan_desc, &cd->tsc, &cd->arfcn);
3593 if (gsm_refer_pcs(cs->arfcn, s))
3594 cd->arfcn |= ARFCN_PCS;
3595 LOGP(DRR, LOGL_INFO, " (chan_nr 0x%02x ARFCN %s TS %u SS %u "
3596 "TSC %u mode %u)\n", cm->chan_desc.chan_nr,
3597 gsm_print_arfcn(cd->arfcn), ch_ts, ch_subch, cd->tsc,
3598 cm->mode);
3600 /* mode */
3601 cause = gsm48_rr_check_mode(ms, cd->chan_nr, cm->mode);
3602 if (cause)
3603 return gsm48_rr_tx_rr_status(ms, cause);
3604 cd->mode = cm->mode;
3605 gsm48_rr_set_mode(ms, cd->chan_nr, cd->mode);
3607 return gsm48_rr_tx_chan_modify_ack(ms, &cm->chan_desc, cm->mode);
3610 /* 9.1.3 sending ASSIGNMENT COMPLETE */
3611 static int gsm48_rr_tx_ass_cpl(struct osmocom_ms *ms, uint8_t cause)
3613 struct msgb *nmsg;
3614 struct gsm48_hdr *gh;
3615 struct gsm48_ass_cpl *ac;
3617 LOGP(DRR, LOGL_INFO, "ASSIGNMENT COMPLETE (cause #%d)\n", cause);
3619 nmsg = gsm48_l3_msgb_alloc();
3620 if (!nmsg)
3621 return -ENOMEM;
3622 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
3623 ac = (struct gsm48_ass_cpl *) msgb_put(nmsg, sizeof(*ac));
3625 gh->proto_discr = GSM48_PDISC_RR;
3626 gh->msg_type = GSM48_MT_RR_ASS_COMPL;
3628 /* RR_CAUSE */
3629 ac->rr_cause = cause;
3631 /* set T200 of SAPI 0 */
3632 ms->lapdm_channel.lapdm_dcch.datalink[DL_SAPI0].dl.t200_sec =
3633 T200_DCCH;
3634 ms->lapdm_channel.lapdm_dcch.datalink[DL_SAPI0].dl.t200_usec = 0;
3636 return gsm48_send_rsl(ms, RSL_MT_RES_REQ, nmsg, 0);
3639 /* 9.1.4 sending ASSIGNMENT FAILURE */
3640 static int gsm48_rr_tx_ass_fail(struct osmocom_ms *ms, uint8_t cause,
3641 uint8_t rsl_prim)
3643 struct msgb *nmsg;
3644 struct gsm48_hdr *gh;
3645 struct gsm48_ass_fail *af;
3647 LOGP(DRR, LOGL_INFO, "ASSIGNMENT FAILURE (cause #%d)\n", cause);
3649 nmsg = gsm48_l3_msgb_alloc();
3650 if (!nmsg)
3651 return -ENOMEM;
3652 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
3653 af = (struct gsm48_ass_fail *) msgb_put(nmsg, sizeof(*af));
3655 gh->proto_discr = GSM48_PDISC_RR;
3656 gh->msg_type = GSM48_MT_RR_ASS_COMPL;
3658 /* RR_CAUSE */
3659 af->rr_cause = cause;
3661 return gsm48_send_rsl(ms, rsl_prim, nmsg, 0);
3664 /* 9.1.2 ASSIGNMENT COMMAND is received */
3665 static int gsm48_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg)
3667 struct gsm48_rrlayer *rr = &ms->rrlayer;
3668 struct gsm322_cellsel *cs = &ms->cellsel;
3669 struct gsm48_sysinfo *s = cs->si;
3670 struct gsm48_hdr *gh = msgb_l3(msg);
3671 struct gsm48_ass_cmd *ac = (struct gsm48_ass_cmd *)gh->data;
3672 int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*ac);
3673 struct tlv_parsed tp;
3674 struct gsm48_rr_cd *cda = &rr->cd_after;
3675 struct gsm48_rr_cd *cdb = &rr->cd_before;
3676 uint8_t ch_type, ch_subch, ch_ts;
3677 uint8_t before_time = 0;
3678 uint16_t ma[64];
3679 uint8_t ma_len;
3680 uint32_t start_mili = 0;
3681 uint8_t cause;
3682 struct msgb *nmsg;
3685 LOGP(DRR, LOGL_INFO, "ASSIGNMENT COMMAND\n");
3687 memset(cda, 0, sizeof(*cda));
3688 cda->ind_tx_power = rr->cd_now.ind_tx_power;
3689 memset(cdb, 0, sizeof(*cdb));
3690 cdb->ind_tx_power = rr->cd_now.ind_tx_power;
3692 if (payload_len < 0) {
3693 LOGP(DRR, LOGL_NOTICE, "Short read of ASSIGNMENT COMMAND "
3694 "message.\n");
3695 return gsm48_rr_tx_rr_status(ms,
3696 GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
3698 tlv_parse(&tp, &gsm48_rr_att_tlvdef, ac->data, payload_len, 0, 0);
3700 /* decode channel description (before time) */
3701 if (TLVP_PRESENT(&tp, GSM48_IE_CH_DESC_1_BEFORE)) {
3702 struct gsm48_chan_desc *ccd = (struct gsm48_chan_desc *)
3703 TLVP_VAL(&tp, GSM48_IE_CH_DESC_1_BEFORE);
3704 cdb->chan_nr = ccd->chan_nr;
3705 rsl_dec_chan_nr(cdb->chan_nr, &ch_type, &ch_subch, &ch_ts);
3706 if (ccd->h0.h) {
3707 cdb->h = 1;
3708 gsm48_decode_chan_h1(ccd, &cdb->tsc, &cdb->maio,
3709 &cdb->hsn);
3710 LOGP(DRR, LOGL_INFO, " before: (chan_nr 0x%02x MAIO %u "
3711 "HSN %u TS %u SS %u TSC %u)\n", ccd->chan_nr,
3712 cdb->maio, cdb->hsn, ch_ts, ch_subch, cdb->tsc);
3713 } else {
3714 cdb->h = 0;
3715 gsm48_decode_chan_h0(ccd, &cdb->tsc, &cdb->arfcn);
3716 if (gsm_refer_pcs(cs->arfcn, s))
3717 cdb->arfcn |= ARFCN_PCS;
3718 LOGP(DRR, LOGL_INFO, " before: (chan_nr 0x%02x "
3719 "ARFCN %s TS %u SS %u TSC %u)\n", ccd->chan_nr,
3720 gsm_print_arfcn(cdb->arfcn),
3721 ch_ts, ch_subch, cdb->tsc);
3723 before_time = 1;
3726 /* decode channel description (after time) */
3727 cda->chan_nr = ac->chan_desc.chan_nr;
3728 rsl_dec_chan_nr(cda->chan_nr, &ch_type, &ch_subch, &ch_ts);
3729 if (ac->chan_desc.h0.h) {
3730 cda->h = 1;
3731 gsm48_decode_chan_h1(&ac->chan_desc, &cda->tsc, &cda->maio,
3732 &cda->hsn);
3733 LOGP(DRR, LOGL_INFO, " after: (chan_nr 0x%02x MAIO %u HSN %u "
3734 "TS %u SS %u TSC %u)\n", ac->chan_desc.chan_nr,
3735 cda->maio, cda->hsn, ch_ts, ch_subch, cda->tsc);
3736 } else {
3737 cda->h = 0;
3738 gsm48_decode_chan_h0(&ac->chan_desc, &cda->tsc, &cda->arfcn);
3739 if (gsm_refer_pcs(cs->arfcn, s))
3740 cda->arfcn |= ARFCN_PCS;
3741 LOGP(DRR, LOGL_INFO, " after: (chan_nr 0x%02x ARFCN %s TS %u "
3742 "SS %u TSC %u)\n", ac->chan_desc.chan_nr,
3743 gsm_print_arfcn(cda->arfcn), ch_ts, ch_subch, cda->tsc);
3746 /* starting time */
3747 #ifdef TEST_STARTING_TIMER
3748 cda->start = 1;
3749 cda->start_tm.fn = (ms->meas.last_fn + TEST_STARTING_TIMER) % 42432;
3750 LOGP(DRR, LOGL_INFO, " TESTING: starting time ahead\n");
3751 #else
3752 if (TLVP_PRESENT(&tp, GSM48_IE_START_TIME)) {
3753 gsm48_decode_start_time(cda, (struct gsm48_start_time *)
3754 TLVP_VAL(&tp, GSM48_IE_START_TIME));
3755 /* 9.1.2.5 "... before time IE is not present..." */
3756 if (!before_time) {
3757 LOGP(DRR, LOGL_INFO, " -> channel description after "
3758 "time only, but starting time\n");
3759 } else
3760 LOGP(DRR, LOGL_INFO, " -> channel description before "
3761 "and after time\n");
3762 } else {
3763 /* 9.1.2.5 "... IEs unnecessary in this message." */
3764 if (before_time) {
3765 before_time = 0;
3766 LOGP(DRR, LOGL_INFO, " -> channel description before "
3767 "time, but no starting time, ignoring!\n");
3770 #endif
3772 /* mobile allocation / frequency list after time */
3773 if (cda->h) {
3774 if (TLVP_PRESENT(&tp, GSM48_IE_MA_AFTER)) {
3775 const uint8_t *lv =
3776 TLVP_VAL(&tp, GSM48_IE_MA_AFTER) - 1;
3778 LOGP(DRR, LOGL_INFO, " after: hopping required and "
3779 "mobile allocation available\n");
3780 if (*lv + 1 > sizeof(cda->mob_alloc_lv)) {
3781 LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
3782 return -ENOMEM;
3784 memcpy(cda->mob_alloc_lv, lv, *lv + 1);
3785 } else
3786 if (TLVP_PRESENT(&tp, GSM48_IE_FREQ_L_AFTER)) {
3787 const uint8_t *lv =
3788 TLVP_VAL(&tp, GSM48_IE_FREQ_L_AFTER) - 1;
3790 LOGP(DRR, LOGL_INFO, " after: hopping required and "
3791 "frequency list available\n");
3792 if (*lv + 1 > sizeof(cda->freq_list_lv)) {
3793 LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
3794 return -ENOMEM;
3796 memcpy(cda->freq_list_lv, lv, *lv + 1);
3797 } else {
3798 LOGP(DRR, LOGL_NOTICE, " after: hopping required, but "
3799 "no mobile allocation / frequency list\n");
3803 /* mobile allocation / frequency list before time */
3804 if (cdb->h) {
3805 if (TLVP_PRESENT(&tp, GSM48_IE_MA_BEFORE)) {
3806 const uint8_t *lv =
3807 TLVP_VAL(&tp, GSM48_IE_MA_BEFORE) - 1;
3809 LOGP(DRR, LOGL_INFO, " before: hopping required and "
3810 "mobile allocation available\n");
3811 if (*lv + 1 > sizeof(cdb->mob_alloc_lv)) {
3812 LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
3813 return -ENOMEM;
3815 memcpy(cdb->mob_alloc_lv, lv, *lv + 1);
3816 } else
3817 if (TLVP_PRESENT(&tp, GSM48_IE_FREQ_L_BEFORE)) {
3818 const uint8_t *lv =
3819 TLVP_VAL(&tp, GSM48_IE_FREQ_L_BEFORE) - 1;
3821 LOGP(DRR, LOGL_INFO, " before: hopping required and "
3822 "frequency list available\n");
3823 if (*lv + 1 > sizeof(cdb->freq_list_lv)) {
3824 LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
3825 return -ENOMEM;
3827 memcpy(cdb->freq_list_lv, lv, *lv + 1);
3828 } else
3829 if (TLVP_PRESENT(&tp, GSM48_IE_F_CH_SEQ_BEFORE)) {
3830 const uint8_t *v =
3831 TLVP_VAL(&tp, GSM48_IE_F_CH_SEQ_BEFORE);
3832 uint8_t len = TLVP_LEN(&tp, GSM48_IE_F_CH_SEQ_BEFORE);
3834 LOGP(DRR, LOGL_INFO, " before: hopping required and "
3835 "frequency channel sequence available\n");
3836 if (len + 1 > sizeof(cdb->freq_seq_lv)) {
3837 LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
3838 return -ENOMEM;
3840 cdb->freq_seq_lv[0] = len;
3841 memcpy(cdb->freq_seq_lv + 1, v, len);
3842 } else
3843 if (cda->mob_alloc_lv[0]) {
3844 LOGP(DRR, LOGL_INFO, " before: hopping required and "
3845 "mobile allocation not available, using "
3846 "mobile allocation after time\n");
3847 memcpy(cdb->mob_alloc_lv, cda->mob_alloc_lv,
3848 sizeof(cdb->mob_alloc_lv));
3849 } else
3850 if (cda->freq_list_lv[0]) {
3851 LOGP(DRR, LOGL_INFO, " before: hopping required and "
3852 "frequency list not available, using "
3853 "frequency list after time\n");
3854 memcpy(cdb->freq_list_lv, cda->freq_list_lv,
3855 sizeof(cdb->freq_list_lv));
3856 } else {
3857 LOGP(DRR, LOGL_NOTICE, " before: hopping required, but "
3858 "no mobile allocation / frequency list\n");
3862 /* cell channel description */
3863 if (TLVP_PRESENT(&tp, GSM48_IE_CELL_CH_DESC)) {
3864 const uint8_t *v = TLVP_VAL(&tp, GSM48_IE_CELL_CH_DESC);
3865 uint8_t len = TLVP_LEN(&tp, GSM48_IE_CELL_CH_DESC);
3867 LOGP(DRR, LOGL_INFO, " both: using cell channel description "
3868 "in case of mobile allocation\n");
3869 if (len + 1 > sizeof(cdb->cell_desc_lv)) {
3870 LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
3871 return -ENOMEM;
3873 cdb->cell_desc_lv[0] = len;
3874 memcpy(cdb->cell_desc_lv + 1, v, len);
3875 cda->cell_desc_lv[0] = len;
3876 memcpy(cda->cell_desc_lv + 1, v, len);
3877 } else {
3878 /* keep old */
3879 memcpy(cdb->cell_desc_lv, rr->cd_now.cell_desc_lv,
3880 sizeof(cdb->cell_desc_lv));
3881 memcpy(cda->cell_desc_lv, rr->cd_now.cell_desc_lv,
3882 sizeof(cda->cell_desc_lv));
3885 /* channel mode */
3886 if (TLVP_PRESENT(&tp, GSM48_IE_CHANMODE_1)) {
3887 cda->mode = cdb->mode = *TLVP_VAL(&tp, GSM48_IE_CHANMODE_1);
3888 LOGP(DRR, LOGL_INFO, " both: changing channel mode 0x%02x\n",
3889 cda->mode);
3890 } else
3891 cda->mode = cdb->mode = rr->cd_now.mode;
3893 /* cipher mode setting */
3894 if (TLVP_PRESENT(&tp, GSM48_IE_CIP_MODE_SET)) {
3895 cda->cipher = cdb->cipher =
3896 *TLVP_VAL(&tp, GSM48_IE_CIP_MODE_SET);
3897 LOGP(DRR, LOGL_INFO, " both: changing cipher mode 0x%02x\n",
3898 cda->cipher);
3899 } else
3900 cda->cipher = cdb->cipher = rr->cd_now.cipher;
3902 /* power command and TA (before and after time) */
3903 gsm48_decode_power_cmd_acc(
3904 (struct gsm48_power_cmd *) &ac->power_command,
3905 &cda->ind_tx_power, NULL);
3906 cdb->ind_tx_power = cda->ind_tx_power;
3907 cda->ind_ta = cdb->ind_ta = rr->cd_now.ind_ta; /* same cell */
3908 LOGP(DRR, LOGL_INFO, " both: (tx_power %d TA %d)\n", cda->ind_tx_power,
3909 cda->ind_ta);
3911 /* check if we have to change channel at starting time */
3912 if (cda->start) {
3913 int32_t now, start, diff;
3915 /* how much time do we have left? */
3916 now = ms->meas.last_fn % 42432;
3917 start = cda->start_tm.fn % 42432;
3918 diff = start - now;
3919 if (diff < 0)
3920 diff += 42432;
3921 LOGP(DRR, LOGL_INFO, " after: (Tnow %d Tstart %d diff %d)\n",
3922 now, start, diff);
3923 start_mili = (uint32_t)diff * 19580 / 42432 * 10;
3924 if (diff >= 32024 || !start_mili) {
3925 LOGP(DRR, LOGL_INFO, " -> Start time already "
3926 "elapsed\n");
3927 before_time = 0;
3928 cda->start = 0;
3929 } else {
3930 LOGP(DRR, LOGL_INFO, " -> Start time is %d ms in the "
3931 "future\n", start_mili);
3935 /* check if channels are valid */
3936 cause = gsm48_rr_check_mode(ms, cda->chan_nr, cda->mode);
3937 if (cause)
3938 return gsm48_rr_tx_ass_fail(ms, cause, RSL_MT_DATA_REQ);
3939 if (before_time) {
3940 cause = gsm48_rr_render_ma(ms, cdb, ma, &ma_len);
3941 if (cause)
3942 return gsm48_rr_tx_ass_fail(ms, cause, RSL_MT_DATA_REQ);
3944 cause = gsm48_rr_render_ma(ms, cda, ma, &ma_len);
3945 if (cause)
3946 return gsm48_rr_tx_ass_fail(ms, cause, RSL_MT_DATA_REQ);
3948 #ifdef TEST_FREQUENCY_MOD
3949 LOGP(DRR, LOGL_INFO, " TESTING: frequency modify ASS.CMD\n");
3950 before_time = 1;
3951 memcpy(cdb, cda, sizeof(*cdb));
3952 cdb->h = 0;
3953 cdb->arfcn = 0;
3954 #endif
3956 /* schedule start of assignment */
3957 rr->modify_state = GSM48_RR_MOD_ASSIGN;
3958 if (!before_time && cda->start) {
3959 start_rr_t_starting(rr, start_mili / 1000, start_mili % 1000);
3960 /* when timer fires, start time is already elapsed */
3961 cda->start = 0;
3963 return 0;
3966 /* if no starting time, start suspension of current link directly */
3967 LOGP(DRR, LOGL_INFO, "request suspension of data link\n");
3968 nmsg = gsm48_l3_msgb_alloc();
3969 if (!nmsg)
3970 return -ENOMEM;
3971 gsm48_send_rsl(ms, RSL_MT_SUSP_REQ, nmsg, 0);
3973 /* release SAPI 3 link, if exits
3974 * FIXME: suspend and resume afterward */
3975 gsm48_release_sapi3_link(ms);
3977 return 0;
3980 /* 9.1.16 sending HANDOVER COMPLETE */
3981 static int gsm48_rr_tx_hando_cpl(struct osmocom_ms *ms, uint8_t cause)
3983 struct msgb *nmsg;
3984 struct gsm48_hdr *gh;
3985 struct gsm48_ho_cpl *hc;
3987 LOGP(DRR, LOGL_INFO, "HANDOVER COMPLETE (cause #%d)\n", cause);
3989 nmsg = gsm48_l3_msgb_alloc();
3990 if (!nmsg)
3991 return -ENOMEM;
3992 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
3993 hc = (struct gsm48_ho_cpl *) msgb_put(nmsg, sizeof(*hc));
3995 gh->proto_discr = GSM48_PDISC_RR;
3996 gh->msg_type = GSM48_MT_RR_HANDO_COMPL;
3998 /* RR_CAUSE */
3999 hc->rr_cause = cause;
4001 // FIXME: mobile observed time
4003 /* set T200 of SAPI 0 */
4004 ms->lapdm_channel.lapdm_dcch.datalink[DL_SAPI0].dl.t200_sec =
4005 T200_DCCH;
4006 ms->lapdm_channel.lapdm_dcch.datalink[DL_SAPI0].dl.t200_usec = 0;
4008 return gsm48_send_rsl(ms, RSL_MT_RES_REQ, nmsg, 0);
4011 /* 9.1.4 sending HANDOVER FAILURE */
4012 static int gsm48_rr_tx_hando_fail(struct osmocom_ms *ms, uint8_t cause,
4013 uint8_t rsl_prim)
4015 struct msgb *nmsg;
4016 struct gsm48_hdr *gh;
4017 struct gsm48_ho_fail *hf;
4019 LOGP(DRR, LOGL_INFO, "HANDOVER FAILURE (cause #%d)\n", cause);
4021 nmsg = gsm48_l3_msgb_alloc();
4022 if (!nmsg)
4023 return -ENOMEM;
4024 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
4025 hf = (struct gsm48_ho_fail *) msgb_put(nmsg, sizeof(*hf));
4027 gh->proto_discr = GSM48_PDISC_RR;
4028 gh->msg_type = GSM48_MT_RR_ASS_COMPL;
4030 /* RR_CAUSE */
4031 hf->rr_cause = cause;
4033 return gsm48_send_rsl(ms, rsl_prim, nmsg, 0);
4036 /* receiving HANDOVER COMMAND message (9.1.15) */
4037 static int gsm48_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg)
4039 struct gsm48_rrlayer *rr = &ms->rrlayer;
4040 struct gsm322_cellsel *cs = &ms->cellsel;
4041 struct gsm48_sysinfo *s = cs->si;
4042 struct gsm48_hdr *gh = msgb_l3(msg);
4043 struct gsm48_ho_cmd *ho = (struct gsm48_ho_cmd *)gh->data;
4044 int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*ho);
4045 struct tlv_parsed tp;
4046 struct gsm48_rr_cd *cda = &rr->cd_after;
4047 struct gsm48_rr_cd *cdb = &rr->cd_before;
4048 uint16_t arfcn;
4049 uint8_t bcc, ncc;
4050 uint8_t ch_type, ch_subch, ch_ts;
4051 uint8_t before_time = 0;
4052 uint16_t ma[64];
4053 uint8_t ma_len;
4054 uint32_t start_mili = 0;
4055 uint8_t cause;
4056 struct msgb *nmsg;
4058 LOGP(DRR, LOGL_INFO, "HANDOVER COMMAND\n");
4060 memset(cda, 0, sizeof(*cda));
4061 cda->ind_tx_power = rr->cd_now.ind_tx_power;
4062 memset(cdb, 0, sizeof(*cdb));
4063 cdb->ind_tx_power = rr->cd_now.ind_tx_power;
4065 if (payload_len < 0) {
4066 LOGP(DRR, LOGL_NOTICE, "Short read of HANDOVER COMMAND "
4067 "message.\n");
4068 return gsm48_rr_tx_rr_status(ms,
4069 GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
4072 /* cell description */
4073 gsm48_decode_cell_desc(&ho->cell_desc, &arfcn, &ncc, &bcc);
4075 /* handover reference */
4076 rr->chan_req_val = ho->ho_ref;
4077 rr->chan_req_mask = 0x00;
4079 tlv_parse(&tp, &gsm48_rr_att_tlvdef, ho->data, payload_len, 0, 0);
4081 /* sync ind */
4082 if (TLVP_PRESENT(&tp, GSM48_IE_SYNC_IND)) {
4083 gsm48_decode_sync_ind(rr, (struct gsm48_sync_ind *)
4084 TLVP_VAL(&tp, GSM48_IE_SYNC_IND));
4085 LOGP(DRR, LOGL_INFO, " (sync_ind=%d rot=%d nci=%d)\n",
4086 rr->hando_sync_ind, rr->hando_rot, rr->hando_nci);
4089 /* decode channel description (before time) */
4090 if (TLVP_PRESENT(&tp, GSM48_IE_CH_DESC_1_BEFORE)) {
4091 struct gsm48_chan_desc *ccd = (struct gsm48_chan_desc *)
4092 TLVP_VAL(&tp, GSM48_IE_CH_DESC_1_BEFORE);
4093 cdb->chan_nr = ccd->chan_nr;
4094 rsl_dec_chan_nr(cdb->chan_nr, &ch_type, &ch_subch, &ch_ts);
4095 if (ccd->h0.h) {
4096 cdb->h = 1;
4097 gsm48_decode_chan_h1(ccd, &cdb->tsc, &cdb->maio,
4098 &cdb->hsn);
4099 LOGP(DRR, LOGL_INFO, " before: (chan_nr 0x%02x MAIO %u "
4100 "HSN %u TS %u SS %u TSC %u)\n", ccd->chan_nr,
4101 cdb->maio, cdb->hsn, ch_ts, ch_subch, cdb->tsc);
4102 } else {
4103 cdb->h = 0;
4104 gsm48_decode_chan_h0(ccd, &cdb->tsc, &cdb->arfcn);
4105 if (gsm_refer_pcs(cs->arfcn, s))
4106 cdb->arfcn |= ARFCN_PCS;
4107 LOGP(DRR, LOGL_INFO, " before: (chan_nr 0x%02x "
4108 "ARFCN %s TS %u SS %u TSC %u)\n", ccd->chan_nr,
4109 gsm_print_arfcn(cdb->arfcn),
4110 ch_ts, ch_subch, cdb->tsc);
4112 before_time = 1;
4115 /* decode channel description (after time) */
4116 cda->chan_nr = ho->chan_desc.chan_nr;
4117 rsl_dec_chan_nr(cda->chan_nr, &ch_type, &ch_subch, &ch_ts);
4118 if (ho->chan_desc.h0.h) {
4119 cda->h = 1;
4120 gsm48_decode_chan_h1(&ho->chan_desc, &cda->tsc, &cda->maio,
4121 &cda->hsn);
4122 LOGP(DRR, LOGL_INFO, " after: (chan_nr 0x%02x MAIO %u HSN %u "
4123 "TS %u SS %u TSC %u)\n", ho->chan_desc.chan_nr,
4124 cda->maio, cda->hsn, ch_ts, ch_subch, cda->tsc);
4125 } else {
4126 cda->h = 0;
4127 gsm48_decode_chan_h0(&ho->chan_desc, &cda->tsc, &cda->arfcn);
4128 if (gsm_refer_pcs(cs->arfcn, s))
4129 cda->arfcn |= ARFCN_PCS;
4130 LOGP(DRR, LOGL_INFO, " after: (chan_nr 0x%02x ARFCN %s TS %u "
4131 "SS %u TSC %u)\n", ho->chan_desc.chan_nr,
4132 gsm_print_arfcn(cda->arfcn), ch_ts, ch_subch, cda->tsc);
4135 /* starting time */
4136 #ifdef TEST_STARTING_TIMER
4137 cda->start = 1;
4138 cda->start_tm.fn = (ms->meas.last_fn + TEST_STARTING_TIMER) % 42432;
4139 LOGP(DRR, LOGL_INFO, " TESTING: starting time ahead\n");
4140 #else
4141 if (TLVP_PRESENT(&tp, GSM48_IE_START_TIME)) {
4142 gsm48_decode_start_time(cda, (struct gsm48_start_time *)
4143 TLVP_VAL(&tp, GSM48_IE_START_TIME));
4144 /* 9.1.2.5 "... before time IE is not present..." */
4145 if (!before_time) {
4146 LOGP(DRR, LOGL_INFO, " -> channel description after "
4147 "time only, but starting time\n");
4148 } else
4149 LOGP(DRR, LOGL_INFO, " -> channel description before "
4150 "and after time\n");
4151 } else {
4152 /* 9.1.2.5 "... IEs unnecessary in this message." */
4153 if (before_time) {
4154 before_time = 0;
4155 LOGP(DRR, LOGL_INFO, " -> channel description before "
4156 "time, but no starting time, ignoring!\n");
4159 #endif
4161 /* mobile allocation / frequency list after time */
4162 if (cda->h) {
4163 if (TLVP_PRESENT(&tp, GSM48_IE_MA_AFTER)) {
4164 const uint8_t *lv =
4165 TLVP_VAL(&tp, GSM48_IE_MA_AFTER) - 1;
4167 LOGP(DRR, LOGL_INFO, " after: hopping required and "
4168 "mobile allocation available\n");
4169 if (*lv + 1 > sizeof(cda->mob_alloc_lv)) {
4170 LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
4171 return -ENOMEM;
4173 memcpy(cda->mob_alloc_lv, lv, *lv + 1);
4174 } else
4175 if (TLVP_PRESENT(&tp, GSM48_IE_FREQ_L_AFTER)) {
4176 const uint8_t *lv =
4177 TLVP_VAL(&tp, GSM48_IE_FREQ_L_AFTER) - 1;
4179 LOGP(DRR, LOGL_INFO, " after: hopping required and "
4180 "frequency list available\n");
4181 if (*lv + 1 > sizeof(cda->freq_list_lv)) {
4182 LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
4183 return -ENOMEM;
4185 memcpy(cda->freq_list_lv, lv, *lv + 1);
4186 } else {
4187 LOGP(DRR, LOGL_NOTICE, " after: hopping required, but "
4188 "no mobile allocation / frequency list\n");
4192 /* mobile allocation / frequency list before time */
4193 if (cdb->h) {
4194 if (TLVP_PRESENT(&tp, GSM48_IE_MA_BEFORE)) {
4195 const uint8_t *lv =
4196 TLVP_VAL(&tp, GSM48_IE_MA_BEFORE) - 1;
4198 LOGP(DRR, LOGL_INFO, " before: hopping required and "
4199 "mobile allocation available\n");
4200 if (*lv + 1 > sizeof(cdb->mob_alloc_lv)) {
4201 LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
4202 return -ENOMEM;
4204 memcpy(cdb->mob_alloc_lv, lv, *lv + 1);
4205 } else
4206 if (TLVP_PRESENT(&tp, GSM48_IE_FREQ_L_BEFORE)) {
4207 const uint8_t *lv =
4208 TLVP_VAL(&tp, GSM48_IE_FREQ_L_BEFORE) - 1;
4210 LOGP(DRR, LOGL_INFO, " before: hopping required and "
4211 "frequency list available\n");
4212 if (*lv + 1 > sizeof(cdb->freq_list_lv)) {
4213 LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
4214 return -ENOMEM;
4216 memcpy(cdb->freq_list_lv, lv, *lv + 1);
4217 } else
4218 if (TLVP_PRESENT(&tp, GSM48_IE_F_CH_SEQ_BEFORE)) {
4219 const uint8_t *v =
4220 TLVP_VAL(&tp, GSM48_IE_F_CH_SEQ_BEFORE);
4221 uint8_t len = TLVP_LEN(&tp, GSM48_IE_F_CH_SEQ_BEFORE);
4223 LOGP(DRR, LOGL_INFO, " before: hopping required and "
4224 "frequency channel sequence available\n");
4225 if (len + 1 > sizeof(cdb->freq_seq_lv)) {
4226 LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
4227 return -ENOMEM;
4229 cdb->freq_seq_lv[0] = len;
4230 memcpy(cdb->freq_seq_lv, v + 1, *v);
4231 } else
4232 if (cda->mob_alloc_lv[0]) {
4233 LOGP(DRR, LOGL_INFO, " before: hopping required and "
4234 "mobile allocation not available, using "
4235 "mobile allocation after time\n");
4236 memcpy(cdb->mob_alloc_lv, cda->mob_alloc_lv,
4237 sizeof(cdb->mob_alloc_lv));
4238 } else
4239 if (cda->freq_list_lv[0]) {
4240 LOGP(DRR, LOGL_INFO, " before: hopping required and "
4241 "frequency list not available, using "
4242 "frequency list after time\n");
4243 memcpy(cdb->freq_list_lv, cda->freq_list_lv,
4244 sizeof(cdb->freq_list_lv));
4245 } else {
4246 LOGP(DRR, LOGL_NOTICE, " before: hopping required, but "
4247 "no mobile allocation / frequency list\n");
4251 /* cell channel description */
4252 if (TLVP_PRESENT(&tp, GSM48_IE_CELL_CH_DESC)) {
4253 const uint8_t *v = TLVP_VAL(&tp, GSM48_IE_CELL_CH_DESC);
4254 uint8_t len = TLVP_LEN(&tp, GSM48_IE_CELL_CH_DESC);
4256 LOGP(DRR, LOGL_INFO, " both: using cell channel description "
4257 "in case of mobile allocation\n");
4258 if (len + 1 > sizeof(cdb->cell_desc_lv)) {
4259 LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
4260 return -ENOMEM;
4262 cdb->cell_desc_lv[0] = len;
4263 memcpy(cdb->cell_desc_lv + 1, v, len);
4264 cda->cell_desc_lv[0] = len;
4265 memcpy(cda->cell_desc_lv + 1, v, len);
4266 } else {
4267 /* keep old */
4268 memcpy(cdb->cell_desc_lv, rr->cd_now.cell_desc_lv,
4269 sizeof(cdb->cell_desc_lv));
4270 memcpy(cda->cell_desc_lv, rr->cd_now.cell_desc_lv,
4271 sizeof(cda->cell_desc_lv));
4274 /* channel mode */
4275 if (TLVP_PRESENT(&tp, GSM48_IE_CHANMODE_1)) {
4276 cda->mode = cdb->mode = *TLVP_VAL(&tp, GSM48_IE_CHANMODE_1);
4277 LOGP(DRR, LOGL_INFO, " both: changing channel mode 0x%02x\n",
4278 cda->mode);
4279 } else
4280 cda->mode = cdb->mode = rr->cd_now.mode;
4282 /* cipher mode setting */
4283 if (TLVP_PRESENT(&tp, GSM48_IE_CIP_MODE_SET)) {
4284 cda->cipher = cdb->cipher =
4285 *TLVP_VAL(&tp, GSM48_IE_CIP_MODE_SET);
4286 LOGP(DRR, LOGL_INFO, " both: changing cipher mode 0x%02x\n",
4287 cda->cipher);
4288 } else
4289 cda->cipher = cdb->cipher = rr->cd_now.cipher;
4291 /* power command and TA (before and after time) */
4292 gsm48_decode_power_cmd_acc(
4293 (struct gsm48_power_cmd *) &ho->power_command,
4294 &cda->ind_tx_power, &rr->hando_act);
4295 cdb->ind_tx_power = cda->ind_tx_power;
4296 cda->ind_ta = cdb->ind_ta = rr->cd_now.ind_ta; /* same cell */
4297 LOGP(DRR, LOGL_INFO, " both: (tx_power %d TA %d access=%s)\n",
4298 cda->ind_tx_power, cda->ind_ta,
4299 (rr->hando_act) ? "optional" : "mandatory");
4301 /* check if we have to change channel at starting time */
4302 if (cda->start) {
4303 int32_t now, start, diff;
4305 /* how much time do we have left? */
4306 now = ms->meas.last_fn % 42432;
4307 start = cda->start_tm.fn % 42432;
4308 diff = start - now;
4309 if (diff < 0)
4310 diff += 42432;
4311 LOGP(DRR, LOGL_INFO, " after: (Tnow %d Tstart %d diff %d)\n",
4312 now, start, diff);
4313 start_mili = (uint32_t)diff * 19580 / 42432 * 10;
4314 if (diff >= 32024 || !start_mili) {
4315 LOGP(DRR, LOGL_INFO, " -> Start time already "
4316 "elapsed\n");
4317 before_time = 0;
4318 cda->start = 0;
4319 } else {
4320 LOGP(DRR, LOGL_INFO, " -> Start time is %d ms in the "
4321 "future\n", start_mili);
4325 /* check if channels are valid */
4326 if (before_time) {
4327 cause = gsm48_rr_render_ma(ms, cdb, ma, &ma_len);
4328 if (cause)
4329 return gsm48_rr_tx_hando_fail(ms, cause, RSL_MT_DATA_REQ);
4331 cause = gsm48_rr_render_ma(ms, cda, ma, &ma_len);
4332 if (cause)
4333 return gsm48_rr_tx_hando_fail(ms, cause, RSL_MT_DATA_REQ);
4336 #if 0
4337 if (not supported) {
4338 LOGP(DRR, LOGL_NOTICE, "New channel is not supported.\n");
4339 return GSM48_RR_CAUSE_CHAN_MODE_UNACCEPT;
4341 #endif
4343 #ifdef TEST_FREQUENCY_MOD
4344 LOGP(DRR, LOGL_INFO, " TESTING: frequency modify HANDO.CMD\n");
4345 before_time = 1;
4346 memcpy(cdb, cda, sizeof(*cdb));
4347 cdb->h = 0;
4348 cdb->arfcn = 0;
4349 #endif
4351 /* schedule start of handover */
4352 rr->modify_state = GSM48_RR_MOD_HANDO;
4353 if (!before_time && cda->start) {
4354 start_rr_t_starting(rr, start_mili / 1000, start_mili % 1000);
4355 /* when timer fires, start time is already elapsed */
4356 cda->start = 0;
4358 return 0;
4361 /* if no starting time, start suspension of current link directly */
4362 LOGP(DRR, LOGL_INFO, "request suspension of data link\n");
4363 nmsg = gsm48_l3_msgb_alloc();
4364 if (!nmsg)
4365 return -ENOMEM;
4366 gsm48_send_rsl(ms, RSL_MT_SUSP_REQ, nmsg, 0);
4368 /* release SAPI 3 link, if exits
4369 * FIXME: suspend and resume afterward */
4370 gsm48_release_sapi3_link(ms);
4372 return 0;
4375 /* send all queued messages down to layer 2 */
4376 static int gsm48_rr_dequeue_down(struct osmocom_ms *ms)
4378 struct gsm48_rrlayer *rr = &ms->rrlayer;
4379 struct msgb *msg;
4381 while((msg = msgb_dequeue(&rr->downqueue))) {
4382 struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *) msg->data;
4383 uint8_t sapi = rrh->sapi;
4385 LOGP(DRR, LOGL_INFO, "Sending queued message.\n");
4386 if (sapi && rr->sapi3_state != GSM48_RR_SAPI3ST_ESTAB) {
4387 LOGP(DRR, LOGL_INFO, "Dropping SAPI 3 msg, no link!\n");
4388 msgb_free(msg);
4389 return 0;
4391 gsm48_send_rsl(ms, RSL_MT_DATA_REQ, msg, 0);
4394 return 0;
4397 /* channel is resumed in dedicated mode */
4398 static int gsm48_rr_estab_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
4400 struct gsm48_rrlayer *rr = &ms->rrlayer;
4402 LOGP(DRR, LOGL_INFO, "data link is resumed\n");
4404 /* transmit queued frames during ho / ass transition */
4405 gsm48_rr_dequeue_down(ms);
4407 rr->modify_state = GSM48_RR_MOD_NONE;
4409 return 0;
4412 /* suspend confirm in dedicated mode */
4413 static int gsm48_rr_susp_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
4415 struct gsm48_rrlayer *rr = &ms->rrlayer;
4417 if (rr->modify_state) {
4418 uint16_t ma[64];
4419 uint8_t ma_len;
4421 /* deactivating dedicated mode */
4422 LOGP(DRR, LOGL_INFO, "suspension coplete, leaving dedicated "
4423 "mode\n");
4424 l1ctl_tx_dm_rel_req(ms);
4425 ms->meas.rl_fail = 0;
4426 rr->dm_est = 0;
4427 l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED);
4429 /* store current channel descriptions */
4430 memcpy(&rr->cd_last, &rr->cd_now, sizeof(rr->cd_last));
4432 /* copy channel description "after time" */
4433 memcpy(&rr->cd_now, &rr->cd_after, sizeof(rr->cd_now));
4435 if (rr->cd_after.start) {
4436 /* render channel "before time" */
4437 gsm48_rr_render_ma(ms, &rr->cd_before, ma, &ma_len);
4439 /* activate channel */
4440 gsm48_rr_activate_channel(ms, &rr->cd_before, ma,
4441 ma_len);
4443 /* render channel "after time" */
4444 gsm48_rr_render_ma(ms, &rr->cd_now, ma, &ma_len);
4446 /* schedule change of channel */
4447 gsm48_rr_channel_after_time(ms, &rr->cd_now, ma, ma_len,
4448 rr->cd_now.start_tm.fn);
4449 } else {
4450 /* render channel "after time" */
4451 gsm48_rr_render_ma(ms, &rr->cd_now, ma, &ma_len);
4453 /* activate channel */
4454 gsm48_rr_activate_channel(ms, &rr->cd_now, ma, ma_len);
4457 /* send DL-RESUME REQUEST */
4458 LOGP(DRR, LOGL_INFO, "request resume of data link\n");
4459 switch (rr->modify_state) {
4460 case GSM48_RR_MOD_ASSIGN:
4461 gsm48_rr_tx_ass_cpl(ms, GSM48_RR_CAUSE_NORMAL);
4462 break;
4463 case GSM48_RR_MOD_HANDO:
4464 gsm48_rr_tx_hando_cpl(ms, GSM48_RR_CAUSE_NORMAL);
4465 break;
4468 #ifdef TODO
4469 /* trigger RACH */
4470 if (rr->modify_state == GSM48_RR_MOD_HANDO) {
4471 gsm48_rr_tx_hando_access(ms);
4472 rr->hando_acc_left = 3;
4474 #endif
4476 return 0;
4480 * radio ressource requests
4483 /* establish request for dedicated mode */
4484 static int gsm48_rr_est_req(struct osmocom_ms *ms, struct msgb *msg)
4486 struct gsm48_rrlayer *rr = &ms->rrlayer;
4487 struct gsm322_cellsel *cs = &ms->cellsel;
4488 struct gsm48_sysinfo *s = &cs->sel_si;
4489 struct gsm_subscriber *subscr = &ms->subscr;
4490 struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *) msg->data;
4491 struct gsm48_hdr *gh = msgb_l3(msg);
4492 uint8_t cause;
4493 struct msgb *nmsg;
4494 struct gsm48_rr_hdr *nrrh;
4495 uint16_t acc_class;
4497 /* 3.3.1.1.3.2 */
4498 if (osmo_timer_pending(&rr->t3122)) {
4499 if (rrh->cause != RR_EST_CAUSE_EMERGENCY) {
4500 LOGP(DRR, LOGL_INFO, "T3122 running, rejecting!\n");
4501 cause = RR_REL_CAUSE_T3122;
4502 reject:
4503 LOGP(DSUM, LOGL_INFO, "Establishing radio link not "
4504 "possible\n");
4505 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
4506 if (!nmsg)
4507 return -ENOMEM;
4508 nrrh = (struct gsm48_rr_hdr *)nmsg->data;
4509 nrrh->cause = cause;
4510 return gsm48_rr_upmsg(ms, nmsg);
4512 LOGP(DRR, LOGL_INFO, "T3122 running, but emergency call\n");
4513 stop_rr_t3122(rr);
4516 /* if state is not idle */
4517 if (rr->state != GSM48_RR_ST_IDLE) {
4518 LOGP(DRR, LOGL_INFO, "We are not IDLE yet, rejecting!\n");
4519 cause = RR_REL_CAUSE_TRY_LATER;
4520 goto reject;
4523 /* cell selected */
4524 if (!cs->selected) {
4525 LOGP(DRR, LOGL_INFO, "No cell selected, rejecting!\n");
4526 cause = RR_REL_CAUSE_TRY_LATER;
4527 goto reject;
4530 /* check if camping */
4531 if (cs->state != GSM322_C3_CAMPED_NORMALLY
4532 && rrh->cause != RR_EST_CAUSE_EMERGENCY) {
4533 LOGP(DRR, LOGL_INFO, "Not camping normally, rejecting! "
4534 "(cs->state = %d)\n", cs->state);
4535 cause = RR_REL_CAUSE_EMERGENCY_ONLY;
4536 goto reject;
4538 if (cs->state != GSM322_C3_CAMPED_NORMALLY
4539 && cs->state != GSM322_C7_CAMPED_ANY_CELL) {
4540 LOGP(DRR, LOGL_INFO, "Not camping, rejecting! "
4541 "(cs->state = %d)\n", cs->state);
4542 cause = RR_REL_CAUSE_TRY_LATER;
4543 goto reject;
4546 /* check for relevant informations */
4547 if (!s->si3) {
4548 LOGP(DRR, LOGL_INFO, "Not enough SI, rejecting!\n");
4549 cause = RR_REL_CAUSE_TRY_LATER;
4550 goto reject;
4553 /* 3.3.1.1.1 */
4554 if (!subscr->acc_barr && s->cell_barr) {
4555 LOGP(DRR, LOGL_INFO, "Cell barred, rejecting!\n");
4556 cause = RR_REL_CAUSE_NOT_AUTHORIZED;
4557 goto reject;
4559 if (rrh->cause == RR_EST_CAUSE_EMERGENCY)
4560 acc_class = subscr->acc_class | 0x0400;
4561 else
4562 acc_class = subscr->acc_class & 0xfbff;
4563 if (!subscr->acc_barr && !(acc_class & (s->class_barr ^ 0xffff))) {
4564 LOGP(DRR, LOGL_INFO, "Cell barred for our access class (access "
4565 "%04x barred %04x)!\n", acc_class, s->class_barr);
4566 cause = RR_REL_CAUSE_NOT_AUTHORIZED;
4567 goto reject;
4570 /* requested by RR */
4571 rr->rr_est_req = 1;
4573 /* clone and store REQUEST message */
4574 if (!gh) {
4575 LOGP(DRR, LOGL_ERROR, "Error, missing l3 message\n");
4576 return -EINVAL;
4578 rr->rr_est_msg = gsm48_l3_msgb_alloc();
4579 if (!rr->rr_est_msg)
4580 return -ENOMEM;
4581 memcpy(msgb_put(rr->rr_est_msg, msgb_l3len(msg)),
4582 msgb_l3(msg), msgb_l3len(msg));
4584 /* request channel */
4585 return gsm48_rr_chan_req(ms, rrh->cause, 0, 0);
4588 /* 3.4.2 transfer data in dedicated mode */
4589 static int gsm48_rr_data_req(struct osmocom_ms *ms, struct msgb *msg)
4591 struct gsm48_rrlayer *rr = &ms->rrlayer;
4592 struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *) msg->data;
4593 uint8_t sapi = rrh->sapi;
4595 if (rr->state != GSM48_RR_ST_DEDICATED) {
4596 msgb_free(msg);
4597 return -EINVAL;
4600 /* pull RR header */
4601 msgb_pull(msg, sizeof(struct gsm48_rr_hdr));
4603 /* set sequence number and increment */
4604 gsm48_apply_v_sd(rr, msg);
4606 /* queue message, during handover or assignment procedure */
4607 if (rr->modify_state == GSM48_RR_MOD_ASSIGN
4608 || rr->modify_state == GSM48_RR_MOD_HANDO) {
4609 LOGP(DRR, LOGL_INFO, "Queueing message during suspend.\n");
4610 msgb_enqueue(&rr->downqueue, msg);
4611 return 0;
4614 if (sapi && rr->sapi3_state != GSM48_RR_SAPI3ST_ESTAB) {
4615 LOGP(DRR, LOGL_INFO, "Dropping SAPI 3 msg, no link!\n");
4616 msgb_free(msg);
4617 return 0;
4620 /* forward message */
4621 return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, msg,
4622 sapi ? rr->sapi3_link_id : 0);
4626 * data indications from data link
4629 /* 3.4.2 data from layer 2 to RR and upper layer*/
4630 static int gsm48_rr_data_ind(struct osmocom_ms *ms, struct msgb *msg)
4632 struct gsm48_hdr *gh = msgb_l3(msg);
4633 struct gsm48_rr_hdr *rrh;
4634 uint8_t pdisc = gh->proto_discr & 0x0f;
4636 if (pdisc == GSM48_PDISC_RR) {
4637 int rc = -EINVAL;
4638 uint8_t skip_ind = (gh->proto_discr & 0xf0) >> 4;
4640 /* ignore if skip indicator is not B'0000' */
4641 if (skip_ind)
4642 return 0;
4644 switch(gh->msg_type) {
4645 case GSM48_MT_RR_ADD_ASS:
4646 rc = gsm48_rr_rx_add_ass(ms, msg);
4647 break;
4648 case GSM48_MT_RR_ASS_CMD:
4649 rc = gsm48_rr_rx_ass_cmd(ms, msg);
4650 break;
4651 case GSM48_MT_RR_CIPH_M_CMD:
4652 rc = gsm48_rr_rx_cip_mode_cmd(ms, msg);
4653 break;
4654 case GSM48_MT_RR_CLSM_ENQ:
4655 rc = gsm48_rr_rx_cm_enq(ms, msg);
4656 break;
4657 case GSM48_MT_RR_CHAN_MODE_MODIF:
4658 rc = gsm48_rr_rx_chan_modify(ms, msg);
4659 break;
4660 case GSM48_MT_RR_HANDO_CMD:
4661 rc = gsm48_rr_rx_hando_cmd(ms, msg);
4662 break;
4663 case GSM48_MT_RR_FREQ_REDEF:
4664 rc = gsm48_rr_rx_frq_redef(ms, msg);
4665 break;
4666 case GSM48_MT_RR_CHAN_REL:
4667 rc = gsm48_rr_rx_chan_rel(ms, msg);
4668 break;
4669 case GSM48_MT_RR_APP_INFO:
4670 LOGP(DRR, LOGL_NOTICE, "APP INFO not supported!\n");
4671 break;
4672 default:
4673 LOGP(DRR, LOGL_NOTICE, "Message type 0x%02x unknown.\n",
4674 gh->msg_type);
4676 /* status message */
4677 gsm48_rr_tx_rr_status(ms, GSM48_RR_CAUSE_MSG_TYPE_N);
4680 msgb_free(msg);
4681 return rc;
4684 /* pull off RSL header up to L3 message */
4685 msgb_pull(msg, (long)msgb_l3(msg) - (long)msg->data);
4687 /* push RR header */
4688 msgb_push(msg, sizeof(struct gsm48_rr_hdr));
4689 rrh = (struct gsm48_rr_hdr *)msg->data;
4690 rrh->msg_type = GSM48_RR_DATA_IND;
4692 return gsm48_rr_upmsg(ms, msg);
4695 /* receive BCCH at RR layer */
4696 static int gsm48_rr_rx_bcch(struct osmocom_ms *ms, struct msgb *msg)
4698 struct gsm48_system_information_type_header *sih = msgb_l3(msg);
4700 switch (sih->system_information) {
4701 case GSM48_MT_RR_SYSINFO_1:
4702 return gsm48_rr_rx_sysinfo1(ms, msg);
4703 case GSM48_MT_RR_SYSINFO_2:
4704 return gsm48_rr_rx_sysinfo2(ms, msg);
4705 case GSM48_MT_RR_SYSINFO_2bis:
4706 return gsm48_rr_rx_sysinfo2bis(ms, msg);
4707 case GSM48_MT_RR_SYSINFO_2ter:
4708 return gsm48_rr_rx_sysinfo2ter(ms, msg);
4709 case GSM48_MT_RR_SYSINFO_3:
4710 return gsm48_rr_rx_sysinfo3(ms, msg);
4711 case GSM48_MT_RR_SYSINFO_4:
4712 return gsm48_rr_rx_sysinfo4(ms, msg);
4713 default:
4714 #if 0
4715 LOGP(DRR, LOGL_NOTICE, "BCCH message type 0x%02x not sup.\n",
4716 sih->system_information);
4717 #endif
4718 return -EINVAL;
4722 /* receive CCCH at RR layer */
4723 static int gsm48_rr_rx_pch_agch(struct osmocom_ms *ms, struct msgb *msg)
4725 struct gsm48_system_information_type_header *sih = msgb_l3(msg);
4727 switch (sih->system_information) {
4728 case GSM48_MT_RR_PAG_REQ_1:
4729 return gsm48_rr_rx_pag_req_1(ms, msg);
4730 case GSM48_MT_RR_PAG_REQ_2:
4731 return gsm48_rr_rx_pag_req_2(ms, msg);
4732 case GSM48_MT_RR_PAG_REQ_3:
4733 return gsm48_rr_rx_pag_req_3(ms, msg);
4735 case GSM48_MT_RR_IMM_ASS:
4736 return gsm48_rr_rx_imm_ass(ms, msg);
4737 case GSM48_MT_RR_IMM_ASS_EXT:
4738 return gsm48_rr_rx_imm_ass_ext(ms, msg);
4739 case GSM48_MT_RR_IMM_ASS_REJ:
4740 return gsm48_rr_rx_imm_ass_rej(ms, msg);
4741 default:
4742 #if 0
4743 LOGP(DRR, LOGL_NOTICE, "CCCH message type 0x%02x unknown.\n",
4744 sih->system_information);
4745 #endif
4746 return -EINVAL;
4750 /* receive ACCH at RR layer */
4751 static int gsm48_rr_rx_acch(struct osmocom_ms *ms, struct msgb *msg)
4753 struct gsm48_rrlayer *rr = &ms->rrlayer;
4754 struct gsm_settings *set = &ms->settings;
4755 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
4756 struct gsm48_system_information_type_header *sih = msgb_l3(msg);
4757 uint8_t ind_ta, ind_tx_power;
4759 if (msgb_l2len(msg) < sizeof(*rllh) + 2 + 2) {
4760 LOGP(DRR, LOGL_ERROR, "Missing TA and TX_POWER IEs\n");
4761 return -EINVAL;
4764 ind_ta = rllh->data[1];
4765 ind_tx_power = rllh->data[3];
4766 LOGP(DRR, LOGL_INFO, "Indicated ta %d (actual ta %d)\n",
4767 ind_ta, ind_ta - set->alter_delay);
4768 LOGP(DRR, LOGL_INFO, "Indicated tx_power %d\n",
4769 ind_tx_power);
4770 if (ind_ta != rr->cd_now.ind_ta
4771 || ind_tx_power != rr->cd_now.ind_tx_power) {
4772 LOGP(DRR, LOGL_INFO, "setting new ta and tx_power\n");
4773 l1ctl_tx_param_req(ms, ind_ta - set->alter_delay,
4774 (set->alter_tx_power) ? set->alter_tx_power_value
4775 : ind_tx_power);
4776 rr->cd_now.ind_ta = ind_ta;
4777 rr->cd_now.ind_tx_power = ind_tx_power;
4780 switch (sih->system_information) {
4781 case GSM48_MT_RR_SYSINFO_5:
4782 return gsm48_rr_rx_sysinfo5(ms, msg);
4783 case GSM48_MT_RR_SYSINFO_5bis:
4784 return gsm48_rr_rx_sysinfo5bis(ms, msg);
4785 case GSM48_MT_RR_SYSINFO_5ter:
4786 return gsm48_rr_rx_sysinfo5ter(ms, msg);
4787 case GSM48_MT_RR_SYSINFO_6:
4788 return gsm48_rr_rx_sysinfo6(ms, msg);
4789 default:
4790 LOGP(DRR, LOGL_NOTICE, "ACCH message type 0x%02x unknown.\n",
4791 sih->system_information);
4792 return -EINVAL;
4796 /* unit data from layer 2 to RR layer */
4797 static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
4799 struct gsm322_cellsel *cs = &ms->cellsel;
4800 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
4801 struct tlv_parsed tv;
4802 uint8_t ch_type, ch_subch, ch_ts;
4804 DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n",
4805 rllh->chan_nr, rllh->link_id);
4807 rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
4808 if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
4809 DEBUGP(DRSL, "UNIT_DATA_IND without L3 INFO ?!?\n");
4810 return -EIO;
4812 msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
4814 if (cs->ccch_state != GSM322_CCCH_ST_SYNC
4815 && cs->ccch_state != GSM322_CCCH_ST_DATA)
4816 return -EINVAL;
4818 /* temporary moved here until confirm is fixed */
4819 if (cs->ccch_state != GSM322_CCCH_ST_DATA) {
4820 LOGP(DCS, LOGL_INFO, "Channel provides data.\n");
4821 cs->ccch_state = GSM322_CCCH_ST_DATA;
4823 /* in dedicated mode */
4824 if (ms->rrlayer.state == GSM48_RR_ST_CONN_PEND)
4825 return gsm48_rr_tx_rand_acc(ms, NULL);
4827 /* set timer for reading BCCH */
4828 if (cs->state == GSM322_C2_STORED_CELL_SEL
4829 || cs->state == GSM322_C1_NORMAL_CELL_SEL
4830 || cs->state == GSM322_C6_ANY_CELL_SEL
4831 || cs->state == GSM322_C4_NORMAL_CELL_RESEL
4832 || cs->state == GSM322_C8_ANY_CELL_RESEL
4833 || cs->state == GSM322_C5_CHOOSE_CELL
4834 || cs->state == GSM322_C9_CHOOSE_ANY_CELL
4835 || cs->state == GSM322_PLMN_SEARCH
4836 || cs->state == GSM322_HPLMN_SEARCH)
4837 start_cs_timer(cs, ms->support.scan_to, 0);
4838 // TODO: timer depends on BCCH config
4841 rsl_dec_chan_nr(rllh->chan_nr, &ch_type, &ch_subch, &ch_ts);
4842 switch (ch_type) {
4843 case RSL_CHAN_PCH_AGCH:
4844 return gsm48_rr_rx_pch_agch(ms, msg);
4845 case RSL_CHAN_BCCH:
4846 return gsm48_rr_rx_bcch(ms, msg);
4847 case RSL_CHAN_Bm_ACCHs:
4848 case RSL_CHAN_Lm_ACCHs:
4849 case RSL_CHAN_SDCCH4_ACCH:
4850 case RSL_CHAN_SDCCH8_ACCH:
4851 return gsm48_rr_rx_acch(ms, msg);
4852 default:
4853 LOGP(DRSL, LOGL_NOTICE, "RSL with chan_nr 0x%02x unknown.\n",
4854 rllh->chan_nr);
4855 return -EINVAL;
4859 /* 3.4.13.3 RR abort in dedicated mode (also in conn. pending mode) */
4860 static int gsm48_rr_abort_req(struct osmocom_ms *ms, struct msgb *msg)
4862 struct gsm48_rrlayer *rr = &ms->rrlayer;
4863 uint8_t *mode;
4865 /* stop pending RACH timer */
4866 stop_rr_t3126(rr);
4868 /* release "normally" if we are in dedicated mode */
4869 if (rr->state == GSM48_RR_ST_DEDICATED) {
4870 struct msgb *nmsg;
4872 LOGP(DRR, LOGL_INFO, "Abort in dedicated state, send release "
4873 "to layer 2.\n");
4875 new_rr_state(rr, GSM48_RR_ST_REL_PEND);
4877 /* release message */
4878 nmsg = gsm48_l3_msgb_alloc();
4879 if (!nmsg)
4880 return -ENOMEM;
4881 mode = msgb_put(nmsg, 2);
4882 mode[0] = RSL_IE_RELEASE_MODE;
4883 mode[1] = 0; /* normal release */
4884 gsm48_send_rsl_nol3(ms, RSL_MT_REL_REQ, nmsg, 0);
4886 /* release SAPI 3 link, if exits */
4887 gsm48_release_sapi3_link(ms);
4888 return 0;
4891 LOGP(DRR, LOGL_INFO, "Abort in connection pending state, return to "
4892 "idle state.\n");
4893 /* return idle */
4894 new_rr_state(rr, GSM48_RR_ST_IDLE);
4896 return 0;
4899 /* release confirm */
4900 static int gsm48_rr_rel_cnf(struct osmocom_ms *ms, struct msgb *msg)
4902 struct gsm48_rrlayer *rr = &ms->rrlayer;
4903 struct msgb *nmsg;
4904 struct gsm48_rr_hdr *nrrh;
4905 uint8_t cause = RR_REL_CAUSE_NORMAL;
4906 uint16_t ma[64];
4907 uint8_t ma_len;
4909 /* switch back to old channel, if modify/ho failed */
4910 switch (rr->modify_state) {
4911 case GSM48_RR_MOD_ASSIGN:
4912 case GSM48_RR_MOD_HANDO:
4913 /* deactivate channel */
4914 l1ctl_tx_dm_rel_req(ms);
4915 ms->meas.rl_fail = 0;
4916 rr->dm_est = 0;
4917 l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED);
4919 /* get old channel description */
4920 memcpy(&rr->cd_now, &rr->cd_last, sizeof(rr->cd_now));
4922 /* render and change radio to old channel */
4923 gsm48_rr_render_ma(ms, &rr->cd_now, ma, &ma_len);
4924 gsm48_rr_activate_channel(ms, &rr->cd_now, ma, ma_len);
4926 /* re-establish old link */
4927 nmsg = gsm48_l3_msgb_alloc();
4928 if (!nmsg)
4929 return -ENOMEM;
4930 if (rr->modify_state == GSM48_RR_MOD_ASSIGN) {
4931 rr->modify_state = GSM48_RR_MOD_ASSIGN_RESUME;
4932 return gsm48_rr_tx_ass_fail(ms,
4933 GSM48_RR_CAUSE_ABNORMAL_UNSPEC,
4934 RSL_MT_RECON_REQ);
4935 } else {
4936 rr->modify_state = GSM48_RR_MOD_HANDO_RESUME;
4937 return gsm48_rr_tx_hando_fail(ms,
4938 GSM48_RR_CAUSE_ABNORMAL_UNSPEC,
4939 RSL_MT_RECON_REQ);
4941 /* returns above */
4942 case GSM48_RR_MOD_ASSIGN_RESUME:
4943 case GSM48_RR_MOD_HANDO_RESUME:
4944 rr->modify_state = GSM48_RR_MOD_NONE;
4945 cause = RR_REL_CAUSE_LINK_FAILURE;
4946 break;
4949 LOGP(DSUM, LOGL_INFO, "Requested channel aborted\n");
4951 /* stop T3211 if running */
4952 stop_rr_t3110(rr);
4954 /* send release indication */
4955 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
4956 if (!nmsg)
4957 return -ENOMEM;
4958 nrrh = (struct gsm48_rr_hdr *)nmsg->data;
4959 nrrh->cause = cause;
4960 gsm48_rr_upmsg(ms, nmsg);
4962 /* return idle */
4963 new_rr_state(rr, GSM48_RR_ST_IDLE);
4964 return 0;
4967 /* MDL-ERROR */
4968 static int gsm48_rr_mdl_error_ind(struct osmocom_ms *ms, struct msgb *msg)
4970 struct gsm48_rrlayer *rr = &ms->rrlayer;
4971 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
4972 struct msgb *nmsg;
4973 struct gsm48_rr_hdr *nrrh;
4974 uint8_t *mode;
4975 uint8_t cause = rllh->data[2];
4976 uint8_t link_id = rllh->link_id;
4978 switch (cause) {
4979 case RLL_CAUSE_SEQ_ERR:
4980 case RLL_CAUSE_UNSOL_DM_RESP_MF:
4981 break;
4982 default:
4983 LOGP(DRR, LOGL_NOTICE, "MDL-Error (cause %d) ignoring\n",
4984 cause);
4987 LOGP(DRR, LOGL_NOTICE, "MDL-Error (cause %d) aborting\n", cause);
4989 /* disconnect the (main) signalling link */
4990 nmsg = gsm48_l3_msgb_alloc();
4991 if (!nmsg)
4992 return -ENOMEM;
4993 mode = msgb_put(nmsg, 2);
4994 mode[0] = RSL_IE_RELEASE_MODE;
4995 mode[1] = 1; /* local release */
4996 gsm48_send_rsl_nol3(ms, RSL_MT_REL_REQ, nmsg, link_id);
4998 /* in case of modify/hando: wait for confirm */
4999 if (rr->modify_state)
5000 return 0;
5002 /* send abort ind to upper layer */
5003 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_ABORT_IND);
5004 if (!nmsg)
5005 return -ENOMEM;
5006 nrrh = (struct gsm48_rr_hdr *)nmsg->data;
5007 nrrh->cause = RR_REL_CAUSE_LINK_FAILURE;
5008 nrrh->sapi = link_id & 7;
5009 gsm48_rr_upmsg(ms, nmsg);
5011 /* only for main signalling link */
5012 if ((link_id & 7) == 0) {
5013 /* return idle */
5014 new_rr_state(rr, GSM48_RR_ST_IDLE);
5015 /* release SAPI 3 link, if exits */
5016 gsm48_release_sapi3_link(ms);
5017 } else {
5018 new_sapi3_state(rr, GSM48_RR_SAPI3ST_IDLE);
5019 LOGP(DSUM, LOGL_INFO, "Radio link SAPI3 failed\n");
5021 return 0;
5024 static int gsm48_rr_estab_ind_sapi3(struct osmocom_ms *ms, struct msgb *msg)
5026 struct gsm48_rrlayer *rr = &ms->rrlayer;
5027 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
5028 uint8_t link_id = rllh->link_id;
5029 struct msgb *nmsg;
5030 struct gsm48_rr_hdr *nrrh;
5032 if (rr->state != GSM48_RR_ST_DEDICATED) {
5033 /* disconnect sapi 3 link */
5034 gsm48_release_sapi3_link(ms);
5035 return -EINVAL;
5038 new_sapi3_state(rr, GSM48_RR_SAPI3ST_ESTAB);
5039 rr->sapi3_link_id = link_id; /* set link ID */
5041 LOGP(DSUM, LOGL_INFO, "Radio link SAPI3 is established\n");
5043 if ((link_id & 0xf8) == 0x00) {
5044 /* raise T200 of SAPI 0 */
5045 ms->lapdm_channel.lapdm_dcch.datalink[DL_SAPI0].dl.t200_sec =
5046 T200_DCCH_SHARED;
5047 ms->lapdm_channel.lapdm_dcch.datalink[DL_SAPI0].dl.t200_usec= 0;
5050 /* send inication to upper layer */
5051 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_EST_IND);
5052 if (!nmsg)
5053 return -ENOMEM;
5054 nrrh = (struct gsm48_rr_hdr *)nmsg->data;
5055 nrrh->sapi = link_id & 7;
5057 return gsm48_rr_upmsg(ms, nmsg);
5060 static int gsm48_rr_estab_cnf_sapi3(struct osmocom_ms *ms, struct msgb *msg)
5062 struct gsm48_rrlayer *rr = &ms->rrlayer;
5063 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
5064 uint8_t link_id = rllh->link_id;
5065 struct msgb *nmsg;
5066 struct gsm48_rr_hdr *nrrh;
5068 if (rr->state != GSM48_RR_ST_DEDICATED) {
5069 gsm48_release_sapi3_link(ms);
5070 return -EINVAL;
5073 new_sapi3_state(rr, GSM48_RR_SAPI3ST_ESTAB);
5074 rr->sapi3_link_id = link_id; /* set link ID, just to be sure */
5076 LOGP(DSUM, LOGL_INFO, "Radio link SAPI3 is established\n");
5078 /* send inication to upper layer */
5079 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_EST_CNF);
5080 if (!nmsg)
5081 return -ENOMEM;
5082 nrrh = (struct gsm48_rr_hdr *)nmsg->data;
5083 nrrh->sapi = link_id & 7;
5085 return gsm48_rr_upmsg(ms, nmsg);
5088 /* 3.4.2 data from layer 2 to RR and upper layer (sapi 3)*/
5089 static int gsm48_rr_data_ind_sapi3(struct osmocom_ms *ms, struct msgb *msg)
5091 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
5092 uint8_t sapi = rllh->link_id & 7;
5093 struct gsm48_hdr *gh = msgb_l3(msg);
5094 struct gsm48_rr_hdr *rrh;
5095 uint8_t pdisc = gh->proto_discr & 0x0f;
5097 if (pdisc == GSM48_PDISC_RR) {
5098 msgb_free(msg);
5099 return -EINVAL;
5102 /* pull off RSL header up to L3 message */
5103 msgb_pull(msg, (long)msgb_l3(msg) - (long)msg->data);
5105 /* push RR header */
5106 msgb_push(msg, sizeof(struct gsm48_rr_hdr));
5107 rrh = (struct gsm48_rr_hdr *)msg->data;
5108 rrh->msg_type = GSM48_RR_DATA_IND;
5109 rrh->sapi = sapi;
5111 return gsm48_rr_upmsg(ms, msg);
5114 static int gsm48_rr_rel_ind_sapi3(struct osmocom_ms *ms, struct msgb *msg)
5116 struct gsm48_rrlayer *rr = &ms->rrlayer;
5117 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
5118 uint8_t link_id = rllh->link_id;
5119 struct msgb *nmsg;
5120 struct gsm48_rr_hdr *nrrh;
5122 new_sapi3_state(rr, GSM48_RR_SAPI3ST_IDLE);
5124 LOGP(DSUM, LOGL_INFO, "Radio link SAPI3 is released\n");
5126 /* lower T200 of SAPI 0 */
5127 ms->lapdm_channel.lapdm_dcch.datalink[DL_SAPI0].dl.t200_sec =
5128 T200_DCCH;
5129 ms->lapdm_channel.lapdm_dcch.datalink[DL_SAPI0].dl.t200_usec = 0;
5131 /* send inication to upper layer */
5132 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
5133 if (!nmsg)
5134 return -ENOMEM;
5135 nrrh = (struct gsm48_rr_hdr *)nmsg->data;
5136 nrrh->cause = RR_REL_CAUSE_NORMAL;
5137 nrrh->sapi = link_id & 7;
5139 return gsm48_rr_upmsg(ms, nmsg);
5142 /* request SAPI 3 establishment */
5143 static int gsm48_rr_est_req_sapi3(struct osmocom_ms *ms, struct msgb *msg)
5145 struct gsm48_rrlayer *rr = &ms->rrlayer;
5146 uint8_t ch_type, ch_subch, ch_ts;
5147 struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *) msg->data;
5148 uint8_t sapi = rrh->sapi;
5149 struct msgb *nmsg;
5151 if (rr->state != GSM48_RR_ST_DEDICATED) {
5152 struct gsm48_rr_hdr *nrrh;
5154 /* send inication to upper layer */
5155 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
5156 if (!nmsg)
5157 return -ENOMEM;
5158 nrrh = (struct gsm48_rr_hdr *)nmsg->data;
5159 nrrh->cause = RR_REL_CAUSE_NORMAL;
5160 nrrh->sapi = sapi;
5161 return gsm48_rr_upmsg(ms, nmsg);
5164 rsl_dec_chan_nr(rr->cd_now.chan_nr, &ch_type, &ch_subch, &ch_ts);
5165 if (ch_type != RSL_CHAN_Bm_ACCHs
5166 && ch_type != RSL_CHAN_Lm_ACCHs) {
5167 LOGP(DRR, LOGL_INFO, "Requesting DCCH link, because no TCH "
5168 "(sapi %d)\n", sapi);
5169 rr->sapi3_link_id = 0x00 | sapi; /* SAPI 3, DCCH */
5170 /* raise T200 of SAPI 0 */
5171 ms->lapdm_channel.lapdm_dcch.datalink[DL_SAPI0].dl.t200_sec =
5172 T200_DCCH_SHARED;
5173 ms->lapdm_channel.lapdm_dcch.datalink[DL_SAPI0].dl.t200_usec= 0;
5174 } else {
5175 LOGP(DRR, LOGL_INFO, "Requesting ACCH link, because TCH "
5176 "(sapi %d)\n", sapi);
5177 rr->sapi3_link_id = 0x40 | sapi; /* SAPI 3, ACCH */
5180 /* already established */
5181 new_sapi3_state(rr, GSM48_RR_SAPI3ST_WAIT_EST);
5183 /* send message */
5184 nmsg = gsm48_l3_msgb_alloc();
5185 if (!nmsg)
5186 return -ENOMEM;
5187 return gsm48_send_rsl_nol3(ms, RSL_MT_EST_REQ, nmsg, rr->sapi3_link_id);
5190 static int gsm48_rr_est_req_estab_sapi3(struct osmocom_ms *ms, struct msgb *msg)
5192 struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *) msg->data;
5193 uint8_t sapi = rrh->sapi;
5194 struct msgb *nmsg;
5195 struct gsm48_rr_hdr *nrrh;
5197 LOGP(DRR, LOGL_INFO, "Radio link SAPI3 already established\n");
5199 /* send inication to upper layer */
5200 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_EST_CNF);
5201 if (!nmsg)
5202 return -ENOMEM;
5203 nrrh = (struct gsm48_rr_hdr *)nmsg->data;
5204 nrrh->sapi = sapi;
5206 return gsm48_rr_upmsg(ms, nmsg);
5210 * state machines
5213 /* state trasitions for link layer messages (lower layer) */
5214 static struct dldatastate {
5215 uint32_t states;
5216 int type;
5217 int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
5218 } dldatastatelist[] = {
5219 /* SAPI 0 on DCCH */
5221 /* data transfer */
5222 {SBIT(GSM48_RR_ST_IDLE) |
5223 SBIT(GSM48_RR_ST_CONN_PEND) |
5224 SBIT(GSM48_RR_ST_DEDICATED) |
5225 SBIT(GSM48_RR_ST_REL_PEND),
5226 RSL_MT_UNIT_DATA_IND, gsm48_rr_unit_data_ind},
5228 {SBIT(GSM48_RR_ST_DEDICATED), /* 3.4.2 */
5229 RSL_MT_DATA_IND, gsm48_rr_data_ind},
5231 /* esablish */
5232 {SBIT(GSM48_RR_ST_IDLE) |
5233 SBIT(GSM48_RR_ST_CONN_PEND) |
5234 SBIT(GSM48_RR_ST_REL_PEND),
5235 RSL_MT_EST_CONF, gsm48_rr_estab_cnf},
5237 /* resume */
5238 {SBIT(GSM48_RR_ST_DEDICATED),
5239 RSL_MT_EST_CONF, gsm48_rr_estab_cnf_dedicated},
5241 /* release */
5242 {SBIT(GSM48_RR_ST_CONN_PEND) |
5243 SBIT(GSM48_RR_ST_DEDICATED),
5244 RSL_MT_REL_IND, gsm48_rr_rel_ind},
5246 {SBIT(GSM48_RR_ST_REL_PEND),
5247 RSL_MT_REL_CONF, gsm48_rr_rel_cnf},
5249 /* reconnect */
5250 {SBIT(GSM48_RR_ST_CONN_PEND) |
5251 SBIT(GSM48_RR_ST_DEDICATED),
5252 RSL_MT_REL_CONF, gsm48_rr_rel_cnf},
5254 /* suspenion */
5255 {SBIT(GSM48_RR_ST_DEDICATED),
5256 RSL_MT_SUSP_CONF, gsm48_rr_susp_cnf_dedicated},
5258 #if 0
5259 {SBIT(GSM48_RR_ST_DEDICATED),
5260 RSL_MT_CHAN_CNF, gsm48_rr_rand_acc_cnf_dedicated},
5261 #endif
5263 {SBIT(GSM48_RR_ST_DEDICATED),
5264 RSL_MT_ERROR_IND, gsm48_rr_mdl_error_ind},
5267 #define DLDATASLLEN \
5268 (sizeof(dldatastatelist) / sizeof(struct dldatastate))
5270 static struct dldatastate dldatastatelists3[] = {
5271 /* SAPI 3 on DCCH */
5273 /* establish */
5274 {SBIT(GSM48_RR_SAPI3ST_IDLE),
5275 RSL_MT_EST_IND, gsm48_rr_estab_ind_sapi3},
5277 /* establish */
5278 {SBIT(GSM48_RR_SAPI3ST_IDLE) | SBIT(GSM48_RR_SAPI3ST_WAIT_EST),
5279 RSL_MT_EST_CONF, gsm48_rr_estab_cnf_sapi3},
5281 /* data transfer */
5282 {SBIT(GSM48_RR_SAPI3ST_ESTAB),
5283 RSL_MT_DATA_IND, gsm48_rr_data_ind_sapi3},
5285 /* release */
5286 {SBIT(GSM48_RR_SAPI3ST_WAIT_EST) | SBIT(GSM48_RR_SAPI3ST_ESTAB),
5287 RSL_MT_REL_IND, gsm48_rr_rel_ind_sapi3},
5289 {ALL_STATES,
5290 RSL_MT_ERROR_IND, gsm48_rr_mdl_error_ind},
5293 #define DLDATASLLENS3 \
5294 (sizeof(dldatastatelists3) / sizeof(struct dldatastate))
5296 static int gsm48_rcv_rll(struct osmocom_ms *ms, struct msgb *msg)
5298 struct gsm48_rrlayer *rr = &ms->rrlayer;
5299 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
5300 int msg_type = rllh->c.msg_type;
5301 int link_id = rllh->link_id;
5302 int i;
5303 int rc;
5305 LOGP(DRSL, LOGL_INFO, "(ms %s) Received '%s' from L2 in state "
5306 "%s (link_id 0x%x)\n", ms->name, rsl_msg_name(msg_type),
5307 gsm48_rr_state_names[rr->state], link_id);
5309 /* find function for current state and message */
5310 if (!(link_id & 7)) {
5311 /* SAPI 0 */
5312 for (i = 0; i < DLDATASLLEN; i++)
5313 if ((msg_type == dldatastatelist[i].type)
5314 && ((1 << rr->state) & dldatastatelist[i].states))
5315 break;
5316 if (i == DLDATASLLEN) {
5317 LOGP(DRSL, LOGL_NOTICE, "RSLms message '%s' "
5318 "unhandled\n", rsl_msg_name(msg_type));
5319 msgb_free(msg);
5320 return 0;
5323 rc = dldatastatelist[i].rout(ms, msg);
5324 } else {
5325 /* SAPI 3 */
5326 for (i = 0; i < DLDATASLLENS3; i++)
5327 if ((msg_type == dldatastatelists3[i].type)
5328 && ((1 << rr->sapi3_state) &
5329 dldatastatelists3[i].states))
5330 break;
5331 if (i == DLDATASLLENS3) {
5332 LOGP(DRSL, LOGL_NOTICE, "RSLms message '%s' "
5333 "unhandled\n", rsl_msg_name(msg_type));
5334 msgb_free(msg);
5335 return 0;
5338 rc = dldatastatelists3[i].rout(ms, msg);
5341 /* free msgb unless it is forwarded */
5342 if (msg_type != RSL_MT_DATA_IND)
5343 msgb_free(msg);
5345 return rc;
5348 static int gsm48_rcv_cch(struct osmocom_ms *ms, struct msgb *msg)
5350 struct gsm48_rrlayer *rr = &ms->rrlayer;
5351 struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
5352 int msg_type = ch->c.msg_type;
5353 int rc;
5355 LOGP(DRSL, LOGL_INFO, "(ms %s) Received '%s' from L2 in state "
5356 "%s\n", ms->name, rsl_msg_name(msg_type),
5357 gsm48_rr_state_names[rr->state]);
5359 if (rr->state == GSM48_RR_ST_CONN_PEND
5360 && msg_type == RSL_MT_CHAN_CONF) {
5361 rc = gsm48_rr_tx_rand_acc(ms, msg);
5362 msgb_free(msg);
5363 return rc;
5366 LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
5367 msgb_free(msg);
5368 return 0;
5372 /* input function for L2 messags up to L3 */
5373 static int gsm48_rcv_rsl(struct osmocom_ms *ms, struct msgb *msg)
5375 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
5376 int rc = 0;
5378 switch (rslh->msg_discr & 0xfe) {
5379 case ABIS_RSL_MDISC_RLL:
5380 rc = gsm48_rcv_rll(ms, msg);
5381 break;
5382 case ABIS_RSL_MDISC_COM_CHAN:
5383 rc = gsm48_rcv_cch(ms, msg);
5384 break;
5385 default:
5386 /* FIXME: implement this */
5387 LOGP(DRSL, LOGL_NOTICE, "unknown RSLms msg_discr 0x%02x\n",
5388 rslh->msg_discr);
5389 msgb_free(msg);
5390 rc = -EINVAL;
5391 break;
5394 return rc;
5397 /* state trasitions for RR-SAP messages from up (main link) */
5398 static struct rrdownstate {
5399 uint32_t states;
5400 int type;
5401 int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
5402 } rrdownstatelist[] = {
5403 /* SAPI 0 */
5405 /* NOTE: If not IDLE, it is rejected there. */
5406 {ALL_STATES, /* 3.3.1.1 */
5407 GSM48_RR_EST_REQ, gsm48_rr_est_req},
5409 {SBIT(GSM48_RR_ST_DEDICATED), /* 3.4.2 */
5410 GSM48_RR_DATA_REQ, gsm48_rr_data_req},
5412 {SBIT(GSM48_RR_ST_CONN_PEND) |
5413 SBIT(GSM48_RR_ST_DEDICATED), /* 3.4.13.3 */
5414 GSM48_RR_ABORT_REQ, gsm48_rr_abort_req},
5417 #define RRDOWNSLLEN \
5418 (sizeof(rrdownstatelist) / sizeof(struct rrdownstate))
5420 /* state trasitions for RR-SAP messages from up with (SAPI 3) */
5421 static struct rrdownstate rrdownstatelists3[] = {
5422 /* SAPI 3 */
5424 {SBIT(GSM48_RR_SAPI3ST_IDLE),
5425 GSM48_RR_EST_REQ, gsm48_rr_est_req_sapi3},
5427 {SBIT(GSM48_RR_SAPI3ST_ESTAB),
5428 GSM48_RR_EST_REQ, gsm48_rr_est_req_estab_sapi3},
5430 {SBIT(GSM48_RR_SAPI3ST_ESTAB),
5431 GSM48_RR_DATA_REQ, gsm48_rr_data_req}, /* handles SAPI 3 too */
5434 #define RRDOWNSLLENS3 \
5435 (sizeof(rrdownstatelists3) / sizeof(struct rrdownstate))
5437 int gsm48_rr_downmsg(struct osmocom_ms *ms, struct msgb *msg)
5439 struct gsm48_rrlayer *rr = &ms->rrlayer;
5440 struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *) msg->data;
5441 int msg_type = rrh->msg_type;
5442 int sapi = rrh->sapi;
5443 int i;
5444 int rc;
5446 LOGP(DRR, LOGL_INFO, "(ms %s) Message '%s' received in state %s "
5447 "(sapi %d)\n", ms->name, get_rr_name(msg_type),
5448 gsm48_rr_state_names[rr->state], sapi);
5450 if (!sapi) {
5451 /* SAPI 0: find function for current state and message */
5452 for (i = 0; i < RRDOWNSLLEN; i++)
5453 if ((msg_type == rrdownstatelist[i].type)
5454 && ((1 << rr->state) & rrdownstatelist[i].states))
5455 break;
5456 if (i == RRDOWNSLLEN) {
5457 LOGP(DRR, LOGL_NOTICE, "Message unhandled at this "
5458 "state.\n");
5459 msgb_free(msg);
5460 return 0;
5463 rc = rrdownstatelist[i].rout(ms, msg);
5464 } else {
5465 /* SAPI 3: find function for current state and message */
5466 for (i = 0; i < RRDOWNSLLENS3; i++)
5467 if ((msg_type == rrdownstatelists3[i].type)
5468 && ((1 << rr->sapi3_state)
5469 & rrdownstatelists3[i].states))
5470 break;
5471 if (i == RRDOWNSLLENS3) {
5472 LOGP(DRR, LOGL_NOTICE, "Message unhandled at this "
5473 "state.\n");
5474 msgb_free(msg);
5475 return 0;
5478 rc = rrdownstatelists3[i].rout(ms, msg);
5481 /* free msgb unless it is forwarded */
5482 if (msg_type != GSM48_RR_DATA_REQ)
5483 msgb_free(msg);
5485 return rc;
5489 * init/exit
5492 int gsm48_rr_init(struct osmocom_ms *ms)
5494 struct gsm48_rrlayer *rr = &ms->rrlayer;
5496 memset(rr, 0, sizeof(*rr));
5497 rr->ms = ms;
5499 LOGP(DRR, LOGL_INFO, "init Radio Ressource process\n");
5501 INIT_LLIST_HEAD(&rr->rsl_upqueue);
5502 INIT_LLIST_HEAD(&rr->downqueue);
5503 /* downqueue is handled here, so don't add_work */
5505 lapdm_channel_set_l3(&ms->lapdm_channel, &rcv_rsl, ms);
5507 start_rr_t_meas(rr, 1, 0);
5509 rr->audio_mode = AUDIO_TX_MICROPHONE | AUDIO_RX_SPEAKER;
5511 return 0;
5514 int gsm48_rr_exit(struct osmocom_ms *ms)
5516 struct gsm48_rrlayer *rr = &ms->rrlayer;
5517 struct msgb *msg;
5519 LOGP(DRR, LOGL_INFO, "exit Radio Ressource process\n");
5521 /* flush queues */
5522 while ((msg = msgb_dequeue(&rr->rsl_upqueue)))
5523 msgb_free(msg);
5524 while ((msg = msgb_dequeue(&rr->downqueue)))
5525 msgb_free(msg);
5527 if (rr->rr_est_msg) {
5528 msgb_free(rr->rr_est_msg);
5529 rr->rr_est_msg = NULL;
5532 stop_rr_t_meas(rr);
5533 stop_rr_t_starting(rr);
5534 stop_rr_t_rel_wait(rr);
5535 stop_rr_t3110(rr);
5536 stop_rr_t3122(rr);
5537 stop_rr_t3124(rr);
5538 stop_rr_t3126(rr);
5540 return 0;
5543 #if 0
5545 todo rr_sync_ind when receiving ciph, re ass, channel mode modify
5548 static void timeout_rr_t3124(void *arg)
5550 struct gsm48_rrlayer *rr = arg;
5551 struct msgb *nmsg;
5553 /* stop sending more access bursts when timer expired */
5554 hando_acc_left = 0;
5556 /* get old channel description */
5557 memcpy(&rr->chan_desc, &rr->chan_last, sizeof(rr->chan_desc));
5559 /* change radio to old channel */
5560 tx_ph_dm_est_req(ms, rr->cd_now.arfcn, rr->cd_now.chan_nr,
5561 rr->cd_now.tsc);
5562 rr->dm_est = 1;
5564 /* re-establish old link */
5565 nmsg = gsm48_l3_msgb_alloc();
5566 if (!nmsg)
5567 return -ENOMEM;
5568 return gsm48_send_rsl(ms, RSL_MT_REEST_REQ, nmsg, 0);
5570 todo
5573 /* send HANDOVER ACCESS burst (9.1.14) */
5574 static int gsm48_rr_tx_hando_access(struct osmocom_ms *ms)
5576 nmsg = msgb_alloc_headroom(20, 16, "HAND_ACCESS");
5577 if (!nmsg)
5578 return -ENOMEM;
5579 *msgb_put(nmsg, 1) = rr->hando_ref;
5580 todo burst
5581 return gsm48_send_rsl(ms, RSL_MT_RAND_ACC_REQ, nmsg, 0);
5584 /* send next channel request in dedicated state */
5585 static int gsm48_rr_rand_acc_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
5587 struct gsm48_rrlayer *rr = &ms->rrlayer;
5588 struct msgb *nmsg;
5589 int s;
5591 if (rr->modify_state != GSM48_RR_MOD_HANDO) {
5592 LOGP(DRR, LOGL_NOTICE, "Random acces confirm, but not in handover state.\n");
5593 return 0;
5596 /* send up to four handover access bursts */
5597 if (rr->hando_acc_left) {
5598 rr->hando_acc_left--;
5599 gsm48_rr_tx_hando_access(ms);
5600 return;
5603 /* start timer for sending next HANDOVER ACCESS bursts afterwards */
5604 if (!osmo_timer_pending(&rr->t3124)) {
5605 if (allocated channel is SDCCH)
5606 start_rr_t3124(rr, GSM_T3124_675);
5607 else
5608 start_rr_t3124(rr, GSM_T3124_320);
5610 if (!rr->n_chan_req) {
5611 start_rr_t3126(rr, 5, 0); /* TODO improve! */
5612 return 0;
5614 rr->n_chan_req--;
5616 /* wait for PHYSICAL INFORMATION message or T3124 timeout */
5617 return 0;
5621 #endif
5623 int gsm48_rr_tx_voice(struct osmocom_ms *ms, struct msgb *msg)
5625 struct gsm48_rrlayer *rr = &ms->rrlayer;
5626 uint8_t ch_type, ch_subch, ch_ts;
5628 if (!rr->dm_est) {
5629 LOGP(DRR, LOGL_INFO, "Current channel is not active\n");
5630 msgb_free(msg);
5631 return -ENOTSUP;
5634 rsl_dec_chan_nr(rr->cd_now.chan_nr, &ch_type, &ch_subch, &ch_ts);
5635 if (ch_type != RSL_CHAN_Bm_ACCHs) {
5636 LOGP(DRR, LOGL_INFO, "Current channel is not (yet) TCH/F\n");
5637 msgb_free(msg);
5638 return -ENOTSUP;
5641 return l1ctl_tx_traffic_req(ms, msg, rr->cd_now.chan_nr, 0);
5644 int gsm48_rr_audio_mode(struct osmocom_ms *ms, uint8_t mode)
5646 struct gsm48_rrlayer *rr = &ms->rrlayer;
5647 uint8_t ch_type, ch_subch, ch_ts;
5649 LOGP(DRR, LOGL_INFO, "setting audio mode to %d\n", mode);
5651 rr->audio_mode = mode;
5653 if (!rr->dm_est)
5654 return 0;
5656 rsl_dec_chan_nr(rr->cd_now.chan_nr, &ch_type, &ch_subch, &ch_ts);
5657 if (ch_type != RSL_CHAN_Bm_ACCHs
5658 && ch_type != RSL_CHAN_Lm_ACCHs)
5659 return 0;
5661 return l1ctl_tx_tch_mode_req(ms, rr->cd_now.mode, mode);