Classmark 3 encoding (Radio Ressource) now uses bit-vector API.
[osmocom-bb.git] / src / host / gsm48-andreas / gsm48_rr.c
blobf2b88a0ee9cc3b99c819ab5b689e25b0a153c929
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.
23 * state transition
26 char *rr_state_names[] = {
27 "IDLE",
28 "CONN PEND",
29 "DEDICATED",
32 static void new_rr_state(struct gsm_rrlayer *rr, int state)
34 if (state < 0 || state >= (sizeof(rr_state_names) / sizeof(char *)))
35 return;
37 if (state == GSM_RRSTATE_IDLE) {
38 struct msgb *msg;
40 /* free establish message, if any */
41 rr->rr_est_req = 0;
42 if (rr->rr_est_msg) {
43 msgb_free(rr->rr_est_msg);
44 rr->rr_est_msg = NULL;
46 /* free all pending messages */
47 while((msg = msgb_dequeue(&rr->downqueue)))
48 free_msgb(msg);
51 DEBUGP(DRR, "new state %s -> %s\n",
52 rr_state_names[rr->state], rr_state_names[state]);
54 rr->state = state;
58 * timers handling
61 static void start_rr_t3122(struct gsm_rrlayer *rr, int sec, int micro)
63 DEBUGP(DRR, "starting T3122 with %d seconds\n", current, sec);
64 rr->t3122.cb = timeout_rr_t3122;
65 rr->t3122.data = rr;
66 bsc_schedule_timer(&rr->t3122, sec, micro);
69 static void start_rr_t3126(struct gsm_rrlayer *rr, int sec, int micro)
71 DEBUGP(DRR, "starting T3126 with %d seconds\n", current, sec);
72 rr->t3126.cb = timeout_rr_t3126;
73 rr->t3126.data = rr;
74 bsc_schedule_timer(&rr->t3126, sec, micro);
77 static void stop_rr_t3122(struct gsm_rrlayer *rr)
79 if (timer_pending(rr->t3122)) {
80 DEBUGP(DRR, "stopping pending timer T3122\n");
81 bsc_del_timer(&rr->t3122);
83 rr->t3122_running = 0;
86 static void stop_rr_t3126(struct gsm_rrlayer *rr)
88 if (bsc_timer_pending(rr->t3126)) {
89 DEBUGP(DRR, "stopping pending timer T3126\n");
90 bsc_del_timer(&rr->t3126);
94 static void timeout_rr_t3122(void *arg)
98 static void timeout_rr_t3126(void *arg)
100 struct gsm_rrlayer *rr = arg;
102 if (rr->rr_est_req) {
103 struct msgb *msg = gsm48_mm_msgb_alloc();
104 struct gsm_mm_hdr *mmh;
106 if (!msg)
107 return -ENOMEM;
108 mmh = (struct gsm_mm_hdr *)msg->data;
109 mmh->msg_type RR_REL_IND;
110 mmh->cause = GSM_MM_CAUSE_RA_FAILURE;
111 rr_rcvmsg(ms, msg);
114 new_rr_state(rr, GSM_RRSTATE_IDLE);
118 * status
121 /* send rr status request */
122 static int gsm_rr_tx_rr_status(struct osmocom_ms *ms, uint8_t cause)
124 struct gsm_rrlayer *rr = ms->rrlayer;
125 struct msgb *msg = gsm48_rr_msgb_alloc();
126 struct gsm48_hdr *gh;
127 struct gsm48_rr_status *st;
129 if (!msg)
130 return -ENOMEM;
131 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
132 st = (struct gsm48_rr_status *) msgb_put(msg, sizeof(*st));
134 gh->proto = GSM48_PDISC_RR;
135 gh->msg_type = GSM48_MT_RR_CIPH_M_COMPL;
137 /* rr cause */
138 st->rr_cause = cause;
140 return rslms_data_req(ms, msg, 0);
144 * ciphering
147 /* send chiperhing mode complete */
148 static int gsm_rr_tx_cip_mode_cpl(struct osmocom_ms *ms, uint8_t cr)
150 struct gsm_rrlayer *rr = ms->rrlayer;
151 struct gsm_subscriber *subcr = ms->subscr;
152 struct msgb *msg = gsm48_rr_msgb_alloc();
153 struct gsm48_hdr *gh;
154 u_int8_t buf[11], *ie;
156 if (!msg)
157 return -ENOMEM;
158 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
160 gh->proto = GSM48_PDISC_RR;
161 gh->msg_type = GSM48_MT_RR_CIPH_M_COMPL;
163 /* MI */
164 if (cr) {
165 gsm48_generate_mid_from_imsi(ie, subscr->imei);
166 ie = msgb_put(msg, 1 + buf[1]);
167 memcpy(ie, buf + 1, 1 + buf[1]);
170 return rslms_data_req(ms, msg, 0);
173 /* receive ciphering mode command */
174 static int gsm_rr_rx_cip_mode_cmd(struct osmocom_ms *ms, struct msgb *msg)
176 struct gsm_rrlayer *rr = ms->rrlayer;
177 struct gsm48_hdr *gh = msgb_l3(msg);
178 struct gsm48_cip_mode_cmd *cm = (struct gsm48_cip_mode_cmd *)gh->data;
179 int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*cm);
180 uint8_t sc, alg_id, cr;
182 if (payload_len < 0) {
183 DEBUGP(DRR, "Short read of CIPHERING MODE COMMAND message.\n");
184 return gsm_rr_tx_rr_status(ms, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
187 /* cipher mode setting */
188 sc = cm->sc;
189 alg_id = cm->alg_id;
190 /* cipher mode response */
191 cr = cm->cr;
193 /* 3.4.7.2 */
194 if (rr->sc && sc)
195 return gsm_rr_tx_rr_status(ms, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
197 /* change to ciphering */
198 tx_ph_cipher_req(ms, sc, alg_id);
199 rr->sc = sc, rr->alg_id = alg_id;
201 /* response */
202 return gsm_rr_tx_cip_mode_cpl(ms, cr);
206 * classmark
209 /* Encode "Classmark 3" (10.5.2.20) */
210 static int gsm_rr_enc_cm3(struct osmocom_sm *ms, uint8_t *buf, uint8_t *len)
212 struct gsm_support *sup = ms->support;
213 struct bitvec bv;
215 memset(&bv, 0, sizeof(bv));
216 bv.data = data;
217 bv.data_len = 12;
219 /* spare bit */
220 bitvec_set_bit(&bv, 0);
221 /* band 3 supported */
222 if (sup->dcs_1800)
223 bitvec_set_bit(&bv, ONE);
224 else
225 bitvec_set_bit(&bv, ZERO);
226 /* band 2 supported */
227 if (sup->e_gsm || sup->r_gsm)
228 bitvec_set_bit(&bv, ONE);
229 else
230 bitvec_set_bit(&bv, ZERO);
231 /* band 1 supported */
232 if (sup->p_gsm && !(sup->e_gsm || sup->r_gsm))
233 bitvec_set_bit(&bv, ONE);
234 else
235 bitvec_set_bit(&bv, ZERO);
236 /* a5 bits */
237 if (sup->a5_7)
238 bitvec_set_bit(&bv, ONE);
239 else
240 bitvec_set_bit(&bv, ZERO);
241 if (sup->a5_6)
242 bitvec_set_bit(&bv, ONE);
243 else
244 bitvec_set_bit(&bv, ZERO);
245 if (sup->a5_5)
246 bitvec_set_bit(&bv, ONE);
247 else
248 bitvec_set_bit(&bv, ZERO);
249 if (sup->a5_4)
250 bitvec_set_bit(&bv, ONE);
251 else
252 bitvec_set_bit(&bv, ZERO);
253 /* radio capability */
254 if (sup->dcs_1800 && !sup->p_gsm && !(sup->e_gsm || sup->r_gsm)) {
255 /* dcs only */
256 bitvec_set_uint(&bv, 0, 4);
257 bitvec_set_uint(&bv, sup->dcs_capa, 4);
258 } else
259 if (sup->dcs_1800 && (sup->p_gsm || (sup->e_gsm || sup->r_gsm))) {
260 /* dcs */
261 bitvec_set_uint(&bv, sup->dcs_capa, 4);
262 /* low band */
263 bitvec_set_uint(&bv, sup->low_capa, 4);
264 } else {
265 /* low band only */
266 bitvec_set_uint(&bv, 0, 4);
267 bitvec_set_uint(&bv, sup->low_capa, 4);
269 /* r support */
270 if (sup->r_gsm) {
271 bitvec_set_bit(&bv, ONE);
272 bitvec_set_uint(&bv, sup->r_capa, 3);
273 } else {
274 bitvec_set_bit(&bv, ZERO);
276 /* multi slot support */
277 if (sup->ms_sup) {
278 bitvec_set_bit(&bv, ONE);
279 bitvec_set_uint(&bv, sup->ms_capa, 5);
280 } else {
281 bitvec_set_bit(&bv, ZERO);
283 /* ucs2 treatment */
284 if (sup->ucs2_treat) {
285 bitvec_set_bit(&bv, ONE);
286 } else {
287 bitvec_set_bit(&bv, ZERO);
289 /* support extended measurements */
290 if (sup->ext_meas) {
291 bitvec_set_bit(&bv, ONE);
292 } else {
293 bitvec_set_bit(&bv, ZERO);
295 /* support measurement capability */
296 if (sup->meas_cap) {
297 bitvec_set_bit(&bv, ONE);
298 bitvec_set_uint(&bv, sup->sms_val, 4);
299 bitvec_set_uint(&bv, sup->sm_val, 4);
300 } else {
301 bitvec_set_bit(&bv, ZERO);
303 /* positioning method capability */
304 if (sup->loc_serv) {
305 bitvec_set_bit(&bv, ONE);
306 bitvec_set_bit(&bv, sup->e_otd_ass == 1);
307 bitvec_set_bit(&bv, sup->e_otd_based == 1);
308 bitvec_set_bit(&bv, sup->gps_ass == 1);
309 bitvec_set_bit(&bv, sup->gps_based == 1);
310 bitvec_set_bit(&bv, sup->gps_conv == 1);
311 } else {
312 bitvec_set_bit(&bv, ZERO);
315 /* partitial bytes will be completed */
316 *len = (bv.cur_bit + 7) >> 3;
317 bitvec_spare_padding(&bv, (*len * 8) - 1);
319 return 0;
322 /* encode classmark 2 */
323 static int gsm_rr_enc_cm2(struct osmocom_sm *ms, struct gsm48_classmark2 *cm)
325 struct gsm_support *sup = ms->support;
327 cm->pwr_lev = sup->pwr_lev;
328 cm->a5_1 = sup->a5_1;
329 cm->es_ind = sup->es_ind;
330 cm->rev_lev = sup->rev_lev;
331 cm->fc = (sup->r_gsm || sup->e_gsm);
332 cm->vgcs = sup->vgcs;
333 cm->vbs = sup->vbs;
334 cm->sm = sup->sms_ptp;
335 cm->ss_ind = sup->ss_ind;
336 cm->ps_cap = sup->ps_cap;
337 cm->a5_2 = sup->a5_2;
338 cm->a5_3 = sup->a5_3;
339 cm->cmsp = sup->cmsp;
340 cm->solsa = sup->solsa;
341 cm->lcsva = sup->lcsva;
344 /* send classmark change */
345 static int gsm_rr_tx_cm_change(struct osmocom_ms *ms)
347 struct gsm_rrlayer *rr = ms->rrlayer;
348 struct gsm_support *sup = ms->support;
349 struct msgb *msg = gsm48_rr_msgb_alloc();
350 struct gsm48_hdr *gh;
351 struct gsm48_cm_change *cc;
352 int len;
353 uint8_t buf[14];
355 if (!msg)
356 return -ENOMEM;
357 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
358 cc = (struct gsm48_cm_change *) msgb_put(msg, sizeof(*cc));
360 gh->proto = GSM48_PDISC_RR;
361 gh->msg_type = GSM48_MT_RR_CLSM_CHG;
363 /* classmark 2 */
364 cc->cm_len = sizeof(cm->cm2);
365 gsm_rr_enc_cm2(ms, &cc->cm2)
367 /* classmark 3 */
368 if (sup->dcs_1800 || sup->e_gsm || sup->r_gsm
369 || sup->a5_7 || sup->a5_6 || sup->a5_5 || sup->a5_4
370 || sup->ms_sup
371 || sup->ucs2_treat
372 || sup->ext_meas || sup->meas_cap
373 || sup->loc_serv) {
374 cm->cm2.cm3 = 1;
375 buf[0] = GSM48_IE_CLASSMARK2;
376 gsm_rr_enc_cm3(ms, buf + 2, &buf[1]);
379 return rslms_data_req(ms, msg, 0);
382 /* receiving classmark enquiry */
383 static int gsm_rr_rx_cm_enq(struct osmocom_ms *ms, struct msgb *msg)
385 struct gsm_rrlayer *rr = ms->rrlayer;
386 struct gsm48_hdr *gh = msgb_l3(msg);
387 int payload_len = msgb_l3len(msg) - sizeof(*gh);
389 /* send classmark */
390 return gsm_rr_tx_cm_change(ms);
394 * random access
397 /* send channel request burst message */
398 static int gsm_rr_tx_chan_req(struct osmocom_ms *ms, int cause)
400 struct gsm_rrlayer *rr = ms->rrlayer;
401 struct msgb *msg;
402 struct gsm_mm_hdr *mmh;
403 uint8_t chan_req;
405 /* 3.3.1.1.2 */
406 new_rr_state(rr, GSM_RRSTATE_CONN_PEND);
408 /* number of retransmissions (without first transmission) */
409 rr->n_chan_req = ms->si.max_retrans;
411 /* generate CHAN REQ (9.1.8) */
412 chan_req = random();
413 switch (cause) {
414 case RR_EST_CAUSE_EMERGENCY:
415 /* 101xxxxx */
416 chan_req &= 0x1f;
417 chan_req |= 0xa0;
418 DEBUGP(DRR, "CHANNEL REQUEST: %02x (Emergency call)\n", chan_req);
419 break;
420 case RR_EST_CAUSE_REESTAB_TCH_F:
421 chan_req &= 0x1f;
422 chan_req |= 0xc0;
423 DEBUGP(DRR, "CHANNEL REQUEST: %02x (re-establish TCH/F)\n", chan_req);
424 break;
425 case RR_EST_CAUSE_REESTAB_TCH_H:
426 if (ms->si.neci) {
427 chan_req &= 0x03;
428 chan_req |= 0x68;
429 DEBUGP(DRR, "CHANNEL REQUEST: %02x (re-establish TCH/H with NECI)\n", chan_req);
430 } else {
431 chan_req &= 0x1f;
432 chan_req |= 0xc0;
433 DEBUGP(DRR, "CHANNEL REQUEST: %02x (re-establish TCH/H no NECI)\n", chan_req);
435 break;
436 case RR_EST_CAUSE_REESTAB_2_TCH_H:
437 if (ms->si.neci) {
438 chan_req &= 0x03;
439 chan_req |= 0x6c;
440 DEBUGP(DRR, "CHANNEL REQUEST: %02x (re-establish TCH/H+TCH/H with NECI)\n", chan_req);
441 } else {
442 chan_req &= 0x1f;
443 chan_req |= 0xc0;
444 DEBUGP(DRR, "CHANNEL REQUEST: %02x (re-establish TCH/H+TCH/H no NECI)\n", chan_req);
446 break;
447 case RR_EST_CAUSE_ANS_PAG_ANY:
448 chan_req &= 0x1f;
449 chan_req |= 0x80;
450 DEBUGP(DRR, "CHANNEL REQUEST: %02x (PAGING Any channel)\n", chan_req);
451 break;
452 case RR_EST_CAUSE_ANS_PAG_SDCCH:
453 chan_req &= 0x0f;
454 chan_req |= 0x10;
455 DEBUGP(DRR, "CHANNEL REQUEST: %02x (PAGING SDCCH)\n", chan_req);
456 break;
457 case RR_EST_CAUSE_ANS_PAG_TCH_F:
458 /* ms supports no dual rate */
459 chan_req &= 0x1f;
460 chan_req |= 0x80;
461 DEBUGP(DRR, "CHANNEL REQUEST: %02x (PAGING TCH/F)\n", chan_req);
462 break;
463 case RR_EST_CAUSE_ANS_PAG_TCH_ANY:
464 /* ms supports no dual rate */
465 chan_req &= 0x1f;
466 chan_req |= 0x80;
467 DEBUGP(DRR, "CHANNEL REQUEST: %02x (PAGING TCH/H or TCH/F)\n", chan_req);
468 break;
469 case RR_EST_CAUSE_ORIG_TCHF:
470 /* ms supports no dual rate */
471 chan_req &= 0x1f;
472 chan_req |= 0xe0;
473 DEBUGP(DRR, "CHANNEL REQUEST: %02x (Orig TCH/F)\n", chan_req);
474 break;
475 case RR_EST_CAUSE_LOC_UPD:
476 if (ms->si.neci) {
477 chan_req &= 0x0f;
478 chan_req |= 0x00;
479 DEBUGP(DRR, "CHANNEL REQUEST: %02x (Location Update with NECI)\n", chan_req);
480 } else {
481 chan_req &= 0x1f;
482 chan_req |= 0x00;
483 DEBUGP(DRR, "CHANNEL REQUEST: %02x (Location Update no NECI)\n", chan_req);
485 break;
486 case RR_EST_CAUSE_OTHER_SDCCH:
487 if (ms->si.neci) {
488 chan_req &= 0x0f;
489 chan_req |= 0x01;
490 DEBUGP(DRR, "CHANNEL REQUEST: %02x (OHTER with NECI)\n", chan_req);
491 } else {
492 chan_req &= 0x1f;
493 chan_req |= 0xe0;
494 DEBUGP(DRR, "CHANNEL REQUEST: %02x (OTHER no NECI)\n", chan_req);
496 break;
497 default:
498 if (!rr->rr_est_req) /* no request from MM */
499 return -EINVAL;
501 DEBUGP(DRR, "CHANNEL REQUEST: with unknown establishment cause: %d\n", rrmsg->cause);
502 msg = gsm48_mm_msgb_alloc();
503 if (!msg)
504 return -ENOMEM;
505 mmh = (struct gsm_mm_hdr *)msg->data;
506 mmh->msg_type RR_REL_IND;
507 mmh->cause = GSM_MM_CAUSE_UNDEFINED;
508 rr_rcvmsg(ms, msg);
509 new_rr_state(rr, GSM_RRSTATE_IDLE);
510 return -EINVAL;
513 rr->wait_assign = 1;
515 /* create and send RACH msg */
516 msg = msgb_alloc_headroom(20, 16, "CHAN_REQ");
517 if (!msg)
518 return -ENOMEM;
519 *msgb_put(msg, 1) = chan_req;
520 rr->chan_req = chan_req;
521 t = ms->si.tx_integer;
522 if (t < 8)
523 t = 8;
524 *msgb_put(msg, 1) = random() % t; /* delay */
525 rr->cr_hist[3] = -1;
526 rr->cr_hist[2] = -1;
527 rr->cr_hist[1] = chan_req;
529 return rslms_tx_rll_req_l3(ms, RSL_MT_RAND_ACC_REQ, chan_nr, 0, msg);
532 /* send next channel request in conn pend state */
533 static int gsm_rr_rand_acc_cnf(struct osmocom_ms *ms, struct msgb *msg)
535 struct gsm_rrlayer *rr = ms->rrlayer;
536 struct msgb *newmsg;
537 int s;
539 if (!rr->n_chan_req) {
540 if (!timer_pending(rr->t3126))
541 start_rr_t3126(rr, GSM_T3126_MS);
542 return 0;
544 rr->n_chan_req--;
546 /* table 3.1 */
547 switch(ms->si.tx_integer) {
548 case 3: case 8: case 14: case 50:
549 if (ms->si.bcch_type == GSM_NON_COMBINED_CCCH)
550 s = 55;
551 else
552 s = 41;
553 case 4: case 9: case 16:
554 if (ms->si.bcch_type == GSM_NON_COMBINED_CCCH)
555 s = 76;
556 else
557 s = 52;
558 case 5: case 10: case 20:
559 if (ms->si.bcch_type == GSM_NON_COMBINED_CCCH)
560 s = 109;
561 else
562 s = 58;
563 case 6: case 11: case 25:
564 if (ms->si.bcch_type == GSM_NON_COMBINED_CCCH)
565 s = 163;
566 else
567 s = 86;
568 default:
569 if (ms->si.bcch_type == GSM_NON_COMBINED_CCCH)
570 s = 217;
571 else
572 s = 115;
574 /* resend chan_req */
575 newmsg = msgb_alloc_headroom(20, 16, "CHAN_REQ");
576 if (!newmsg)
577 return -ENOMEM;
578 *msgb_put(newmsg, 1) = rr->chan_req;
579 *msgb_put(newmsg, 1) = (random() % ms->si.tx_integer) + s; /* delay */
580 rr->cr_hist[3] = rr->cr_hist[2];
581 rr->cr_hist[2] = rr->cr_hist[1];
582 rr->cr_hist[1] = chan_req;
583 return rslms_tx_rll_req_l3(ms, RSL_MT_RAND_ACC_REQ, chan_nr, 0, newmsg);
587 * paging
590 /* paging channel request */
591 static int gsm_rr_chan2cause[4] = {
592 RR_EST_CAUSE_ANS_PAG_ANY,
593 RR_EST_CAUSE_ANS_PAG_SDCCH,
594 RR_EST_CAUSE_ANS_PAG_TCH_F,
595 RR_EST_CAUSE_ANS_PAG_TCH_ANY
598 /* given LV of mobile identity is checked agains ms */
599 static int gsm_match_mi(struct osmocom_ms *ms, u_int8_t mi)
601 char imsi[16];
602 u_int32_t tmsi;
604 if (mi[0] < 1)
605 return 0;
606 mi_type = mi[1] & GSM_MI_TYPE_MASK;
607 switch (mi_type) {
608 case GSM_MI_TYPE_TMSI:
609 if (mi[0] < 5)
610 return;
611 memcpy(&tmsi, mi+2, 4);
612 if (ms->subscr.tmsi == ntohl(tmsi)
613 && ms->subscr.tmsi_valid)
614 return 1;
615 break;
616 case GSM_MI_TYPE_IMSI:
617 gsm48_mi_to_string(imsi, sizeof(imsi), mi + 1, mi[0]);
618 if (!strcmp(imsi, ms->subscr.imsi))
619 return 1;
620 break;
621 default:
622 DEBUGP(DRR, "paging with unsupported MI type %d.\n", mi_type);
625 return 0;
628 /* paging request 1 message */
629 static int gsm_rr_rx_pag_req_1(struct osmocom_ms *ms, struct msgb *msg)
631 struct gsm_rrlayer *rr = ms->rrlayer;
632 struct gsm48_rr_paging1 *pa = msgb_l3(msg);
633 int payload_len = msgb_l3len(msg) - sizeof(*pa);
634 int chan_first, chan_second;
635 uint8_t mi;
637 /* 3.3.1.1.2: ignore paging while establishing */
638 if (rr->state != GSM_RRSTATE_IDLE)
639 return 0;
641 if (payload_len < 2) {
642 short:
643 DEBUGP(DRR, "Short read of paging request 1 message .\n");
644 return -EINVAL;
647 /* channel needed */
648 chan_first = pa->cneed1;
649 chan_second = pa->cneed2;
650 /* first MI */
651 mi = pa->data + 1;
652 if (payload_len < mi[0] + 1)
653 goto short;
654 if (gsm_match_mi(ms, mi) > 0)
655 return gsm_rr_tx_chan_req(ms, gsm_rr_chan2cause[chan_first]);
656 /* second MI */
657 payload_len -= mi[0] + 1;
658 mi = pa->data + mi[0] + 1;
659 if (payload_len < 2)
660 return 0;
661 if (mi[0] != GSM48_IE_MOBILE_ID)
662 return 0;
663 if (payload_len < mi[1] + 2)
664 goto short;
665 if (gsm_match_mi(ms, mi + 1) > 0)
666 return gsm_rr_tx_chan_req(ms, gsm_rr_chan2cause[chan_second]);
668 return 0;
671 /* paging request 2 message */
672 static int gsm_rr_rx_pag_req_2(struct osmocom_ms *ms, struct gsm_msgb *msg)
674 struct gsm_rrlayer *rr = ms->rrlayer;
675 struct gsm48_rr_paging2 *pa = msgb_l3(msg);
676 int payload_len = msgb_l3len(msg) - sizeof(*pa);
677 u_int32_t tmsi;
678 int chan_first, chan_second, chan_third;
680 /* 3.3.1.1.2: ignore paging while establishing */
681 if (rr->state != GSM_RRSTATE_IDLE)
682 return 0;
684 if (payload_len < 0) {
685 short:
686 DEBUGP(DRR, "Short read of paging request 2 message .\n");
687 return -EINVAL;
690 /* channel needed */
691 chan_first = pa->cneed1;
692 chan_second = pa->cneed2;
693 /* first MI */
694 if (ms->subscr.tmsi == ntohl(pa->tmsi1)
695 && ms->subscr.tmsi_valid)
696 return gsm_rr_tx_chan_req(ms, gsm_rr_chan2cause[chan_first]);
697 /* second MI */
698 if (ms->subscr.tmsi == ntohl(pa->tmsi2)
699 && ms->subscr.tmsi_valid)
700 return gsm_rr_tx_chan_req(ms, gsm_rr_chan2cause[chan_second]);
701 /* third MI */
702 mi = pa->data;
703 if (payload_len < 2)
704 return 0;
705 if (mi[0] != GSM48_IE_MOBILE_ID)
706 return 0;
707 if (payload_len < mi[1] + 2 + 1) /* must include "channel needed" */
708 goto short;
709 chan_third = mi[mi[1] + 2] & 0x03; /* channel needed */
710 if (gsm_match_mi(ms, mi + 1) > 0)
711 return gsm_rr_tx_chan_req(ms, gsm_rr_chan2cause[chan_third]);
713 return 0;
716 /* paging request 3 message */
717 static int gsm_rr_rx_pag_req_3(struct osmocom_ms *ms, struct gsm_msgb *msg)
719 struct gsm_rrlayer *rr = ms->rrlayer;
720 struct gsm48_rr_paging3 *pa = msgb_l3(msg);
721 int payload_len = msgb_l3len(msg) - sizeof(*pa);
722 u_int32_t tmsi;
723 int chan_first, chan_second, chan_third, chan_fourth;
725 /* 3.3.1.1.2: ignore paging while establishing */
726 if (rr->state != GSM_RRSTATE_IDLE)
727 return 0;
729 if (payload_len < 0) { /* must include "channel needed", part of *pa */
730 short:
731 DEBUGP(DRR, "Short read of paging request 3 message .\n");
732 return -EINVAL;
735 /* channel needed */
736 chan_first = pa->cneed1;
737 chan_second = pa->cneed2;
738 chan_third = pa->cneed3;
739 chan_fourth = pa->cneed4;
740 /* first MI */
741 if (ms->subscr.tmsi == ntohl(pa->tmsi1)
742 && ms->subscr.tmsi_valid)
743 return gsm_rr_tx_chan_req(ms, gsm_rr_chan2cause[chan_first]);
744 /* second MI */
745 if (ms->subscr.tmsi == ntohl(pa->tmsi2)
746 && ms->subscr.tmsi_valid)
747 return gsm_rr_tx_chan_req(ms, gsm_rr_chan2cause[chan_second]);
748 /* thrid MI */
749 if (ms->subscr.tmsi == ntohl(pa->tmsi3)
750 && ms->subscr.tmsi_valid)
751 return gsm_rr_tx_chan_req(ms, gsm_rr_chan2cause[chan_third]);
752 /* fourth MI */
753 if (ms->subscr.tmsi == ntohl(pa->tmsi4)
754 && ms->subscr.tmsi_valid)
755 return gsm_rr_tx_chan_req(ms, gsm_rr_chan2cause[chan_fourth]);
757 return 0;
761 * (immediate) assignment
764 /* match request reference agains request history */
765 static int gsm_match_ra(struct osmocom_ms *ms, struct gsm48_req_ref *req)
767 struct gsm_rrlayer *rr = ms->rrlayer;
768 int i;
770 for (i = 0; i < 3; i++) {
771 if (rr->cr_hist[i] >= 0
772 && ref->ra == rr->cr_hist[i]) {
773 // todo: match timeslot
774 return 1;
778 return 0;
781 /* transmit assignment complete after establishing link */
782 static int gsm_rr_tx_ass_cpl(struct osmocom_ms *ms, uint8_t cause)
784 struct gsm_rrlayer *rr = ms->rrlayer;
785 struct msgb *msg = gsm48_rr_msgb_alloc();
786 struct gsm48_hdr *gh;
787 struct gsm48_ass_cpl *ac;
789 if (!msg)
790 return -ENOMEM;
791 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
792 ac = (struct gsm48_ass_cpl *) msgb_put(msg, sizeof(*ac));
794 gh->proto = GSM48_PDISC_RR;
795 gh->msg_type = GSM48_MT_RR_ASS_COMPL;
797 /* RR_CAUSE */
798 ac->rr_cause = cause;
800 return rslms_data_req(ms, msg, 0);
803 /* transmit failure to old link */
804 static int gsm_rr_tx_ass_fail(struct osmocom_ms *ms, uint8_t cause)
806 struct gsm_rrlayer *rr = ms->rrlayer;
807 struct msgb *msg = gsm48_rr_msgb_alloc();
808 struct gsm48_hdr *gh;
809 struct gsm48_ass_fail *ac;
811 if (!msg)
812 return -ENOMEM;
813 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
814 af = (struct gsm48_ass_fail *) msgb_put(msg, sizeof(*af));
816 gh->proto = GSM48_PDISC_RR;
817 gh->msg_type = GSM48_MT_RR_ASS_COMPL;
819 /* RR_CAUSE */
820 af->rr_cause = cause;
822 return rslms_data_req(ms, msg, 0);
825 /* receive immediate assignment */
826 static int gsm_rr_rx_imm_ass(struct osmocom_ms *ms, struct gsm_msgb *msg)
828 struct gsm_rrlayer *rr = ms->rrlayer;
829 struct gsm48_imm_ass *ia = msgb_l3(msg);
830 int payload_len = msgb_l3len(msg) - sizeof(*ia);
832 /* 3.3.1.1.2: ignore assignment while idle */
833 if (rr->state != GSM_RRSTATE_CONN_PEND || !rr->wait_assign)
834 return 0;
836 if (payload_len < 1 /* mobile allocation IE must be included */
837 || *gh->data + 1 > payload_len) { /* short read of IE */
838 DEBUGP(DRR, "Short read of immediate assignment message.\n");
839 return -EINVAL;
841 if (*gh->data > 8) {
842 DEBUGP(DRR, "moble allocation in immediate assignment too large.\n");
843 return -EINVAL;
846 /* request ref */
847 if (gsm_match_ra(ms, ia->req_ref)) {
848 /* channel description */
849 memset(&rr->chan_desc, 0, sizeof(cd));
850 memcpy(rr->chan_desc.chan_desc, ia->chan_desc, 3);
851 /* timing advance */
852 rr->timing_advance = ia->timing_advance;
853 /* mobile allocation */
854 memcpy(rr->mobile_alloc_lv, gh->data, *gh->data + 1);
855 rr->wait_assing = 0;
856 return gsm_rr_dl_est(ms);
859 return 0;
862 /* receive immediate assignment extended */
863 static int gsm_rr_rx_imm_ass_ext(struct osmocom_ms *ms, struct gsm_msgb *msg)
865 struct gsm_rrlayer *rr = ms->rrlayer;
866 struct gsm48_imm_ass_ext *ia = msgb_l3(msg);
867 int payload_len = msgb_l3len(msg) - sizeof(*ia);
869 /* 3.3.1.1.2: ignore assignment while idle */
870 if (rr->state != GSM_RRSTATE_CONN_PEND || !rr->wait_assign)
871 return 0;
873 if (payload_len < 1 /* mobile allocation IE must be included */
874 || *gh->data + 1 > payload_len) { /* short read of IE */
875 DEBUGP(DRR, "Short read of immediate assignment extended message.\n");
876 return -EINVAL;
878 if (*gh->data > 4) {
879 DEBUGP(DRR, "moble allocation in immediate assignment extended too large.\n");
880 return -EINVAL;
883 /* request ref 1 */
884 if (gsm_match_ra(ms, ia->req_ref1)) {
885 /* channel description */
886 memset(&rr->chan_desc, 0, sizeof(cd));
887 memcpy(rr->chan_desc.chan_desc, ia->chan_desc1, 3);
888 /* timing advance */
889 rr->timing_advance = ia->timing_advance1;
890 /* mobile allocation */
891 memcpy(rr->mobile_alloc_lv, gh->data, *gh->data + 1);
892 rr->wait_assing = 0;
893 return gsm_rr_dl_est(ms);
895 /* request ref 1 */
896 if (gsm_match_ra(ms, ia->req_ref2)) {
897 /* channel description */
898 memset(&rr->chan_desc, 0, sizeof(cd));
899 memcpy(rr->chan_desc.chan_desc, ia->chan_desc2, 3);
900 /* timing advance */
901 rr->timing_advance = ia->timing_advance2;
902 /* mobile allocation */
903 memcpy(rr->mobile_alloc_lv, gh->data, *gh->data + 1);
904 rr->wait_assing = 0;
905 return gsm_rr_dl_est(ms);
908 return 0;
911 /* receive immediate assignment reject */
912 static int gsm_rr_rx_imm_ass_rej(struct osmocom_ms *ms, struct gsm_msgb *msg)
914 struct gsm_rrlayer *rr = ms->rrlayer;
915 struct gsm48_imm_ass_rej *ia = msgb_l3(msg);
916 int payload_len = msgb_l3len(msg) - sizeof(*ia);
917 int i;
918 struct gsm48_req_ref *req_ref;
919 uint8_t t3122_value;
921 /* 3.3.1.1.2: ignore assignment while idle */
922 if (rr->state != GSM_RRSTATE_CONN_PEND || !rr->wait_assign)
923 return 0;
925 if (payload_len < 0) {
926 short:
927 DEBUGP(DRR, "Short read of immediate assignment reject message.\n");
928 return -EINVAL;
931 for (i = 0; i < 4; i++) {
932 /* request reference */
933 req_ref = (struct gsm48_req_ref *)(((uint8_t *)&ia->req_ref1) + i * 4);
934 if (gsm_match_ra(ms, req_ref)) {
935 /* wait indication */
936 t3122_value = ((uint8_t *)&ia->wait_ind1) + i * 4;
937 if (t3122_value)
938 start_rr_t3122(rr, t3122_value, 0);
939 /* start timer 3126 if not already */
940 if (!timer_pending(rr->t3126))
941 start_rr_t3126(rr, GSM_T3126_MS);
942 /* stop assignmnet requests */
943 rr->n_chan_req = 0;
945 /* wait until timer 3126 expires, then release
946 * or wait for channel assignment */
947 return 0;
951 return 0;
954 /* receive additional assignment */
955 static int gsm_rr_rx_add_ass(struct osmocom_ms *ms, struct msgb *msg)
957 struct gsm_rrlayer *rr = ms->rrlayer;
958 struct gsm48_hdr *gh = msgb_l3(msg);
959 struct gsm48_add_ass *aa = (struct gsm48_add_ass *)gh->data;
960 int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*aa);
962 if (payload_len < 0) {
963 DEBUGP(DRR, "Short read of ADDITIONAL ASSIGNMENT message.\n");
964 return gsm_rr_tx_rr_status(ms, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
966 tlv_parse(&tp, &rsl_att_tlvdef, aa->data, payload_len, 0, 0);
968 return gsm_rr_tx_rr_status(ms, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
972 * measturement reports
975 static int gsm_rr_tx_meas_rep(struct osmocom_ms *ms)
977 struct gsm_rrlayer *rr = ms->rrlayer;
978 struct gsm_rr_meas *meas = &rr->meas;
979 struct msgb *msg = gsm48_rr_msgb_alloc();
980 struct gsm48_hdr *gh;
981 struct gsm48_meas_res *mr;
983 if (!msg)
984 return -ENOMEM;
985 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
986 mr = (struct gsm48_meas_res *) msgb_put(msg, sizeof(*mr));
988 gh->proto = GSM48_PDISC_RR;
989 gh->msg_type = GSM48_MT_RR_MEAS_RES;
991 /* measurement results */
992 mr->rxlev_full = meas->rxlev_full;
993 mr->rxlev_sub = meas->rxlev_sub;
994 mr->rxqual_full = meas->rxqual_full;
995 mr->rxqual_sub = meas->rxqual_sub;
996 mr->dtx = meas->dtx;
997 mr->ba = meas->ba;
998 mr->meas_valid = meas->meas_valid;
999 if (meas->ncell_na) {
1000 /* no results for serving cells */
1001 mr->no_n_hi = 1;
1002 mr->no_n_lo = 3;
1003 } else {
1004 mr->no_n_hi = meas->count >> 2;
1005 mr->no_n_lo = meas->count & 3;
1007 rxlev_nc1 = meas->rxlev_nc[0];
1008 rxlev_nc2_hi = meas->rxlev_nc[1] >> 1;
1009 rxlev_nc2_lo = meas->rxlev_nc[1] & 1;
1010 rxlev_nc3_hi = meas->rxlev_nc[2] >> 2;
1011 rxlev_nc3_lo = meas->rxlev_nc[2] & 3;
1012 rxlev_nc4_hi = meas->rxlev_nc[3] >> 3;
1013 rxlev_nc4_lo = meas->rxlev_nc[3] & 7;
1014 rxlev_nc5_hi = meas->rxlev_nc[4] >> 4;
1015 rxlev_nc5_lo = meas->rxlev_nc[4] & 15;
1016 rxlev_nc6_hi = meas->rxlev_nc[5] >> 5;
1017 rxlev_nc6_lo = meas->rxlev_nc[5] & 31;
1018 bsic_nc1_hi = meas->bsic_nc[0] >> 3;
1019 bsic_nc1_lo = meas->bsic_nc[0] & 7;
1020 bsic_nc2_hi = meas->bsic_nc[1] >> 4;
1021 bsic_nc2_lo = meas->bsic_nc[1] & 15;
1022 bsic_nc3_hi = meas->bsic_nc[2] >> 5;
1023 bsic_nc3_lo = meas->bsic_nc[2] & 31;
1024 bsic_nc4 = meas->bsic_nc[3];
1025 bsic_nc5 = meas->bsic_nc[4];
1026 bsic_nc6 = meas->bsic_nc[5];
1027 bcch_f_nc1 = meas->bcch_f_nc[0];
1028 bcch_f_nc2 = meas->bcch_f_nc[1];
1029 bcch_f_nc3 = meas->bcch_f_nc[2];
1030 bcch_f_nc4 = meas->bcch_f_nc[3];
1031 bcch_f_nc5_hi = meas->bcch_f_nc[4] >> 1;
1032 bcch_f_nc5_lo = meas->bcch_f_nc[4] & 1;
1033 bcch_f_nc6_hi = meas->bcch_f_nc[5] >> 2;
1034 bcch_f_nc6_lo = meas->bcch_f_nc[5] & 3;
1036 //todo return rslms_data_req(ms, msg, 0);
1040 * link establishment and release
1043 /* activate link and send establish request */
1044 static int gsm_rr_dl_est(struct osmocom_ms *ms)
1046 struct gsm_rrlayer *rr = ms->rrlayer;
1047 struct gsm_subscriber *subcr = ms->subscr;
1048 struct msgb *msg;
1049 struct gsm48_hdr *gh;
1050 struct gsm48_pag_rsp *pa;
1052 /* 3.3.1.1.3.1 */
1053 stop_rr_t3126(rr);
1055 /* flush pending RACH requests */
1056 rr->n_chan_req = 0; // just to be safe
1057 msg = msgb_alloc_headroom(20, 16, "RAND_FLUSH");
1058 if (!msg)
1059 return -ENOMEM;
1060 rslms_tx_rll_req_l3(ms, RSL_MT_RAND_ACC_FLSH, chan_nr, 0, msg);
1062 /* send DL_EST_REQ */
1063 if (rr->rr_est_msg) {
1064 /* use queued message */
1065 msg = rr->rr_est_msg;
1066 rr->rr_est_msg = 0;
1067 } else {
1068 uint8_t mi[11];
1070 /* create paging response */
1071 msg = gsm48_rr_msgb_alloc();
1072 if (!msg)
1073 return -ENOMEM;
1074 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1075 pr = (struct gsm48_pag_rsp *) msgb_put(msg, sizeof(*pr));
1076 /* key sequence */
1077 if (subscr->key_valid)
1078 pr->key_seq = subscr->key_seq;
1079 else
1080 pr->key_seq = 7;
1081 /* classmark 2 */
1082 cc->cm_len = sizeof(cm->cm2);
1083 gsm_rr_enc_cm2(ms, &cc->cm2)
1084 /* mobile identity */
1085 if (ms->subscr.tmsi_valid) {
1086 gsm48_generate_mid_from_tmsi(mi, subscr->tmsi);
1087 } else if (subscr->imsi[0])
1088 gsm48_generate_mid_from_imsi(mi, subscr->imsi);
1089 else {
1090 mi[1] = 1;
1091 mi[2] = 0xf0 | GSM_MI_TYPE_NONE;
1093 msgb_put(msg, 1 + mi[1]);
1094 memcpy(cm->data, mi + 1, 1 + mi[1]);
1097 /* activate channel */
1098 tx_ph_dm_est_req(ms, arfcn, rr->chan_desc.chan_desc.chan_nr);
1100 /* start establishmnet */
1101 return rslms_tx_rll_req_l3(ms, RSL_MT_EST_REQ, rr->chan_desc.chan_desc.chan_nr, 0, msg);
1104 /* the link is established */
1105 static int gsm_rr_estab_cnf(struct osmocom_ms *ms, struct msgb *msg)
1107 struct msgb *newmsg;
1108 struct gsm_mm_hdr *newmmh;
1110 /* if MM has releases before confirm, we start release */
1111 if (rr->state == GSM_RRSTATE_IDLE) {
1112 /* release message */
1113 newmsg = gsm48_rr_msgb_alloc();
1114 if (!newmsg)
1115 return -ENOMEM;
1116 /* start release */
1117 return rslms_tx_rll_req_l3(ms, RSL_MT_REL_REQ, 0, 0, newmsg);
1120 /* 3.3.1.1.4 */
1121 new_rr_state(rr, GSM_RRSTATE_DEDICATED);
1123 /* send confirm to upper layer */
1124 newmsg = gsm48_mm_msgb_alloc();
1125 if (!newmsg)
1126 return -ENOMEM;
1127 newmmh = (struct gsm_mm_hdr *)newmsg->data;
1128 newmmh->msg_type = (rr->rr_est_req) ? RR_EST_CNF : RR_EST_IND;
1129 return rr_rcvmsg(ms, newmsg);
1132 /* the link is released */
1133 static int gsm_rr_rel_cnf(struct osmocom_ms *ms, struct gsm_dl *dlmsg)
1135 /* deactivate channel */
1136 tx_ph_dm_rel_req(ms, arfcn, rr->chan_desc.chan_desc.chan_nr);
1138 /* do nothing, because we aleady IDLE
1139 * or we received the rel cnf of the last connection
1140 * while already requesting a new one (CONN PEND)
1143 return 0;
1147 * radio ressource requests
1150 /* establish request for dedicated mode */
1151 static int gsm_rr_est_req(struct osmocom_ms *ms, struct msgb *msg)
1153 struct gsm_rrlayer *rr = ms->rrlayer;
1154 struct gsm_mm_hdr *mmh = msgb->data;
1155 struct gsm48_hdr *gh = msgb_l3(msg);
1157 /* 3.3.1.1.3.2 */
1158 if (timer_pending(rr->t3122)) {
1159 if (rrmsg->cause != RR_EST_CAUSE_EMERGENCY) {
1160 struct msgb *newmsg;
1161 struct gsm_mm_hdr *newmmh;
1163 newmsg = gsm48_mm_msgb_alloc();
1164 if (!newmsg)
1165 return -ENOMEM;
1166 newmmh = (struct gsm_mm_hdr *)newmsg->data;
1167 newmmh->msg_type RR_REL_IND;
1168 newmmh->cause = GSM_MM_CAUSE_T3122_PEND;
1169 return rr_rcvmsg(ms, newmsg);
1170 } else
1171 stop_rr_t3122(rr);
1174 /* 3.3.1.1.1 */
1175 if (rrmsg->cause != RR_EST_CAUSE_EMERGENCY) {
1176 if (!(ms->access_class & ms->si.access_class)) {
1177 reject:
1178 if (!ms->opt.access_class_override) {
1179 struct msgb *newmsg;
1180 struct gsm_mm_hdr *newmmh;
1182 newmsg = gsm48_mm_msgb_alloc();
1183 if (!newmsg)
1184 return -ENOMEM;
1185 newmmh = (struct gsm_mm_hdr *)newmsg->data;
1186 newmmh->msg_type RR_REL_IND;
1187 newmmh->cause = GSM_MM_CAUSE_NOT_AUTHORIZED;
1188 return rr_rcvmsg(ms, newmsg);
1191 } else {
1192 if (!(ms->access_class & ms->si.access_class)
1193 && !ms->si.emergency)
1194 goto reject;
1197 /* requested by RR */
1198 rr->rr_est_req = 1;
1200 /* clone and store REQUEST message */
1201 if (!gh) {
1202 printf("Error, missing l3 message\n");
1203 return -EINVAL;
1205 rr->rr_est_msg = msgb_alloc_headroom(256, 16, "EST_REQ");
1206 if (!rr->rr_est_msg)
1207 return -ENOMEM;
1208 memcpy(msgb_put(rr_est_msg, msgb_l3len(msg)),
1209 msgb_l3(msg), msgb_l3len(msg));
1211 /* request channel */
1212 return gsm_rr_tx_chan_req(ms, mmh->cause);
1215 /* send all queued messages down to layer 2 */
1216 static int gsm_rr_dequeue_down(struct osmocom_ms *ms)
1218 struct gsm_rrlayer *rr = ms->rrlayer;
1219 struct msgb *msg;
1221 while((msg = msgb_dequeue(&rr->downqueue))) {
1222 rslms_tx_rll_req_l3(ms, RSL_MT_DATA_REQ, chan_nr, 0, msg);
1225 return 0;
1228 /* 3.4.2 transfer data in dedicated mode */
1229 static int gsm_rr_data_req(struct osmocom_ms *ms, struct msgb *msg)
1231 struct gsm_rrlayer *rr = ms->rrlayer;
1233 if (rr->state != GSM_RRSTATE_DEDICATED) {
1234 msgb_free(msg)
1235 return -EINVAL;
1238 /* pull header */
1239 msgb_pull(msg, sizeof(struct gsm_mm_hdr));
1241 /* queue message, during handover or assignment procedure */
1242 if (rr->hando_susp_state || rr->assign_susp_state) {
1243 msgb_enqueue(&rr->downqueue, msg);
1244 return 0;
1247 /* forward message */
1248 return rslms_tx_rll_req_l3(ms, RSL_MT_DATA_REQ, chan_nr, 0, msg);
1252 * data indications from data link
1255 /* 3.4.2 data from layer 2 to RR and upper layer*/
1256 static int gsm_rr_data_ind(struct osmocom_ms *ms, struct msbg *msg)
1258 struct gsm48_hdr *gh = msgb_l3(msg);
1259 u_int8_t pdisc = gh->proto_discr & 0x0f;
1261 if (pdisc == GSM48_PDISC_RR) {
1262 int rc = -EINVAL;
1264 switch(gh->msg_type) {
1265 case GSM48_MT_RR_ADD_ASS:
1266 rc = gsm_rr_rx_add_ass(ms, msg);
1267 break;
1268 case GSM48_MT_RR_ASS_CMD:
1269 rc = gsm_rr_rx_ass_cmd(ms, msg);
1270 break;
1271 case GSM48_MT_RR_CIP_MODE_CMD:
1272 rc = gsm_rr_rx_cip_mode_cmd(ms, msg);
1273 break;
1274 case GSM48_MT_RR_CLSM_ENQ:
1275 rc = gsm_rr_rx_cm_enq(ms, msg);
1276 break;
1277 case GSM48_MT_RR_HANDO_CMD:
1278 rc = gsm_rr_rx_hando_cmd(ms, msg);
1279 break;
1280 case GSM48_MT_RR_FREQ_REDEF:
1281 rc = gsm_rr_rx_freq_redef(ms, msg);
1282 break;
1283 default:
1284 DEBUGP(DRR, "Message type 0x%02x unknown.\n", gh->msg_type);
1287 free_msgb(msg);
1288 return rc;
1291 /* push header */
1292 msgb_push(msg, sizeof(struct gsm_mm_hdr));
1293 mmh = (struct gsm_mm_hdr *)msg->data;
1294 mmh->msg_type = RR_DATA_IND;
1295 /* forward message */
1296 return rr_rcvmsg(ms, msg);
1299 /* unit data from layer 2 to RR layer */
1300 static int gsm_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
1302 struct gsm48_hdr *gh = msgb_l3(msg);
1304 switch (gh->msg_type) {
1305 case GSM48_MT_RR_PAG_REQ_1:
1306 return gsm_rr_rx_pag_req_1(ms, dlmsg->msg);
1307 case GSM48_MT_RR_PAG_REQ_2:
1308 return gsm_rr_rx_pag_req_2(ms, dlmsg->msg);
1309 case GSM48_MT_RR_PAG_REQ_3:
1310 return gsm_rr_rx_pag_req_3(ms, dlmsg->msg);
1311 case GSM48_MT_RR_IMM_ASS:
1312 return gsm_rr_rx_imm_ass(ms, dlmsg->msg);
1313 case GSM48_MT_RR_IMM_ASS_EXT:
1314 return gsm_rr_rx_imm_ass_ext(ms, dlmsg->msg);
1315 case GSM48_MT_RR_IMM_ASS_REJ:
1316 return gsm_rr_rx_imm_ass_rej(ms, dlmsg->msg);
1317 default:
1318 DEBUGP(DRR, "Message type 0x%02x unknown.\n", gh->msg_type);
1319 return -EINVAL;
1325 complete
1326 -------------------------------------------------------------------------------
1327 uncomplete
1346 * system information
1349 /* decode "Cell Channel Description" (10.5.2.1b) and other frequency lists */
1350 static int gsm48_decode_freq_list(struct gsm_sysinfo_freq *f, uint8_t *cd, uint8_t len, uint8_t mask, uint8_t frqt)
1352 int i;
1354 /* NOTES:
1356 * The Range format uses "SMOD" computation.
1357 * e.g. "n SMOD m" equals "((n - 1) % m) + 1"
1358 * A cascade of multiple SMOD computations is simpified:
1359 * "(n SMOD m) SMOD o" equals "(((n - 1) % m) % o) + 1"
1361 * The Range format uses 16 octets of data in SYSTEM INFORMATION.
1362 * When used in dedicated messages, the length can be less.
1363 * In this case the ranges are decoded for all frequencies that
1364 * fit in the block of given length.
1367 /* tabula rasa */
1368 for (i = 0; i < 1024; i++)
1369 f[i].mask &= ~frqt;
1371 /* 00..XXX. */
1372 if ((cd[0] & 0xc0 & mask) == 0x00) {
1373 /* Bit map 0 format */
1374 if (len < 16)
1375 return -EINVAL;
1376 for (i = 1; i <= 124; i++)
1377 if ((cd[15 - ((i-1) >> 3)] & (1 << ((i-1) & 7))))
1378 f[i].mask |= frqt;
1380 return 0;
1383 /* only Bit map 0 format for P-GSM */
1384 if (ms->support.p_gsm && !ms->support.e_gsm
1385 && !ms->support.r_gsm && !ms->support.dcs_1800)
1386 return 0;
1388 /* 10..0XX. */
1389 if ((cd[0] & 0xc8 & mask) == 0x80) {
1390 /* Range 1024 format */
1391 uint16_t w[17]; /* 1..16 */
1392 struct gsm_range_1024 *r = (struct gsm_range_1024 *)cd;
1394 if (len < 2)
1395 return -EINVAL;
1396 memset(w, 0, sizeof(w));
1397 if (r->f0)
1398 f[0].mask |= frqt;
1399 w[1] = (r->w1_hi << 8) | r->w1_lo;
1400 if (len >= 4)
1401 w[2] = (r->w2_hi << 1) | r->w2_lo;
1402 if (len >= 5)
1403 w[3] = (r->w3_hi << 2) | r->w3_lo;
1404 if (len >= 6)
1405 w[4] = (r->w4_hi << 2) | r->w4_lo;
1406 if (len >= 7)
1407 w[5] = (r->w5_hi << 2) | r->w5_lo;
1408 if (len >= 8)
1409 w[6] = (r->w6_hi << 2) | r->w6_lo;
1410 if (len >= 9)
1411 w[7] = (r->w7_hi << 2) | r->w7_lo;
1412 if (len >= 10)
1413 w[8] = (r->w8_hi << 1) | r->w8_lo;
1414 if (len >= 10)
1415 w[9] = r->w9;
1416 if (len >= 11)
1417 w[10] = r->w10;
1418 if (len >= 12)
1419 w[11] = (r->w11_hi << 6) | r->w11_lo;
1420 if (len >= 13)
1421 w[12] = (r->w12_hi << 5) | r->w12_lo;
1422 if (len >= 14)
1423 w[13] = (r->w13_hi << 4) | r->w13_lo;
1424 if (len >= 15)
1425 w[14] = (r->w14_hi << 3) | r->w14_lo;
1426 if (len >= 16)
1427 w[15] = (r->w15_hi << 2) | r->w15_lo;
1428 if (len >= 16)
1429 w[16] = r->w16;
1430 if (w[1])
1431 f[w[1]].mask |= frqt;
1432 if (w[2])
1433 f[((w[1] - 512 + w[2] - 1) % 1023) + 1].mask |= frqt;
1434 if (w[3])
1435 f[((w[1] + w[3] - 1) % 1023) + 1].mask |= frqt;
1436 if (w[4])
1437 f[((w[1] - 512 + ((w[2] - 256 + w[4] - 1) % 511)) % 1023) + 1].mask |= frqt;
1438 if (w[5])
1439 f[((w[1] + ((w[3] - 256 - w[5] - 1) % 511)) % 1023) + 1].mask |= frqt;
1440 if (w[6])
1441 f[((w[1] - 512 + ((w[2] + w[6] - 1) % 511)) % 1023) + 1].mask |= frqt;
1442 if (w[7])
1443 f[((w[1] + ((w[3] + w[7] - 1) % 511)) % 1023) + 1].mask |= frqt;
1444 if (w[8])
1445 f[((w[1] - 512 + ((w[2] - 256 + ((w[4] - 128 + w[8] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
1446 if (w[9])
1447 f[((w[1] + ((w[3] - 256 + ((w[5] - 128 + w[9] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
1448 if (w[10])
1449 f[((w[1] - 512 + ((w[2] + ((w[6] - 128 + w[10] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
1450 if (w[11])
1451 f[((w[1] + ((w[3] + ((w[7] - 128 + w[11] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
1452 if (w[12])
1453 f[((w[1] - 512 + ((w[2] - 256 + ((w[4] + w[12] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
1454 if (w[13])
1455 f[((w[1] + ((w[3] - 256 + ((w[5] + w[13] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
1456 if (w[14])
1457 f[((w[1] - 512 + ((w[2] + ((w[6] + w[14] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
1458 if (w[15])
1459 f[((w[1] + ((w[3] + ((w[7] + w[15] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt;
1460 if (w[16])
1461 f[((w[1] - 512 + ((w[2] - 256 + ((w[4] - 128 + ((w[8] - 64 + w[16] - 1) % 127)) % 255)) % 511)) % 1023) + 1].mask |= frqt;
1463 return 0;
1465 /* 10..100. */
1466 if ((cd[0] & 0xce & mask) == 0x88) {
1467 /* Range 512 format */
1468 uint16_t w[18]; /* 1..17 */
1469 struct gsm_range_512 *r = (struct gsm_range_512 *)cd;
1471 if (len < 4)
1472 return -EINVAL;
1473 memset(w, 0, sizeof(w));
1474 w[0] = (r->orig_arfcn_hi << 9) || (r->orig_arfcn_mid << 1) || r->orig_arfcn_lo;
1475 w[1] = (r->w1_hi << 2) || r->w1_lo;
1476 if (len >= 5)
1477 w[2] = (r->w2_hi << 2) || r->w2_lo;
1478 if (len >= 6)
1479 w[3] = (r->w3_hi << 2) || r->w3_lo;
1480 if (len >= 7)
1481 w[4] = (r->w4_hi << 1) || r->w4_lo;
1482 if (len >= 7)
1483 w[5] = r->w5;
1484 if (len >= 8)
1485 w[6] = r->w6;
1486 if (len >= 9)
1487 w[7] = (r->w7_hi << 6) || r->w7_lo;
1488 if (len >= 10)
1489 w[8] = (r->w8_hi << 4) || r->w8_lo;
1490 if (len >= 11)
1491 w[9] = (r->w9_hi << 2) || r->w9_lo;
1492 if (len >= 11)
1493 w[10] = r->w10;
1494 if (len >= 12)
1495 w[11] = r->w11;
1496 if (len >= 13)
1497 w[12] = (r->w12_hi << 4) || r->w12_lo;
1498 if (len >= 14)
1499 w[13] = (r->w13_hi << 2) || r->w13_lo;
1500 if (len >= 14)
1501 w[14] = r->w14;
1502 if (len >= 15)
1503 w[15] = r->w15;
1504 if (len >= 16)
1505 w[16] = (r->w16_hi << 3) || r->w16_lo;
1506 if (len >= 16)
1507 w[17] = r->w17;
1508 if (w[0])
1509 f[w[0]].mask |= frqt;
1510 if (w[1])
1511 f[(w[0] + w[1]) % 1024].mask |= frqt;
1512 if (w[2])
1513 f[(w[0] + ((w[1] - 256 + w[2] - 1) % 511) + 1) % 1024].mask |= frqt;
1514 if (w[3])
1515 f[(w[0] + ((w[1] + w[3] - 1) % 511) + 1) % 1024].mask |= frqt;
1516 if (w[4])
1517 f[(w[0] + ((w[1] - 256 + ((w[2] - 128 + w[4] - 1) % 255)) % 511) + 1) % 1024].mask |= frqt;
1518 if (w[5])
1519 f[(w[0] + ((w[1] + ((w[3] - 128 + w[5] - 1) % 255)) % 511) + 1) % 1024].mask |= frqt;
1520 if (w[6])
1521 f[(w[0] + ((w[1] - 256 + ((w[2] + w[6] - 1) % 255)) % 511) + 1) % 1024].mask |= frqt;
1522 if (w[7])
1523 f[(w[0] + ((w[1] + ((w[3] + w[7] - 1) % 255)) % 511) + 1) % 1024].mask |= frqt;
1524 if (w[8])
1525 f[(w[0] + ((w[1] - 256 + ((w[2] - 128 + ((w[4] - 64 + w[8] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
1526 if (w[9])
1527 f[(w[0] + ((w[1] + ((w[3] - 128 + ((w[5] - 64 + w[9] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
1528 if (w[10])
1529 f[(w[0] + ((w[1] - 256 + ((w[2] + ((w[6] - 64 + w[10] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
1530 if (w[11])
1531 f[(w[0] + ((w[1] + ((w[3] + ((w[7] - 64 + w[11] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
1532 if (w[12])
1533 f[(w[0] + ((w[1] - 256 + ((w[2] - 128 + ((w[4] + w[12] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
1534 if (w[13])
1535 f[(w[0] + ((w[1] + ((w[3] - 128 + ((w[5] + w[13] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
1536 if (w[14])
1537 f[(w[0] + ((w[1] - 256 + ((w[2] + ((w[6] + w[14] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
1538 if (w[15])
1539 f[(w[0] + ((w[1] + ((w[3] + ((w[7] + w[15] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
1540 if (w[16])
1541 f[(w[0] + ((w[1] - 256 + ((w[2] - 128 + ((w[4] - 64 + ((w[8] - 32 + w[16] - 1) % 63)) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
1542 if (w[17])
1543 f[(w[0] + ((w[1] + ((w[3] - 128 + ((w[5] - 64 + ((w[9] - 32 + w[17] - 1) % 63)) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt;
1545 return 0;
1547 /* 10..101. */
1548 if ((cd[0] & & mask 0xce) == 0x8a) {
1549 /* Range 256 format */
1550 uint16_t w[22]; /* 1..21 */
1551 struct gsm_range_256 *r = (struct gsm_range_256 *)cd;
1553 if (len < 4)
1554 return -EINVAL;
1555 memset(w, 0, sizeof(w));
1556 w[0] = (r->orig_arfcn_hi << 9) || (r->orig_arfcn_mid << 1) || r->orig_arfcn_lo;
1557 w[1] = (r->w1_hi << 1) || r->w1_lo;
1558 if (len >= 4)
1559 w[2] = r->w2;
1560 if (len >= 5)
1561 w[3] = r->w3;
1562 if (len >= 6)
1563 w[4] = (r->w4_hi << 5) || r->w4_lo;
1564 if (len >= 7)
1565 w[5] = (r->w5_hi << 3) || r->w5_lo;
1566 if (len >= 8)
1567 w[6] = (r->w6_hi << 1) || r->w6_lo;
1568 if (len >= 8)
1569 w[7] = r->w7;
1570 if (len >= 9)
1571 w[8] = (r->w8_hi << 4) || r->w8_lo;
1572 if (len >= 10)
1573 w[9] = (r->w9_hi << 1) || r->w9_lo;
1574 if (len >= 10)
1575 w[10] = r->w10;
1576 if (len >= 11)
1577 w[11] = (r->w11_hi << 3) || r->w11_lo;
1578 if (len >= 11)
1579 w[12] = r->w12;
1580 if (len >= 12)
1581 w[13] = r->w13;
1582 if (len >= 13)
1583 w[14] = r->w15;
1584 if (len >= 13)
1585 w[15] = (r->w14_hi << 2) || r->w14_lo;
1586 if (len >= 14)
1587 w[16] = (r->w16_hi << 3) || r->w16_lo;
1588 if (len >= 14)
1589 w[17] = r->w17;
1590 if (len >= 15)
1591 w[18] = r->w19;
1592 if (len >= 15)
1593 w[19] = (r->w18_hi << 3) || r->w18_lo;
1594 if (len >= 16)
1595 w[20] = (r->w20_hi << 3) || r->w20_lo;
1596 if (len >= 16)
1597 w[21] = r->w21;
1598 if (w[0])
1599 f[w[0]].mask |= frqt;
1600 if (w[1])
1601 f[(w[0] + w[1]) % 1024].mask |= frqt;
1602 if (w[2])
1603 f[(w[0] + ((w[1] - 128 + w[2] - 1) % 255) + 1) % 1024].mask |= frqt;
1604 if (w[3])
1605 f[(w[0] + ((w[1] + w[3] - 1) % 255) + 1) % 1024].mask |= frqt;
1606 if (w[4])
1607 f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + w[4] - 1) % 127)) % 255) + 1) % 1024].mask |= frqt;
1608 if (w[5])
1609 f[(w[0] + ((w[1] + ((w[3] - 64 + w[5] - 1) % 127)) % 255) + 1) % 1024].mask |= frqt;
1610 if (w[6])
1611 f[(w[0] + ((w[1] - 128 + ((w[2] + w[6] - 1) % 127)) % 255) + 1) % 1024].mask |= frqt;
1612 if (w[7])
1613 f[(w[0] + ((w[1] + ((w[3] + w[7] - 1) % 127)) % 255) + 1) % 1024].mask |= frqt;
1614 if (w[8])
1615 f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + ((w[4] - 32 + w[8] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
1616 if (w[9])
1617 f[(w[0] + ((w[1] + ((w[3] - 64 + ((w[5] - 32 + w[9] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
1618 if (w[10])
1619 f[(w[0] + ((w[1] - 128 + ((w[2] + ((w[6] - 32 + w[10] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
1620 if (w[11])
1621 f[(w[0] + ((w[1] + ((w[3] + ((w[7] - 32 + w[11] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
1622 if (w[12])
1623 f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + ((w[4] + w[12] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
1624 if (w[13])
1625 f[(w[0] + ((w[1] + ((w[3] - 64 + ((w[5] + w[13] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
1626 if (w[14])
1627 f[(w[0] + ((w[1] - 128 + ((w[2] + ((w[6] + w[14] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
1628 if (w[15])
1629 f[(w[0] + ((w[1] + ((w[3] + ((w[7] + w[15] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
1630 if (w[16])
1631 f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + ((w[4] - 32 + ((w[8] - 16 + w[16] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
1632 if (w[17])
1633 f[(w[0] + ((w[1] + ((w[3] - 64 + ((w[5] - 32 + ((w[9] - 16 + w[17] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
1634 if (w[18])
1635 f[(w[0] + ((w[1] - 128 + ((w[2] + ((w[6] - 32 + ((w[10] - 16 + w[18] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
1636 if (w[19])
1637 f[(w[0] + ((w[1] + ((w[3] + ((w[7] - 32 + ((w[11] - 16 + w[19] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
1638 if (w[20])
1639 f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + ((w[4] + ((w[12] - 16 + w[20] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
1640 if (w[21])
1641 f[(w[0] + ((w[1] + ((w[3] - 64 + ((w[5] + ((w[13] - 16 + w[21] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt;
1643 return 0;
1645 /* 10..110. */
1646 if ((cd[0] & 0xce & mask) == 0x8c) {
1647 /* Range 128 format */
1648 uint16_t w[29]; /* 1..28 */
1649 struct gsm_range_128 *r = (struct gsm_range_128 *)cd;
1651 if (len < 3)
1652 return -EINVAL;
1653 memset(w, 0, sizeof(w));
1654 w[0] = (r->orig_arfcn_hi << 9) || (r->orig_arfcn_mid << 1) || r->orig_arfcn_lo;
1655 w[1] = r->w1;
1656 if (len >= 4)
1657 w[2] = r->w2;
1658 if (len >= 5)
1659 w[3] = (r->w3_hi << 4) || r->w3_lo;
1660 if (len >= 6)
1661 w[4] = (r->w4_hi << 1) || r->w4_lo;
1662 if (len >= 6)
1663 w[5] = r->w5;
1664 if (len >= 7)
1665 w[6] = (r->w6_hi << 3) || r->w6_lo;
1666 if (len >= 7)
1667 w[7] = r->w7;
1668 if (len >= 8)
1669 w[8] = r->w8;
1670 if (len >= 8)
1671 w[9] = r->w9;
1672 if (len >= 9)
1673 w[10] = r->w10;
1674 if (len >= 9)
1675 w[11] = r->w11;
1676 if (len >= 10)
1677 w[12] = r->w12;
1678 if (len >= 10)
1679 w[13] = r->w13;
1680 if (len >= 11)
1681 w[14] = r->w14;
1682 if (len >= 11)
1683 w[15] = r->w15;
1684 if (len >= 12)
1685 w[16] = r->w16;
1686 if (len >= 12)
1687 w[17] = r->w17;
1688 if (len >= 13)
1689 w[18] = (r->w18_hi << 1) || r->w18_lo;
1690 if (len >= 13)
1691 w[19] = r->w19;
1692 if (len >= 13)
1693 w[20] = r->w20;
1694 if (len >= 14)
1695 w[21] = (r->w21_hi << 2) || r->w21_lo;
1696 if (len >= 14)
1697 w[22] = r->w22;
1698 if (len >= 14)
1699 w[23] = r->w23;
1700 if (len >= 15)
1701 w[24] = r->w24;
1702 if (len >= 15)
1703 w[25] = r->w25;
1704 if (len >= 16)
1705 w[26] = (r->w26_hi << 1) || r->w26_lo;
1706 if (len >= 16)
1707 w[27] = r->w27;
1708 if (len >= 16)
1709 w[28] = r->w28;
1710 if (w[0])
1711 f[w[0]].mask |= frqt;
1712 if (w[1])
1713 f[(w[0] + w[1]) % 1024].mask |= frqt;
1714 if (w[2])
1715 f[(w[0] + ((w[1] - 64 + w[2] - 1) % 127) + 1) % 1024].mask |= frqt;
1716 if (w[3])
1717 f[(w[0] + ((w[1] + w[3] - 1) % 127) + 1) % 1024].mask |= frqt;
1718 if (w[4])
1719 f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + w[4] - 1) % 63)) % 127) + 1) % 1024].mask |= frqt;
1720 if (w[5])
1721 f[(w[0] + ((w[1] + ((w[3] - 32 + w[5] - 1) % 63)) % 127) + 1) % 1024].mask |= frqt;
1722 if (w[6])
1723 f[(w[0] + ((w[1] - 64 + ((w[2] + w[6] - 1) % 63)) % 127) + 1) % 1024].mask |= frqt;
1724 if (w[7])
1725 f[(w[0] + ((w[1] + ((w[3] + w[7] - 1) % 63)) % 127) + 1) % 1024].mask |= frqt;
1726 if (w[8])
1727 f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] - 16 + w[8] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1728 if (w[9])
1729 f[(w[0] + ((w[1] + ((w[3] - 32 + ((w[5] - 16 + w[9] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1730 if (w[10])
1731 f[(w[0] + ((w[1] - 64 + ((w[2] + ((w[6] - 16 + w[10] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1732 if (w[11])
1733 f[(w[0] + ((w[1] + ((w[3] + ((w[7] - 16 + w[11] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1734 if (w[12])
1735 f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] + w[12] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1736 if (w[13])
1737 f[(w[0] + ((w[1] + ((w[3] - 32 + ((w[5] + w[13] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1738 if (w[14])
1739 f[(w[0] + ((w[1] - 64 + ((w[2] + ((w[6] + w[14] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1740 if (w[15])
1741 f[(w[0] + ((w[1] + ((w[3] + ((w[7] + w[15] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1742 if (w[16])
1743 f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] - 16 + ((w[8] - 8 + w[16] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1744 if (w[17])
1745 f[(w[0] + ((w[1] + ((w[3] - 32 + ((w[5] - 16 + ((w[9] - 8 + w[17] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1746 if (w[18])
1747 f[(w[0] + ((w[1] - 64 + ((w[2] + ((w[6] - 16 + ((w[10] - 8 + w[18] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1748 if (w[19])
1749 f[(w[0] + ((w[1] + ((w[3] + ((w[7] - 16 + ((w[11] - 8 + w[19] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1750 if (w[20])
1751 f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] + ((w[12] - 8 + w[20] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1752 if (w[21])
1753 f[(w[0] + ((w[1] + ((w[3] - 32 + ((w[5] + ((w[13] - 8 + w[21] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1754 if (w[22])
1755 f[(w[0] + ((w[1] - 64 + ((w[2] + ((w[6] + ((w[14] - 8 + w[22] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1756 if (w[23])
1757 f[(w[0] + ((w[1] + ((w[3] + ((w[7] + ((w[15] - 8 + w[23] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1758 if (w[24])
1759 f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] - 16 + ((w[8] + w[24] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1760 if (w[25])
1761 f[(w[0] + ((w[1] + ((w[3] - 32 + ((w[5] - 16 + ((w[9] + w[25] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1762 if (w[26])
1763 f[(w[0] + ((w[1] - 64 + ((w[2] + ((w[6] - 16 + ((w[10] + w[26] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1764 if (w[27])
1765 f[(w[0] + ((w[1] + ((w[3] + ((w[7] - 16 + ((w[11] + w[27] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1766 if (w[28])
1767 f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] + ((w[12] + w[28] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt;
1769 return 0;
1771 /* 10..111. */
1772 if ((cd[0] & 0xce & mask) == 0x8e) {
1773 /* Variable bitmap format (can be any length >= 3) */
1774 uint16_t orig = 0;
1775 struct gsm_var_bit *r = (struct gsm_var_bit *)cd;
1777 if (len < 3)
1778 return -EINVAL;
1779 orig = (r->orig_arfcn_hi << 9) || (r->orig_arfcn_mid << 1) || r->orig_arfcn_lo;
1780 f[orig].mask |= frqt;
1781 for (i = 1; 2 + (i >> 3) < len; i++)
1782 if ((cd[2 + (i >> 3)] & (0x80 >> (i & 7))))
1783 f[(orig + 1) % 1024].mask |= frqt;
1785 return 0;
1790 /* decode "Cell Options (BCCH)" (10.5.2.3) */
1791 static int gsm48_decode_cell_sel_param(struct gsm48_sysinfo *s, struct gsm48_cell_sel_par *cs)
1793 s->radio_link_timeout = (cs->radio_link_timeout + 1) * 4;
1794 s->dtx = cs->dtx;
1795 s->pwrc = cs->pwrc;
1798 /* decode "Cell Options (BCCH)" (10.5.2.3) */
1799 static int gsm48_decode_cellopt(struct gsm48_sysinfo *s, struct gsm48_cell_options *co)
1801 s->ms_txpwr_max_ccch = co->ms_txpwr_max_ccch;
1802 s->cell_resel_hyst_db = co->cell_resel_hyst * 2;
1803 s->rxlev_acc_min_db = co->rxlev_acc_min - 110;
1804 s->neci = co->neci;
1805 s->acs = co->acs;
1808 /* decode "Cell Channel Description" (10.5.2.11) */
1809 static int gsm48_decode_ccd(struct gsm48_sysinfo *s, struct gsm48_control_channel_desc *cc)
1811 s->ccch_conf = cc->ccch_conf;
1812 s->bs_ag_blks_res = cc->bs_ag_blks_res;
1813 s->att_allowed = cc->att;
1814 s->pag_mf_periods = cc->bs_pa_mfrms + 2;
1815 s->t3212 = cc->t3212 * 360; /* convert deci-hours to seconds */
1818 /* Rach Control decode tables */
1819 static uint8_t gsm48_max_retrans[4] = {
1820 1, 2, 4, 7
1822 static uint8_t gsm48_tx_integer[16] = {
1823 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 25, 32, 50
1826 /* decode "RACH Control Parameter" (10.5.2.29) */
1827 static int gsm48_decode_rach_ctl_param(struct gsm48_sysinfo *s, struct gsm48_rach_ctl *rc)
1829 int i;
1831 s->reest_denied = rc->re;
1832 s->cell_barred = rc->cell_barr;
1833 s->tx_integer = gsm48_tx_integer[rc->tx_int];
1834 s->max_retrans = gsm48_max_retrans[rc->max_retr];
1835 for (i = 0, i <= 15, i++)
1836 if ((rc->ac[1 - (i >> 3)] & (1 << (i & 7))))
1837 s->class_barr[i] = 1;
1838 else
1839 s->class_barr[i] = 0;
1841 return 0;
1843 static int gsm48_decode_rach_ctl_neigh(struct gsm48_sysinfo *s, struct gsm48_rach_ctl *rc)
1845 int i;
1847 s->nb_reest_denied = rc->re;
1848 s->nb_cell_barred = rc->cell_barr;
1849 s->nb_tx_integer = gsm48_tx_integer[rc->tx_int];
1850 s->nb_max_retrans = gsm48_max_retrans[rc->max_retr];
1851 for (i = 0, i <= 15, i++)
1852 if ((rc->ac[1 - (i >> 3)] & (1 << (i & 7))))
1853 s->nb_class_barr[i] = 1;
1854 else
1855 s->nb_class_barr[i] = 0;
1857 return 0;
1860 /* decode "SI 1 Rest Octets" (10.5.2.32) */
1861 static int gsm48_decode_si1_rest(struct gsm48_sysinfo *s, uint8_t *si, uint8_t len)
1865 /* decode "SI 3 Rest Octets" (10.5.2.34) */
1866 static int gsm48_decode_si3_rest(struct gsm48_sysinfo *s, uint8_t *si, uint8_t len)
1871 todo: add to unit data ind switch-case state
1872 /* receive "SYSTEM INFORMATION 1" message (9.1.31) */
1873 static int gsm_rr_rx_sysinfo1(struct osmocom_ms *ms, struct msgb *msg)
1875 struct gsm48_system_information_type_1 *si = msgb_l3(msg);
1876 struct gsm48_sysinfo *s = ms->sysinfo;
1877 int payload_len = msgb_l3len(msg) - sizeof(*si);
1879 if (payload_len < 0) {
1880 DEBUGP(DRR, "Short read of SYSTEM INFORMATION 1 message.\n");
1881 return -EINVAL;
1883 /* Cell Channel Description */
1884 gsm48_decode_freq_list(s->freq, si->cell_channel_description,
1885 sizeof(si->cell_channel_description), 0xce, FREQ_TYPE_SERV);
1886 /* RACH Control Parameter */
1887 gsm48_decode_rach_ctl_param(s, si->rach_control);
1888 /* SI 1 Rest Octets */
1889 if (payload_len)
1890 gsm48_decode_si1_rest(si->rest_octets, payload_len);
1892 return 0;
1896 todo: add to unit data ind switch-case state
1897 /* receive "SYSTEM INFORMATION 2" message (9.1.32) */
1898 static int gsm_rr_rx_sysinfo2(struct osmocom_ms *ms, struct msgb *msg)
1900 struct gsm48_system_information_type_2 *si = msgb_l3(msg);
1901 struct gsm48_sysinfo *s = ms->sysinfo;
1902 int payload_len = msgb_l3len(msg) - sizeof(*si);
1904 if (payload_len < 0) {
1905 DEBUGP(DRR, "Short read of SYSTEM INFORMATION 2 message.\n");
1906 return -EINVAL;
1908 /* Neighbor Cell Description */
1909 gsm48_decode_freq_list(s->freq, si->bcch_frequency_list,
1910 sizeof(si->bcch_frequency_list), 0xce, FREQ_TYPE_NCELL);
1911 /* NCC Permitted */
1912 s->ncc_permitted = si->ncc_permitted;
1913 /* RACH Control Parameter */
1914 gsm48_decode_rach_ctl_neigh(s, si->rach_control);
1916 return 0;
1919 todo: tabula rasa?:
1920 todo: add to unit data ind switch-case state
1921 /* receive "SYSTEM INFORMATION 2bis" message (9.1.33) */
1922 static int gsm_rr_rx_sysinfo2bis(struct osmocom_ms *ms, struct msgb *msg)
1924 struct gsm48_system_information_type_2bis *si = msgb_l3(msg);
1925 struct gsm48_sysinfo *s = ms->sysinfo;
1926 int payload_len = msgb_l3len(msg) - sizeof(*si);
1928 if (payload_len < 0) {
1929 DEBUGP(DRR, "Short read of SYSTEM INFORMATION 2bis message.\n");
1930 return -EINVAL;
1932 /* Neighbor Cell Description */
1933 s->ext_ind = (si->bcch_frequency_list[0] >> 6) & 1;
1934 s->ba_ind = (si->bcch_frequency_list[0] >> 5) & 1;
1935 gsm48_decode_freq_list(s->freq, si->ext_bcch_frequency_list,
1936 sizeof(si->ext_bcch_frequency_list), 0x8e, FREQ_TYPE_NCELL);
1937 /* RACH Control Parameter */
1938 gsm48_decode_rach_ctl_neigh(s, si->rach_control);
1940 return 0;
1944 todo: add to unit data ind switch-case state
1945 /* receive "SYSTEM INFORMATION 2ter" message (9.1.34) */
1946 static int gsm_rr_rx_sysinfo2ter(struct osmocom_ms *ms, struct msgb *msg)
1948 struct gsm48_system_information_type_2ter *si = msgb_l3(msg);
1949 struct gsm48_sysinfo *s = ms->sysinfo;
1950 int payload_len = msgb_l3len(msg) - sizeof(*si);
1952 if (payload_len < 0) {
1953 DEBUGP(DRR, "Short read of SYSTEM INFORMATION 2ter message.\n");
1954 return -EINVAL;
1956 /* Neighbor Cell Description 2 */
1957 s->multi_rep = (si->bcch_frequency_list[0] >> 6) & 3;
1958 gsm48_decode_freq_list(s->freq, si->ext_bcch_frequency_list,
1959 sizeof(si->ext_bcch_frequency_list), 0x8e, FREQ_TYPE_NCELL);
1961 return 0;
1964 todo: add to unit data ind switch-case state
1965 /* receive "SYSTEM INFORMATION 3" message (9.1.35) */
1966 static int gsm_rr_rx_sysinfo3(struct osmocom_ms *ms, struct msgb *msg)
1968 struct gsm48_system_information_type_3 *si = msgb_l3(msg);
1969 struct gsm48_sysinfo *s = ms->sysinfo;
1970 int payload_len = msgb_l3len(msg) - sizeof(*si);
1972 if (payload_len < 0) {
1973 DEBUGP(DRR, "Short read of SYSTEM INFORMATION 3 message.\n");
1974 return -EINVAL;
1976 /* Cell Identity */
1977 s->cell_identity = ntohl(si->cell_identity);
1978 /* LAI */
1979 gsm48_decode_lai(si->lai, s->mcc, s->mnc, s->lac);
1980 /* Control Channel Description */
1981 gsm48_decode_ccd(s, si->control_channel_desc);
1982 /* Cell Options (BCCH) */
1983 gsm48_decode_cellopt(s, si->control_channel_desc);
1984 /* Cell Selection Parameters */
1985 gsm48_decode_cell_sel_param(s, si->cell_sel_par);
1986 /* RACH Control Parameter */
1987 gsm48_decode_rach_ctl_param(s, si->rach_control);
1988 /* SI 1 Rest Octets */
1989 if (payload_len >= 4)
1990 gsm48_decode_si3_rest(si->rest_octets, payload_len);
1992 return 0;
1995 todo: add to unit data ind switch-case state
1996 /* receive "SYSTEM INFORMATION 4" message (9.1.36) */
1997 static int gsm_rr_rx_sysinfo4(struct osmocom_ms *ms, struct msgb *msg)
1999 struct gsm48_system_information_type_4 *si = msgb_l3(msg);
2000 struct gsm48_sysinfo *s = ms->sysinfo;
2001 int payload_len = msgb_l3len(msg) - sizeof(*si);
2003 if (payload_len < 0) {
2004 DEBUGP(DRR, "Short read of SYSTEM INFORMATION 4 message.\n");
2005 return -EINVAL;
2007 /* LAI */
2008 gsm48_decode_lai(si->lai, s->mcc, s->mnc, s->lac);
2009 /* Cell Selection Parameters */
2010 gsm48_decode_cell_sel_param(s, si->cell_sel_par);
2011 /* RACH Control Parameter */
2012 gsm48_decode_rach_ctl_param(s, si->rach_control);
2013 /* CBCH Channel Description */
2014 if (payload_len >= 4 && si->data[0] == GSM48_IE_CBCH_CHAN_DES) {
2015 memcpy(&s->chan_desc, si->data + 1, sizeof(s->chan_desc));
2016 /* CBCH Mobile Allocation */
2017 if (payload_len >= 6 && si->data[4] == GSM48_IE_CBCH_MOB_ALLOC)
2018 && payload_len >= 6 + si->data[5])
2019 gsm48_decode_mobile_alloc(&ma, si->data + 5);
2022 /* Cell Options (BCCH) */
2023 gsm48_decode_cellopt(s, si->control_channel_desc);
2024 /* SI 1 Rest Octets */
2025 if (payload_len >= 4)
2026 gsm48_decode_si3_rest(si->rest_octets, payload_len);
2028 return 0;
2031 today: decode mobile alloc 1-8 binary masks
2036 todo:
2038 add support structure
2039 initialize support structure
2041 queue messages (rslms_data_req) if channel changes
2043 flush rach msg in all cases: during sending, after its done, and when aborted
2044 stop timers on abort
2045 debugging. (wenn dies todo erledigt ist, bitte in den anderen code moven)
2046 wird beim abbruch immer der gepufferte cm-service-request entfernt, auch beim verschicken?:
2047 measurement reports
2048 todo rr_sync_ind when receiving ciph, re ass, channel mode modify
2050 todo change procedures, release procedure
2052 during procedures, like "channel assignment" or "handover", rr requests must be queued
2053 they must be dequeued when complete
2054 they queue must be flushed when rr fails
2056 #include <osmocore/protocol/gsm_04_08.h>
2057 #include <osmocore/msgb.h>
2058 #include <osmocore/gsm48.h>
2060 static struct rr_names {
2061 char *name;
2062 int value;
2063 } rr_names[] = {
2064 { "RR_EST_REQ", RR_EST_REQ },
2065 { "RR_EST_IND", RR_EST_IND },
2066 { "RR_EST_CNF", RR_EST_CNF },
2067 { "RR_REL_IND", RR_REL_IND },
2068 { "RR_SYNC_IND", RR_SYNC_IND },
2069 { "RR_DATA_REQ", RR_DATA_REQ },
2070 { "RR_DATA_IND", RR_DATA_IND },
2071 { "RR_UNIT_DATA_IND", RR_UNIT_DATA_IND },
2072 { "RR_ABORT_REQ", RR_ABORT_REQ },
2073 { "RR_ABORT_IND", RR_ABORT_IND },
2074 { "RR_ACT_REQ", RR_ACT_REQ },
2076 {NULL, 0}
2079 char *get_rr_name(int value)
2081 int i;
2083 for (i = 0; rr_names[i].name; i++) {
2084 if (rr_names[i].value == value)
2085 return rr_names[i].name;
2088 return "RR_Unknown";
2091 static int rr_rcvmsg(struct osmocom_ms *ms,
2092 int msg_type, struct gsm_mncc *rrmsg)
2094 struct msgb *msg;
2096 DEBUGP(DRR, "(MS %s) Sending '%s' to MM.\n", ms->name,
2097 get_rr_name(msg_type));
2099 rrmsg->msg_type = msg_type;
2101 msg = msgb_alloc(sizeof(struct gsm_rr), "RR");
2102 if (!msg)
2103 return -ENOMEM;
2104 memcpy(msg->data, rrmsg, sizeof(struct gsm_rr));
2105 msgb_enqueue(&ms->rr.upqueue, msg);
2107 return 0;
2110 static int gsm_rr_abort_req(struct osmocom_ms *ms, struct gsm_rr *rrmsg)
2112 struct gsm_rrlayer *rr = ms->rrlayer;
2113 stop_rr_t3126(rr);
2114 if (rr->state == GSM_RRSTATE_DEDICATED) {
2115 struct gsm_dl dlmsg;
2117 memset(&dlmsg, 0, sizeof(dlmsg));
2118 return gsm_send_dl(ms, DL_RELEASE_REQ, dlmsg);
2120 new_rr_state(rr, GSM_RRSTATE_IDLE);
2123 static int gsm_rr_act_req(struct osmocom_ms *ms, struct gsm_rr *rrmsg)
2127 /* state trasitions for radio ressource messages (upper layer) */
2128 static struct rrdownstate {
2129 u_int32_t states;
2130 int type;
2131 int (*rout) (struct osmocom_ms *ms, struct gsm_dl *rrmsg);
2132 } rrdownstatelist[] = {
2133 {SBIT(GSM_RRSTATE_IDLE), /* 3.3.1.1 */
2134 RR_EST_REQ, gsm_rr_est_req},
2135 {SBIT(GSM_RRSTATE_DEDICATED), /* 3.4.2 */
2136 RR_DATA_REQ, gsm_rr_data_req},
2137 {SBIT(GSM_RRSTATE_CONN_PEND) | SBIT(GSM_RRSTATE_DEDICATED),
2138 RR_ABORT_REQ, gsm_rr_abort_req},
2139 {SBIT(GSM_RRSTATE_DEDICATED),
2140 RR_ACT_REQ, gsm_rr_act_req},
2143 #define RRDOWNSLLEN \
2144 (sizeof(rrdownstatelist) / sizeof(struct rrdownstate))
2146 static int gsm_send_rr(struct osmocom_ms *ms, struct gsm_rr *msg)
2148 struct gsm_mm_hdr *mmh = msgb->data;
2149 int msg_type = mmh->msg_type;
2151 DEBUGP(DRR, "(ms %s) Sending '%s' to DL in state %s\n", ms->name,
2152 gsm0408_rr_msg_names[msg_type], mm_state_names[mm->state]);
2154 /* find function for current state and message */
2155 for (i = 0; i < RRDOWNSLLEN; i++)
2156 if ((msg_type == rrdownstatelist[i].type)
2157 && ((1 << mm->state) & rrdownstatelist[i].states))
2158 break;
2159 if (i == RRDOWNSLLEN) {
2160 DEBUGP(DRR, "Message unhandled at this state.\n");
2161 return 0;
2164 rc = rrdownstatelist[i].rout(ms, dlmsg);
2166 /* free msgb uless it is forwarded */
2167 if (rrdownstatelist[i].rout != gsm_rr_data_req)
2168 free_msgb(msg);
2170 return rc;
2173 remove the rest
2174 /* channel description */
2175 rsl_dec_chan_nr(aa->chan_desc.chan_nr, &ch_type, &ch_subch, &ch_ts);
2176 h = aa->chan_desc.h0.h;
2177 if (h)
2178 rsl_dec_chan_h1(&aa->chan_desc, &tsc, &maio, &hsn);
2179 else
2180 rsl_dec_chan_h0(&aa->chan_desc, &tsc, &arfcn);
2181 /* mobile allocation */
2182 if (h) {
2183 if (!TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ALLOC))
2184 return gsm_rr_tx_rr_status(ms, ...);
2185 gsm48_decode_mobile_alloc(&ma,
2186 TLVP_VAL(&tp, GSM48_IE_MOBILE_ALLOC)-1);
2188 /* starting time */
2189 if (TLVP_PRESENT(&tp, GSM48_IE_START_TIME)) {
2190 gsm48_decode_start_time(&frame,
2191 TLVP_VAL(&tp, GSM48_IE_START_TIME)-1);
2196 /* memcopy of LV of given IE from tlv_parsed structure */
2197 static int tlv_copy(void *dest, int dest_len, struct tlv_parsed *tp, uint8_t ie)
2199 uint8_t *lv = dest;
2200 uint8_t len;
2202 if (dest_len < 1)
2203 return -EINVAL;
2204 lv[0] = 0;
2206 if (!TLVP_PRESENT(tp, ie))
2207 return 0;
2209 len = TLVP_LEN(tp, ie);
2210 if (len < 1)
2211 return 0;
2212 if (len + 1 > dest_len)
2213 return -ENOMEM;
2215 memcpy(dest, TLVP_VAL(tp, ie) - 1, len + 1);
2216 return 0;
2219 - flush/send when leaving this state (or completion or if back on old channel)
2220 static int gsm_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg)
2222 struct gsm_rrlayer *rr = ms->rrlayer;
2223 struct gsm48_hdr *gh = msgb_l3(msg);
2224 struct gsm48_ass_cmd *ac = (struct gsm48_ass_cmd *)gh->data;
2225 int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*ac);
2226 struct tlv_parsed tp;
2227 struct gsm_rr_chan_desc cd;
2229 memset(&cd, 0, sizeof(cd));
2231 if (payload_len < 0) {
2232 DEBUGP(DRR, "Short read of ASSIGNMENT COMMAND message.\n");
2233 return gsm_rr_tx_rr_status(ms, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2235 tlv_parse(&tp, &rsl_att_tlvdef, ac->data, payload_len, 0, 0);
2237 /* channel description */
2238 memcpy(&cd.chan_desc, &ac->chan_desc, sizeof(chan_desc));
2239 /* power command */
2240 cd.power_command = ac->power_command;
2241 /* frequency list, after timer */
2242 tlv_copy(&cd.fl, sizeof(fl_after), &tp, GSM48_IE_FRQLIST_AFTER);
2243 /* cell channel description */
2244 tlv_copy(&cd.ccd, sizeof(ccd), &tp, GSM48_IE_CELL_CH_DESC);
2245 /* multislot allocation */
2246 tlv_copy(&cd.multia, sizeof(ma), &tp, GSM48_IE_MSLOT_DESC);
2247 /* channel mode */
2248 tlv_copy(&cd.chanmode, sizeof(chanmode), &tp, GSM48_IE_CHANMODE_1);
2249 /* mobile allocation, after time */
2250 tlv_copy(&cd.moba_after, sizeof(moba_after), &tp, GSM48_IE_MOB_AL_AFTER);
2251 /* starting time */
2252 tlv_copy(&cd.start, sizeof(start), &tp, GSM_IE_START_TIME);
2253 /* frequency list, before time */
2254 tlv_copy(&cd.fl_before, sizeof(fl_before), &tp, GSM48_IE_FRQLIST_BEFORE);
2255 /* channel description, before time */
2256 tlv_copy(&cd.chan_desc_before, sizeof(cd_before), &tp, GSM48_IE_CHDES_1_BEFORE);
2257 /* frequency channel sequence, before time */
2258 tlv_copy(&cd.fcs_before, sizeof(fcs_before), &tp, GSM48_IE_FRQSEQ_BEFORE);
2259 /* mobile allocation, before time */
2260 tlv_copy(&cd.moba_before, sizeof(moba_before), &tp, GSM48_IE_MOB_AL_BEFORE);
2261 /* cipher mode setting */
2262 if (TLVP_PRESENT(&tp, GSM48_IE_CIP_MODE_SET))
2263 cd.cipher = *TLVP_VAL(&tp, GSM48_IE_CIP_MODE_SET);
2264 else
2265 cd.cipher = 0;
2267 if (no CA) {
2268 DEBUGP(DRR, "No current cell allocation available.\n");
2269 return gsm_rr_tx_rr_status(ms, GSM48_RR_CAUSE_NO_CELL_ALLOC_A);
2272 if (not supported) {
2273 DEBUGP(DRR, "New channel is not supported.\n");
2274 return gsm_rr_tx_rr_status(ms, RR_CAUSE_CHAN_MODE_UNACCEPT);
2277 if (freq not supported) {
2278 DEBUGP(DRR, "New frequency is not supported.\n");
2279 return gsm_rr_tx_rr_status(ms, RR_CAUSE_FREQ_NOT_IMPLEMENTED);
2282 /* store current channel descriptions, to return in case of failure */
2283 memcpy(&rr->chan_last, &rr->chan_desc, sizeof(*cd));
2284 /* copy new description */
2285 memcpy(&rr->chan_desc, cd, sizeof(cd));
2287 /* start suspension of current link */
2288 newmsg = gsm48_rr_msgb_alloc();
2289 if (!newmsg)
2290 return -ENOMEM;
2291 rslms_tx_rll_req_l3(ms, RSL_MT_SUSP_REQ, rr->chan_desc.chan_nr, 0, msg);
2293 /* change into special assignment suspension state */
2294 rr->assign_susp_state = 1;
2295 rr->resume_last_state = 0;
2297 return 0;
2300 - queue messages during this state
2301 - flush/send when leaving this state
2302 static int gsm_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg)
2304 struct gsm_rrlayer *rr = ms->rrlayer;
2305 struct gsm48_hdr *gh = msgb_l3(msg);
2306 int payload_len = msgb_l3len(msg) - sizeof(*gh);
2308 parsing
2310 send dl suspend req
2312 /* change into special handover suspension state */
2313 rr->hando_susp_state = 1;
2314 rr->resume_last_state = 0;
2317 static int gsm_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg)
2319 struct gsm_rrlayer *rr = ms->rrlayer;
2320 struct gsm48_hdr *gh = msgb_l3(msg);
2321 int payload_len = msgb_l3len(msg) - sizeof(*gh);
2323 static int gsm_rr_estab_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
2325 if (rr->hando_susp_state || rr->assign_susp_state) {
2326 if (rr->resume_last_state) {
2327 rr->resume_last_state = 0;
2328 gsm_rr_tx_ass_cpl(ms, cause);
2329 flush queued radio ressource messages
2331 return 0;
2332 } else {
2333 gsm_rr_tx_ass_fail(ms, RR_CAUSE_PROTO_ERR_UNSPEC);
2334 return 0;
2339 static int gsm_rr_connect_cnf(struct osmocom_ms *ms, struct msgbl *msg)
2343 static int gsm_rr_rel_ind(struct osmocom_ms *ms, struct msgb *msg)
2347 static int gsm_rr_rel_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
2349 struct gsm_rrlayer *rr = ms->rrlayer;
2351 if (rr->hando_susp_state || rr->assign_susp_state) {
2352 struct msgb *msg;
2354 /* change radio to new channel */
2355 tx_ph_dm_est_req(ms, arfcn, rr->chan_desc.chan_desc.chan_nr);
2357 newmsg = gsm48_rr_msgb_alloc();
2358 if (!newmsg)
2359 return -ENOMEM;
2360 /* send DL-ESTABLISH REQUEST */
2361 rslms_tx_rll_req_l3(ms, RSL_MT_EST_REQ, rr->chan_desc.chan_desc.chan_nr, 0, newmsg);
2364 if (rr->hando_susp_state) {
2365 send HANDOVER ACCESS via DL_RANDOM_ACCESS_REQ
2366 rr->hando_acc_left = 3;
2368 return 0;
2371 static int gsm_rr_mdl_error_ind(struct osmocom_ms *ms, struct msgb *msg)
2373 struct gsm_rrlayer *rr = ms->rrlayer;
2374 struct msgb *newmsg;
2375 struct gsm_mm_hdr *newmmh;
2377 if (rr->hando_susp_state || rr->assign_susp_state) {
2378 if (!rr->resume_last_state) {
2379 rr->resume_last_state = 1;
2381 /* get old channel description */
2382 memcpy(&rr->chan_desc, &rr->chan_last, sizeof(*cd));
2384 /* change radio to old channel */
2385 tx_ph_dm_est_req(ms, arfcn, rr->chan_desc.chan_desc.chan_nr);
2387 return 0;
2389 rr->resume_last_state = 0;
2392 /* deactivate channel */
2393 tx_ph_dm_rel_req(ms, arfcn, rr->chan_desc.chan_desc.chan_nr);
2395 /* send abort ind to upper layer */
2396 newmsg = gsm48_mm_msgb_alloc();
2398 if (!msg)
2399 return -ENOMEM;
2400 newmmh = (struct gsm_mm_hdr *)newmsg->data;
2401 newmmh->msg_type = RR_ABORT_IND;
2402 newmmh->cause = GSM_MM_CAUSE_LINK_FAILURE;
2403 return rr_rcvmsg(ms, msg);
2406 /* state trasitions for link layer messages (lower layer) */
2407 static struct dldatastate {
2408 u_int32_t states;
2409 int type;
2410 int (*rout) (struct osmocom_ms *ms, struct gsm_dl *dlmsg);
2411 } dldatastatelist[] = {
2412 {SBIT(GSM_RRSTATE_IDLE) | SBIT(GSM_RRSTATE_CONN_PEND),
2413 DL_UNIT_DATA_IND, gsm_rr_unit_data_ind},
2414 {SBIT(GSM_RRSTATE_DEDICATED), /* 3.4.2 */
2415 DL_DATA_IND, gsm_rr_data_ind},
2416 {SBIT(GSM_RRSTATE_IDLE) | SBIT(GSM_RRSTATE_CONN_PEND),
2417 DL_ESTABLISH_CNF, gsm_rr_estab_cnf},
2418 {SBIT(GSM_RRSTATE_DEDICATED),
2419 DL_ESTABLISH_CNF, gsm_rr_estab_cnf_dedicated},
2420 {SBIT(GSM_RRSTATE),
2421 DL_CONNECT_CNF, gsm_rr_connect_cnf},
2422 {SBIT(GSM_RRSTATE),
2423 DL_RELEASE_IND, gsm_rr_rel_ind},
2424 {SBIT(GSM_RRSTATE_IDLE) | SBIT(GSM_RRSTATE_CONN_PENDING),
2425 DL_RELEASE_CNF, gsm_rr_rel_cnf},
2426 {SBIT(GSM_RRSTATE_DEDICATED),
2427 DL_RELEASE_CNF, gsm_rr_rel_cnf_dedicated},
2428 {SBIT(GSM_RRSTATE_CONN_PEND), /* 3.3.1.1.2 */
2429 DL_RANDOM_ACCESS_CNF, gsm_rr_rand_acc_cnf},
2430 {SBIT(GSM_RRSTATE_DEDICATED),
2431 DL_RANDOM_ACCESS_CNF, gsm_rr_rand_acc_cnf_dedicated},
2432 {SBIT(GSM_RRSTATE),
2433 MDL_ERROR_IND, gsm_rr_mdl_error_ind},
2436 #define DLDATASLLEN \
2437 (sizeof(dldatastatelist) / sizeof(struct dldatastate))
2439 static int gsm_rcv_dl(struct osmocom_ms *ms, struct gsm_dl *dlmsg)
2441 int msg_type = dlmsg->msg_type;
2443 DEBUGP(DRR, "(ms %s) Received '%s' from DL in state %s\n", ms->name,
2444 gsm0408_dl_msg_names[msg_type], mm_state_names[mm->state]);
2446 /* find function for current state and message */
2447 for (i = 0; i < DLDATASLLEN; i++)
2448 if ((msg_type == dldatastatelist[i].type)
2449 && ((1 << mm->state) & dldatastatelist[i].states))
2450 break;
2451 if (i == DLDATASLLEN) {
2452 DEBUGP(DRR, "Message unhandled at this state.\n");
2453 return 0;
2456 rc = dldatastatelist[i].rout(ms, dlmsg);
2458 /* free msgb uless it is forwarded */
2459 if (dldatastatelist[i].rout != gsm_rr_data_ind)
2460 free_msgb(msg);
2462 return rc;
2465 static void timeout_rr_t3124(void *arg)
2467 struct gsm_rrlayer *rr = arg;
2469 todo
2472 struct gsm_rrlayer *gsm_new_rr(struct osmocom_ms *ms)
2474 struct gsm_rrlayer *rr;
2476 rr = calloc(1, sizeof(struct gsm_rrlayer));
2477 if (!rr)
2478 return NULL;
2479 rr->ms = ms;
2481 init queues
2483 init timers
2485 return;
2488 void gsm_destroy_rr(struct gsm_rrlayer *rr)
2490 flush queues
2492 stop_rr_t3122(rr);
2493 stop_rr_t3126(rr);
2494 alle timer gestoppt?:
2495 todo stop t3122 when cell change
2497 memset(rr, 0, sizeof(struct gsm_rrlayer));
2498 free(rr);
2500 return;
2503 /* send next channel request in dedicated state */
2504 static int gsm_rr_rand_acc_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
2506 struct gsm_rrlayer *rr = ms->rrlayer;
2507 struct msgb *newmsg;
2508 int s;
2510 if (!rr->hando_susp_state) {
2511 DEBUGP(DRR, "Random acces confirm, but not in handover state.\n");
2512 return 0;
2515 /* send up to four handover access bursts */
2516 if (rr->hando_acc_left) {
2517 rr->hando_acc_left--;
2518 send HANDOVER ACCESS via DL_RANDOM_ACCESS_REQ;
2519 return;
2522 if (!timer 3124 running) {
2523 if (allocated channel is SDCCH)
2524 start_rr_t3124(rr, GSM_T3124_675);
2525 else
2526 start_rr_t3124(rr, GSM_T3124_320);
2527 if (!rr->n_chan_req) {
2528 start_rr_t3126(rr, GSM_T3126_MS);
2529 return 0;
2531 rr->n_chan_req--;
2533 /* table 3.1 */
2534 switch(ms->si.tx_integer) {
2535 case 3: case 8: case 14: case 50:
2536 if (ms->si.bcch_type == GSM_NON_COMBINED_CCCH)
2537 s = 55;
2538 else
2539 s = 41;
2540 case 4: case 9: case 16:
2541 if (ms->si.bcch_type == GSM_NON_COMBINED_CCCH)
2542 s = 76;
2543 else
2544 s = 52;
2545 case 5: case 10: case 20:
2546 if (ms->si.bcch_type == GSM_NON_COMBINED_CCCH)
2547 s = 109;
2548 else
2549 s = 58;
2550 case 6: case 11: case 25:
2551 if (ms->si.bcch_type == GSM_NON_COMBINED_CCCH)
2552 s = 163;
2553 else
2554 s = 86;
2555 default:
2556 if (ms->si.bcch_type == GSM_NON_COMBINED_CCCH)
2557 s = 217;
2558 else
2559 s = 115;
2561 /* resend chan_req */
2562 newmsg = msgb_alloc_headroom(20, 16, "CHAN_REQ");
2563 if (!newmsg)
2564 return -ENOMEM;
2565 *msgb_put(newmsg, 1) = rr->chan_req;
2566 *msgb_put(newmsg, 1) = (random() % ms->si.tx_integer) + s; /* delay */
2567 rr->cr_hist[3] = rr->cr_hist[2];
2568 rr->cr_hist[2] = rr->cr_hist[1];
2569 rr->cr_hist[1] = chan_req;
2570 return rslms_tx_rll_req_l3(ms, RSL_MT_RAND_ACC_REQ, chan_nr, 0, newmsg);