comparison src/g23m-gsm/rr/rr_datf.c @ 1:fa8dc04885d8

src/g23m-*: import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:25:50 +0000
parents
children
comparison
equal deleted inserted replaced
0:4e78acac3d88 1:fa8dc04885d8
1 /*
2 +-----------------------------------------------------------------------------
3 | Project :
4 | Modul :
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose : This module defines the functions for the data transfer
18 | capability of the module Radio Resource.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef RR_DATF_C
23 #define RR_DATF_C
24
25 #define ENTITY_RR
26
27 /*==== INCLUDES ===================================================*/
28
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stddef.h> /* offsetof */
32 #include "typedefs.h"
33 #include "pcm.h"
34 #include "pconst.cdg"
35 #include "mconst.cdg"
36 #include "message.h"
37 #include "ccdapi.h"
38 #include "vsi.h"
39 #include "custom.h"
40 #include "gsm.h"
41 #include "prim.h"
42 #include "cnf_rr.h"
43 #include "tok.h"
44 #include "rr.h"
45 #include "rr_em.h"
46
47 /*==== EXPORT =====================================================*/
48
49 /*==== PRIVATE ====================================================*/
50 static void dat_fill_mobile_identity (USHORT fill_type,
51 T_mob_ident *moid);
52 static BOOL dat_eplmn_equal_req (const UBYTE *mcc,
53 const UBYTE *mnc);
54 static void dat_get_background_and_bits (UBYTE *background,
55 UBYTE *bits);
56 static UBYTE dat_get_burst (UBYTE background,
57 UBYTE bits);
58 static UBYTE dat_get_delta (UBYTE i);
59 static UBYTE dat_get_ncell_pos (USHORT channel);
60 static BOOL dat_hplmn_country (const UBYTE *mcc);
61 static SHORT dat_imsi_mod_1000 (void);
62 static SHORT dat_no_of_paging_blocks (UBYTE index);
63 static BOOL dat_owner_of_auth_0_to_9 (void);
64 static BOOL dat_owner_of_auth_11_to_15 (void);
65 static void dat_send_random_bursts (void);
66
67 typedef struct CODE_TABLE
68 {
69 USHORT cause;
70 UBYTE last_channel;
71 UBYTE neci_flag;
72 UBYTE channel_needed;
73 UBYTE ms_capability;
74 UBYTE tch_f_needed;
75 UBYTE background;
76 UBYTE bits;
77 } CODE_TABLE ;
78
79 typedef struct CONVER_TXINTEGER
80 {
81 USHORT t;
82 USHORT s_non_combined;
83 USHORT s_combined;
84 } CONVERT_TXINTEGER;
85
86 /*==== VARIABLES ==================================================*/
87
88 /*==== FUNCTIONS ==================================================*/
89
90
91 /*
92 * -------------------------------------------------------------------
93 * Procedures
94 * -------------------------------------------------------------------
95 */
96
97 /*
98 +--------------------------------------------------------------------+
99 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
100 | STATE : code ROUTINE : dat_access_allowed |
101 +--------------------------------------------------------------------+
102
103 PURPOSE : The function decides whether the access to the network is
104 allowed or not.
105 (GSM 4.18, chapter 3.3.1.1.1 Permission to access the network).
106
107 */
108
109 GLOBAL BOOL dat_access_allowed (USHORT establish_cause)
110 {
111 GET_INSTANCE_DATA;
112 BOOL result = TRUE;
113
114 TRACE_FUNCTION ("dat_access_allowed()");
115
116 #if defined (_SIMULATION_)
117 TRACE_EVENT_P1 ("ACC CLASS BCCH = %4x", rr_data->nc_data[SC_INDEX].rach.ac);
118 TRACE_EVENT_P1 ("ACC CLASS SIM = %4x", rr_data->ms_data.access_classes);
119 #endif
120
121 if (establish_cause EQ ESTCS_EMERGENCY_CALL)
122 {
123 /*
124 * if it is an emergency call the corresponding flag
125 * in the random access control parameters must be set
126 */
127 if (rr_data->nc_data[SC_INDEX].rach.ac & 0x0400)
128 result = FALSE;
129
130 /*
131 * or the MS must be member of one of the special classes
132 * defined on the SIM card.
133 */
134 if (result EQ FALSE)
135 {
136 result = dat_owner_of_auth_11_to_15 ();
137 }
138 }
139 else
140 {
141 /*
142 * for non-ememrgency calls
143 */
144
145 /*
146 * Normally, the whole check here should not be necessary as MM
147 * should know about limited service condition and not try to
148 * update in automatic mode or to establish a non-emergency CM service.
149 * So the check here is superflous, but if it catches, MM has a problem
150 * as it will think the cell is temporary barred and will wait for the
151 * barr state to change, not indicating limited service to the MMI under
152 * certain circumstances. It seems so that here something was fixed at
153 * the wrong place.
154 * The old condition was: if (dat_forbidden_lai_check (SC_INDEX))
155 */
156 if(
157 (establish_cause EQ ESTCS_LOCATION_UPDATING)
158 AND
159 ((rr_data->ms_data.operation_mode & 0x40) EQ 0x40)
160 )
161 {
162 /*
163 * Do not barr access for MM procedure establishment if we are in manual
164 * mode. This was previously bypassed within dat_forbidden_lai_check()
165 * function but was leading to incorrect cell reselection whilst RR
166 * was in manual.
167 * If MM wants to perform a LU at this place it means that user manually
168 * selected this network and is then allowed to attempt registration. If
169 * we reseleted on a LAC forbidden for provision of regional service, MM
170 * is switched to limited service so no normal LU will be triggered.
171 */
172 if (dat_owner_of_auth_0_to_9 ())
173 result = TRUE;
174 else
175 result = dat_owner_of_auth_11_to_15 ();
176 }
177 else if ( rr_data->ms_data.rr_service EQ LIMITED_SERVICE)
178 {
179 /*
180 * RR is in limited service.
181 * Only emergency calls are allowed in this state
182 */
183 result = FALSE;
184 }
185 else if (
186 dat_forb_lai_check (SC_INDEX)
187 AND
188 dat_roam_forb_lai_check (SC_INDEX)
189 )
190 {
191 /*
192 * if RR is not inside of a forbidden location area,
193 * the MS must be member of one of the normal or one
194 * of the special classes stored on the SIM card.
195 */
196 if (dat_owner_of_auth_0_to_9 ())
197 result = TRUE;
198 else
199 result = dat_owner_of_auth_11_to_15 ();
200
201 }
202 else
203 {
204 /*
205 * if RR is inside of a forbidden location area
206 * no normal calls are allowed
207 */
208 TRACE_ERROR ("Unexpected, MM doesn't know its service state.");
209 result = FALSE;
210 }
211 }
212
213 return (result);
214 }
215
216 /*
217 +--------------------------------------------------------------------+
218 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
219 | STATE : code ROUTINE : dat_calc_downlink_timeout |
220 +--------------------------------------------------------------------+
221
222 PURPOSE : The downlink signalling failure criterion is based on the
223 downlink signalling failure counter DSC. When the MS
224 camps on a cell, DSC shall be initialized to a value equal
225 to the nearest integer to 90/N where N is the BS_PA_MFRMS
226 parameter for that cell (GSM 5.08, chapter 6.5 Downlink
227 Signalling Failure).
228
229 */
230
231 GLOBAL UBYTE dat_calc_downlink_timeout (UBYTE index)
232 {
233 GET_INSTANCE_DATA;
234 UBYTE divisor;
235 UBYTE dl=0;
236
237 TRACE_FUNCTION ("dat_calc_downlink_timeout()");
238
239 /*
240 * The stored value for BS_PA_MFRMS is in air-interface coding.
241 * To get the real value a value of 2 must be added
242 */
243 divisor = rr_data->nc_data[index].control_descr.bs_pa_mfrms + 2;
244
245 /*
246 * calculate the initial value for the downlink signalling counter.
247 */
248 TRACE_ASSERT(divisor NEQ 0);
249 if(divisor NEQ 0)
250 {
251 dl = 90 / divisor;
252 }
253
254 /*
255 * correct rounding failures
256 *
257 * BS_PA_MFRMS = 2 -> 90/2 = 45
258 * 3 -> 90/3 = 30
259 * 4 -> 90/4 = 22.5 -> 23
260 * 5 -> 90/5 = 18
261 * 6 -> 90/6 = 15
262 * 7 -> 90/7 = 12.85 -> 13
263 * 8 -> 90/8 = 11.25
264 * 9 -> 90/9 = 10
265 */
266 if (divisor EQ 4 OR divisor EQ 7)
267 {
268 dl++;
269 }
270 return (dl);
271 }
272
273 /*
274 +--------------------------------------------------------------------+
275 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
276 | STATE : code ROUTINE : dat_calc_paging_group |
277 +--------------------------------------------------------------------+
278
279 PURPOSE : Calculation of paging group is described in GSM 5.02,
280 chapter 6.5.2.
281
282 PAGING_GROUP (0 .. N-1) = ((IMSI mod 1000) mod (BS_CC_CHANS x N)) mod N
283
284 where
285
286 N = number of paging blocks "available" on one CCCH =
287 (number of paging blocks "available" in a 51-multiframe
288 on one CCCH) x BS_PA_MFRMS.
289
290 IMSI = International Mobile Subscriber Identity, as defined in GSM 03.03.
291
292 mod = Modulo.
293
294 */
295
296 GLOBAL UBYTE dat_calc_paging_group (UBYTE index)
297 {
298 GET_INSTANCE_DATA;
299 /*
300 * calculation of the number of paging blocks
301 */
302 SHORT n = dat_no_of_paging_blocks (index);
303
304 /*
305 * calculation of IMSI modulo 1000
306 */
307 SHORT a = dat_imsi_mod_1000 ();
308
309 /*
310 * calculation of BS_CC_CHANS * N (GSM 5.02 section 3.3.2.3)
311 */
312 SHORT b = ((rr_data->nc_data[index].control_descr.ccch_conf / 2) + 1) * n;
313
314 TRACE_FUNCTION ("dat_calc_paging_group()");
315
316 /*
317 * calculation of the paging group
318 */
319 return ((UBYTE) ((a % b) % n));
320 }
321
322 /*
323 +--------------------------------------------------------------------+
324 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
325 | STATE : code ROUTINE : dat_calc_tn |
326 +--------------------------------------------------------------------+
327
328 PURPOSE : Determination of the timeslot of the paging block for the
329 MS in idle mode is described in GSM 5.02, chapter 6.5.2
330
331 The formula for calculation of the CCCH group must be used.
332 The dependency between timeslot and CCCH group is
333
334 tn = 2 * CCCH_GROUP
335
336 CCCH_GROUP (0 .. BS_CC_CHANS-1) = ((IMSI mod 1000) mod (BS_CC_CHANS x N)) div N
337
338 where
339
340 N = number of paging blocks "available" on one CCCH =
341 (number of paging blocks "available" in a 51-multiframe
342 on one CCCH) x BS_PA_MFRMS.
343
344 IMSI = International Mobile Subscriber Identity, as defined in GSM 03.03.
345
346 mod = Modulo.
347
348 div = Integer division.
349
350 */
351
352 GLOBAL UBYTE dat_calc_tn (UBYTE index)
353 {
354 GET_INSTANCE_DATA;
355 /*
356 * calculate the number of paging blocks
357 */
358 SHORT n = dat_no_of_paging_blocks (index);
359
360 /*
361 * calculate IMSI modulo 1000
362 */
363 SHORT a = dat_imsi_mod_1000 ();
364
365 /*
366 * calculate BS_CC_CHANS * N (GSM 5.02 section 3.3.2.3)
367 */
368 SHORT b = ((rr_data->nc_data[index].control_descr.ccch_conf / 2) + 1) * n;
369
370 TRACE_FUNCTION ("dat_calc_tn()");
371
372 /*
373 * calculate the timeslot
374 */
375 return ((UBYTE) ((a % b) / n) * 2);
376 }
377
378 /*
379 +--------------------------------------------------------------------+
380 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
381 | STATE : code ROUTINE : dat_check_error_flag |
382 +--------------------------------------------------------------------+
383
384 PURPOSE : In the formatter module several tests are performed to
385 check the syntax and the semantic of the incoming messages.
386 The results of this checks are stored in the error variables.
387 This function sends a RR STATUS message back to the network
388 if a mandatory or conditional error has been detected for
389 a message received in acknowledged mode. It indicates to the
390 calling function whether the message shall be ignored or not.
391
392 */
393
394 GLOBAL BOOL dat_check_error_flag (BOOL send_rr_status)
395 {
396 GET_INSTANCE_DATA;
397 TRACE_FUNCTION ("dat_check_error_flag()");
398
399 /*
400 * if an error unequal to optional info error has occured
401 */
402 if (rr_data->ms_data.error.cs NEQ 0 AND
403 rr_data->ms_data.error.cs NEQ OPTIONAL_INFO_ERROR)
404 {
405
406
407 if (send_rr_status)
408 {
409 /*
410 * if the message has been received in acknowledged mode,
411 * answer to the network with a RR STATUS message.
412 */
413 /* Implements RR Clone findings #23 */
414 dat_send_rr_status_msg(rr_data->ms_data.error.cs);
415
416
417 }
418
419 }
420
421 switch (rr_data->ms_data.error.cs)
422 {
423 /* case RRC_INVALID_MAN_INFO: this value is currently never set */
424 case RRC_INCORRECT_MSG:
425 case RRC_COND_IE_ERROR:
426 /*
427 * Major failure in the message, ignore it
428 */
429 return FALSE;
430
431 default:
432 /*
433 * minor or no failure, process the message
434 */
435 return TRUE;
436 }
437 }
438
439 /*
440 +--------------------------------------------------------------------+
441 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
442 | STATE : code ROUTINE : dat_code_channel_mode_to_mm|
443 +--------------------------------------------------------------------+
444
445 PURPOSE : A changed channel mode is signalled to MM.
446
447 */
448
449 GLOBAL void dat_code_channel_mode_to_mm (void)
450 {
451 GET_INSTANCE_DATA;
452 PALLOC (sync_ind, RR_SYNC_IND);
453
454 TRACE_FUNCTION ("dat_code_channel_mode_to_mm()");
455
456 /*
457 * set the channel type
458 */
459 switch (rr_data->sc_data.chan_desc.chan_type)
460 {
461 case CH_TCH_F:
462 TRACE_EVENT ("TCH/F configured");
463 sync_ind->chm.ch_type = CH_TCH_F;
464 break;
465 case CH_TCH_H_1:
466 case CH_TCH_H_2:
467 TRACE_EVENT ("TCH/H configured");
468 sync_ind->chm.ch_type = CH_TCH_H;
469 break;
470 default:
471 TRACE_EVENT ("SDCCH configured");
472 sync_ind->chm.ch_type = CH_SDCCH;
473 break;
474 }
475
476 /*
477 * set the rest of the parameters
478 */
479 sync_ind->ciph = NOT_PRESENT_8BIT;
480 sync_ind->chm.ch_mode = rr_data->sc_data.ch_mode;
481 memset(&sync_ind->mm_info, 0, sizeof(T_mm_info));
482 sync_ind->mm_info.valid = FALSE;
483 memset(&sync_ind->bcch_info, 0, sizeof(T_bcch_info));
484 sync_ind->bcch_info.v_bcch = FALSE;
485 sync_ind->synccs = NOT_PRESENT_16BIT;
486
487 PSENDX(MM, sync_ind);
488 }
489
490 /*
491 +--------------------------------------------------------------------+
492 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
493 | STATE : code ROUTINE : dat_code_ciphering_to_mm |
494 +--------------------------------------------------------------------+
495
496 PURPOSE : A changed ciphering mode is signalled to MM.
497
498 */
499
500 GLOBAL void dat_code_ciphering_to_mm (UBYTE ciph_on)
501 {
502 PALLOC (sync_ind, RR_SYNC_IND);
503
504 TRACE_FUNCTION ("dat_code_ciphering_to_mm()");
505
506 /*
507 * set the new cipher mode
508 */
509 sync_ind->ciph = ciph_on;
510
511 /*
512 * clear the rest of the parameters
513 */
514 sync_ind->chm.ch_mode = NOT_PRESENT_8BIT;
515 memset(&sync_ind->mm_info, 0, sizeof(T_mm_info));
516 sync_ind->mm_info.valid = FALSE;
517 memset(&sync_ind->bcch_info, 0, sizeof(T_bcch_info));
518 sync_ind->bcch_info.v_bcch = FALSE;
519 sync_ind->synccs = NOT_PRESENT_16BIT;
520
521 PSENDX(MM, sync_ind);
522 }
523
524 /*
525 +--------------------------------------------------------------------+
526 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
527 | STATE : code ROUTINE : dat_code_reestablishment_fail |
528 +--------------------------------------------------------------------+
529
530 PURPOSE : Indicate a failed call reestablishment to MM. If a radio
531 link failure has occured, RR performs a cell reselection
532 to come back to idle mode and then the reestablishment may
533 starts. If no suitable cell is available, it may takes
534 a long time until no service is signalled. This function is
535 used to finish the reestablish earlier, if no candidate
536 is available during coming back from dedicated.
537
538 */
539
540 GLOBAL void dat_code_reestablishment_fail (void)
541 {
542 GET_INSTANCE_DATA;
543 T_NC_DATA *rrd = &rr_data->nc_data[SC_INDEX];
544
545 PALLOC (sync_ind, RR_SYNC_IND);
546
547 TRACE_FUNCTION ("dat_code_reestablishment_fail()");
548
549 sync_ind->mm_info.valid = TRUE;
550 sync_ind->mm_info.att = rrd->control_descr.att;
551 /*
552 * No reestablishment
553 */
554 sync_ind->mm_info.re = 1;
555 sync_ind->mm_info.ncc = (rrd->bsic >> 3) & 7;
556 sync_ind->mm_info.bcc = rrd->bsic & 7;
557 sync_ind->mm_info.t3212 = rrd->control_descr.t3212;
558 /*sync_ind->mm_info.la = !dat_forb_lai_check (SC_INDEX);*/
559 sync_ind->mm_info.la = (!(dat_forb_lai_check (SC_INDEX) AND
560 dat_roam_forb_lai_check (SC_INDEX)));
561
562 sync_ind->ciph = NOT_PRESENT_8BIT;;
563 sync_ind->chm.ch_mode = NOT_PRESENT_8BIT;
564 sync_ind->bcch_info.v_bcch = FALSE;
565 sync_ind->synccs = NOT_PRESENT_16BIT;
566
567 PSENDX (MM, sync_ind);
568 }
569
570 /*
571 +--------------------------------------------------------------------+
572 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
573 | STATE : code ROUTINE : dat_code_measure_report |
574 +--------------------------------------------------------------------+
575
576 PURPOSE : RR builds a RR MEASUREMENT REPORT message for the uplink
577 sacch, whenever it receives a measurement report from the
578 layer 1.
579
580 */
581
582 GLOBAL void dat_code_measure_report (T_MPH_MEASUREMENT_IND *report)
583 {
584 GET_INSTANCE_DATA;
585 USHORT i;
586
587 MCAST (meas, U_MEAS_REP);
588 PALLOC_MSG (dl_unitdata_req, DL_UNITDATA_REQ, U_MEAS_REP);/* T_DL_UNITDATA_REQ */
589
590 TRACE_FUNCTION ("dat_code_measure_report()");
591 memset (&dl_unitdata_req->sdu.buf[0], 0, dl_unitdata_req->sdu.o_buf / BITS_PER_BYTE);
592
593 /*
594 * initialize C-structure for the Uplink message
595 */
596 memset (meas, 0, sizeof (T_U_MEAS_REP));
597
598 /*
599 * set message type
600 */
601 meas->msg_type = U_MEAS_REP;
602
603
604 if (report->valid)
605 {
606 /*
607 * measurement report from layer 1 is valid,
608 * then copy data to C-structure for message
609 */
610 meas->meas_result.ba_used = rr_data->sc_data.ba_index;
611 meas->meas_result.dtx_used = report->dtx;
612 meas->meas_result.meas_valid = 0;
613
614 if (rr_data->dyn_config.fho)
615 {
616 /*
617 * forced handover, special test feature to simulate
618 * a bad serving cell
619 */
620 meas->meas_result.rxlev_full = 0;
621 meas->meas_result.rxlev_sub = 0;
622 }
623 else
624 {
625 /*
626 * take values from layer 1
627 */
628 meas->meas_result.rxlev_full = report->rx_lev_full;
629 meas->meas_result.rxlev_sub = report->rx_lev_sub;
630 }
631
632 meas->meas_result.rxqual_full = report->rx_qual_full;
633 meas->meas_result.rxqual_sub = report->rx_qual_sub;
634
635 /*
636 * copy neighbourcell values
637 */
638 meas->meas_result.num_ncell = report->ncells.no_of_ncells;
639
640 #if defined (REL99) && defined (TI_PS_FF_EMR)
641 if ( (rr_data->sc_data.ba_list_idle EQ TRUE) OR
642 (rr_data->sc_data.ba_list_ded EQ TRUE) )
643 #else
644 /*
645 * report ncells only if BA complete or
646 * it´s a expansion (5ter) and the 5/5bis are sent before
647 */
648 if ( (rr_data->sc_data.cd.sys_info_read & (SYS_INFO_5_READ | SYS_INFO_5BIS_READ))
649 EQ (SYS_INFO_5_READ | SYS_INFO_5BIS_READ) )
650 #endif
651 {
652 /*
653 * fill ncells to the measurement report
654 */
655 for (i=0;i<meas->meas_result.num_ncell;i++)
656 {
657 meas->meas_result.ncell[i].bsic = report->ncells.bsic[i];
658
659 /*
660 * set position in neighbourcell list instead of channel number
661 */
662 meas->meas_result.ncell[i].bcch_ncell = dat_get_ncell_pos (report->ncells.arfcn[i]);
663 meas->meas_result.ncell[i].rx_lev_ncell = report->ncells.rx_lev[i];
664
665 TRACE_EVENT_P4 ("MR:%u[%4u] p=%u rxl=%u",
666 i, report->ncells.arfcn[i],
667 meas->meas_result.ncell[i].bcch_ncell,
668 meas->meas_result.ncell[i].rx_lev_ncell); /* +++ */
669
670 }
671 }
672 else
673 {
674 /*
675 * Table 10.5.47/GSM 04.08: Measurement Results information element
676 * Range: 0 to 7 (See GSM 05.08)
677 * NO-NCELL-M, Number of neighbouring cell measurements (octets 4 and 5)
678 *
679 * No neighbour cell measurement result := 0
680 * Neighbour cell information not available for serving cell := 7
681 */
682 meas->meas_result.num_ncell = 7;
683 }
684
685 }
686 else
687 {
688 /*
689 * measurement report from layer 1 is invalid
690 */
691 TRACE_EVENT ("invalid Meas");
692 meas->meas_result.meas_valid = 1;
693 }
694
695 /*
696 * code message and send to layer 2.
697 */
698 for_dat_unitdata_req (dl_unitdata_req);
699 }
700
701
702 /*
703 +--------------------------------------------------------------------+
704 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
705 | STATE : code ROUTINE : dat_code_ext_meas_report |
706 +--------------------------------------------------------------------+
707
708 PURPOSE : RR builds a RR EXTENDED MEASUREMENT REPORT message for the
709 uplink sacch.
710 */
711
712 GLOBAL void dat_code_ext_meas_report (T_MPH_EMO_MEAS_IND *mph_emo_meas_ind)
713 {
714 GET_INSTANCE_DATA;
715 USHORT *emo_arfcn = rr_data-> emo_arfcn;
716 UBYTE c_emo_arfcn = rr_data->c_emo_arfcn;
717 T_ext_meas_res *ext_meas_res;
718 UBYTE *rx_lev_ncell;
719 T_meas_results *meas_results;
720 UBYTE i,k;
721
722 MCAST (u_ext_meas_report, U_EXT_MEAS_REPORT);
723 PALLOC_MSG (dl_unitdata_req, DL_UNITDATA_REQ, U_EXT_MEAS_REPORT);
724
725 TRACE_FUNCTION ("dat_code_ext_meas_report()");
726
727 /*
728 * initialize C-structure for the Uplink message
729 */
730 memset (u_ext_meas_report, 0, sizeof (T_U_EXT_MEAS_REPORT));
731
732 ext_meas_res = &u_ext_meas_report->ext_meas_res;
733
734 /*
735 * set message type
736 */
737 u_ext_meas_report->msg_type = U_EXT_MEAS_REPORT;
738
739 ext_meas_res->sc_used = rr_data->emo_seq;
740 ext_meas_res->dtx_used = mph_emo_meas_ind->dtx;
741
742 rx_lev_ncell = &ext_meas_res->rx_lev_ncell[0];
743 meas_results = &mph_emo_meas_ind->meas_results[0];
744
745 TRACE_ASSERT( c_emo_arfcn <= MAX_EMO_CHANNELS);
746 TRACE_ASSERT( mph_emo_meas_ind->c_meas_results <= (MAX_EMO_CHANNELS +1));
747
748 for ( k = 0; k < c_emo_arfcn; k++ )
749 {
750 for ( i = 0; i < mph_emo_meas_ind->c_meas_results; i++ )
751 {
752 if ( emo_arfcn[k] EQ meas_results[i].arfcn )
753 {
754 rx_lev_ncell[k] = meas_results[i].rx_lev;
755 }
756 }
757 }
758
759 /*
760 * code message and send to layer 2.
761 */
762 for_dat_unitdata_req (dl_unitdata_req);
763
764 }
765
766
767 /*
768 +--------------------------------------------------------------------+
769 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
770 | STATE : code ROUTINE : dat_code_mph_chan_mode_req |
771 +--------------------------------------------------------------------+
772
773 PURPOSE : configure a new channel mode to layer 1.
774
775 */
776
777 GLOBAL void dat_code_mph_chan_mode_req (T_D_CHAN_MOD *chan_mod)
778 {
779 GET_INSTANCE_DATA;
780 PALLOC (channel_mode_req, MPH_CHANNEL_MODE_REQ);
781
782 TRACE_FUNCTION ("dat_code_mph_chan_mode_req()");
783
784 memset(channel_mode_req, 0, sizeof(T_MPH_CHANNEL_MODE_REQ));
785
786 /*
787 * configure layer 1 with multi-rate configuration if present
788 */
789 if ( rr_data->sc_data.ch_mode EQ CM_AMR )
790 {
791 int i;
792 channel_mode_req->amr_conf.nscb = rr_data->sc_data.amr_conf.nscb;
793 channel_mode_req->amr_conf.icmi = rr_data->sc_data.amr_conf.icmi;
794 channel_mode_req->amr_conf.st_mode = rr_data->sc_data.amr_conf.st_mode;
795 channel_mode_req->amr_conf.acs = rr_data->sc_data.amr_conf.set_amr;
796
797 channel_mode_req->amr_conf.v_cod_prop = rr_data->sc_data.amr_conf.v_cod_prop;
798 if(channel_mode_req->amr_conf.v_cod_prop)
799 {
800 channel_mode_req->amr_conf.c_cod_prop = rr_data->sc_data.amr_conf.c_cod_prop;
801 for (i=0; i< channel_mode_req->amr_conf.c_cod_prop; i++)
802 memcpy(&channel_mode_req->amr_conf.cod_prop[i],
803 &rr_data->sc_data.amr_conf.cod_prop[i], sizeof(T_cod_prop));
804 }
805 }
806
807 /*
808 * set new channel mode
809 */
810 channel_mode_req->ch = chan_mod->chan_desc.chan_type;
811 channel_mode_req->mode = chan_mod->chan_mode;
812 PSENDX (PL, channel_mode_req);
813 }
814
815 /*
816 +--------------------------------------------------------------------+
817 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
818 | STATE : code ROUTINE : dat_code_mph_ciphering_req |
819 +--------------------------------------------------------------------+
820
821 PURPOSE : configure new cipher parameter to layer 1.
822
823 */
824
825 GLOBAL void dat_code_mph_ciphering_req (UBYTE ciph_on,
826 UBYTE algo,
827 UBYTE * kc)
828 {
829 PALLOC (mph_ciphering_req, MPH_CIPHERING_REQ);
830
831 TRACE_FUNCTION ("dat_code_mph_ciphering_req()");
832
833 if (ciph_on)
834 {
835 /*
836 * ciphering is on, then set cipher algorithm
837 * and Kc value.
838 */
839 mph_ciphering_req->ciph.stat = CIPH_ON;
840 mph_ciphering_req->ciph.algo = algo;
841 memcpy (mph_ciphering_req->ciph.kc, kc, KC_STRING_SIZE);
842 }
843 else
844 {
845 /*
846 * ciphering is off, then set default values
847 */
848 mph_ciphering_req->ciph.stat = CIPH_OFF;
849 mph_ciphering_req->ciph.algo = 0;
850 memset (mph_ciphering_req->ciph.kc, 0, KC_STRING_SIZE);
851 }
852
853 PSENDX (PL, mph_ciphering_req);
854 }
855
856 /*
857 +--------------------------------------------------------------------+
858 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
859 | STATE : code ROUTINE : dat_code_sys_info_change |
860 +--------------------------------------------------------------------+
861
862 PURPOSE : A change in parameters of system information type 6
863 has been detected. The parameters are configured
864 in layer 1.
865
866 */
867
868 GLOBAL void dat_code_sys_info_change (UBYTE dtx,
869 UBYTE pwrc,
870 UBYTE rlt)
871 {
872 PALLOC (dedicated_req, MPH_DEDICATED_REQ);
873
874 TRACE_FUNCTION ("dat_code_sys_info_change()");
875
876 memset (dedicated_req, 0, sizeof (T_MPH_DEDICATED_REQ));
877
878 /*
879 * set new dtx, rlt, pwrc and ncc_permitted values
880 */
881 dedicated_req->tr_para.dtx = dtx;
882 dedicated_req->tr_para.rlt = rlt;
883 dedicated_req->tr_para.pwrc = pwrc;
884 dedicated_req->mod = MODE_SYS_INFO_CHANGE;
885
886 PSENDX (PL, dedicated_req);
887 }
888
889
890 /*
891 +--------------------------------------------------------------------+
892 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
893 | STATE : code ROUTINE : dat_code_mph_imm_assign_req |
894 +--------------------------------------------------------------------+
895
896 PURPOSE : configure layer 1 after reception of an immediate assignment
897 or immediate assignment extended message.
898
899 */
900
901 GLOBAL void dat_code_mph_imm_assign_req (T_start *start,
902 UBYTE power,
903 UBYTE maio,
904 T_LIST *freq_after_sti,
905 T_LIST *freq_bef_sti)
906 {
907 GET_INSTANCE_DATA;
908
909 PALLOC (dedicated_req, MPH_DEDICATED_REQ);
910
911 TRACE_FUNCTION ("dat_code_mph_imm_assign_req()");
912
913 memset (dedicated_req, 0, sizeof (T_MPH_DEDICATED_REQ));
914
915 dedicated_req->mod = MODE_IMM_ASSIGN;
916
917 /*
918 * set starting time if available
919 */
920 memcpy (&dedicated_req->start, start,
921 sizeof (T_start));
922
923 /*
924 * set channel type
925 */
926 dedicated_req->ch_type.ch = rr_data->sc_data.chan_desc.chan_type;
927 dedicated_req->ch_type.tn = rr_data->sc_data.chan_desc.tn;
928 dedicated_req->ch_type.tsc = rr_data->sc_data.chan_desc.tsc;
929 dedicated_req->ch_type.h = rr_data->sc_data.chan_desc.hop;
930
931 if (rr_data->sc_data.chan_desc.hop EQ H_NO)
932 {
933 /*
934 * set channel number if no hopping is configured
935 */
936 dedicated_req->ch_type.arfcn = rr_data->sc_data.chan_desc.arfcn;
937 }
938 else
939 {
940 /*
941 * set maio, hsn and hopping list, if hopping is configured
942 */
943 dedicated_req->ch_type.maio = rr_data->sc_data.chan_desc.maio;
944 dedicated_req->ch_type.hsn = rr_data->sc_data.chan_desc.hsn;
945
946 /* CSI-LLD section:4.1.1.11
947 * This function Updates the black list with the MA list received
948 * in immediate_assignment req
949 */
950 cs_remove_BA_MA_from_black_list(rr_data->cs_data.region,freq_after_sti);
951
952 srv_create_list (freq_after_sti, dedicated_req->ch_type.ma,
953 MAX_MA_CHANNELS, TRUE, 0);
954 }
955
956 /*
957 * set channel type 2 (only maio and mobile allocation)
958 */
959 dedicated_req->ch_type2.maio = maio;
960
961 /* CSI-LLD section:4.1.1.11
962 * This function Updates the black list with the MA list received
963 * in immediate_assignment req
964 */
965 cs_remove_BA_MA_from_black_list(rr_data->cs_data.region,freq_bef_sti);
966
967 srv_create_list (freq_bef_sti, dedicated_req->ch_type2.ma, MAX_MA_CHANNELS,
968 TRUE, 0);
969
970 dedicated_req->arfcn = rr_data->nc_data[SC_INDEX].arfcn;
971
972 /*
973 * set power, dtx, rlt, pwrc, timing advance and channel mode
974 */
975 dedicated_req->tr_para.power = power;
976 dedicated_req->tr_para.dtx = rr_data->sc_data.cd.dtx;
977 dedicated_req->tr_para.rlt = rr_data->sc_data.cd.cell_options.rlt;
978 dedicated_req->tr_para.pwrc = rr_data->sc_data.cd.cell_options.pow_ctrl;
979 dedicated_req->tr_para.tav = rr_data->sc_data.new_ta;
980 dedicated_req->tr_para.mode = rr_data->sc_data.ch_mode;
981
982 RR_EM_GET_HOPPING_CHANNEL(dedicated_req->ch_type.ma,dedicated_req->ch_type2.ma,
983 dedicated_req->start.v_start,maio);
984
985 PSENDX (PL, dedicated_req);
986 }
987
988 /*
989 +--------------------------------------------------------------------+
990 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
991 | STATE : code ROUTINE : dat_code_mph_freq_redef_req|
992 +--------------------------------------------------------------------+
993
994 PURPOSE : configure a new hopping list after reception of a frequency
995 redefinition message.
996
997 */
998
999 GLOBAL void dat_code_mph_freq_redef_req (T_start *start,
1000 T_LIST *hop_list)
1001 {
1002 GET_INSTANCE_DATA;
1003
1004 T_chan_desc * chan_desc = &rr_data->sc_data.chan_desc;
1005
1006 PALLOC (freq_redef_req, MPH_FREQ_REDEF_REQ);
1007
1008 TRACE_FUNCTION ("dat_code_mph_freq_redef_req()");
1009
1010 /*
1011 * copy start time
1012 */
1013 memcpy (&freq_redef_req->start, start, sizeof (T_start));
1014
1015 /*
1016 * set new hopping list
1017 */
1018 srv_create_list (hop_list, freq_redef_req->ch_type.ma, MAX_MA_CHANNELS, TRUE,0);
1019
1020 /* CSI-LLD section:4.1.1.11
1021 * This function Updates the black list with the MA list received
1022 * in Frequency redifinition message
1023 */
1024 cs_remove_BA_MA_from_black_list(rr_data->cs_data.region,hop_list);
1025
1026 /*
1027 * set channel type, timeslot, training sequence code,
1028 * hopping indication, maio and hsn.
1029 */
1030 freq_redef_req->ch_type.ch = chan_desc->chan_type;
1031 freq_redef_req->ch_type.tn = chan_desc->tn;
1032 freq_redef_req->ch_type.tsc = chan_desc->tsc;
1033 freq_redef_req->ch_type.h = chan_desc->hop;
1034 freq_redef_req->ch_type.maio = chan_desc->maio;
1035 freq_redef_req->ch_type.hsn = chan_desc->hsn;
1036
1037 rr_data->mode_after_dedi = MODE_CELL_RESELECTION;
1038
1039 EM_FREQ_REDEF;
1040
1041 RR_EM_GET_HOPPING_CHANNEL (freq_redef_req->ch_type.ma, freq_redef_req->ch_type.ma, FALSE,0);
1042
1043 PSENDX (PL, freq_redef_req);
1044 }
1045
1046 /*
1047 +--------------------------------------------------------------------+
1048 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1049 | STATE : code ROUTINE : dat_code_mph_old_chan_req |
1050 +--------------------------------------------------------------------+
1051
1052 PURPOSE : During channel assignment or handover the layer 2 link is
1053 suspended and a new channel is configured. Then the layer 2
1054 connection is resumed on the new channel. If this fails,
1055 RR switches back to the old channel. The trigger for this
1056 is this function.
1057
1058 */
1059
1060 GLOBAL void dat_code_mph_old_chan_req (void)
1061 {
1062 PALLOC ( mph_dedicated_fail_req, MPH_DEDICATED_FAIL_REQ);
1063
1064 TRACE_FUNCTION ("dat_code_mph_old_chan_req()");
1065
1066 PSENDX (PL, mph_dedicated_fail_req);
1067 }
1068
1069 /*
1070 +--------------------------------------------------------------------+
1071 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1072 | STATE : code ROUTINE : dat_code_prr_channel |
1073 +--------------------------------------------------------------------+
1074
1075 PURPOSE : Set the channel type and the service access point
1076 identification according to the configured channel type.
1077
1078 */
1079
1080 GLOBAL void dat_code_prr_channel (UBYTE *ch_type,
1081 UBYTE *sapi,
1082 UBYTE chan_type)
1083 {
1084 TRACE_FUNCTION ("dat_code_prr_channel()");
1085
1086 /*
1087 * SAPI is always 0
1088 */
1089 *sapi = SAPI_0;
1090
1091 /*
1092 * convert air-interface coding of channel type
1093 * to internal values.
1094 */
1095 switch (chan_type)
1096 {
1097 case CH_TCH_F:
1098 *ch_type = L2_CHANNEL_FACCH_F;
1099 break;
1100 case CH_TCH_H_1:
1101 case CH_TCH_H_2:
1102 *ch_type = L2_CHANNEL_FACCH_H;
1103 break;
1104 default:
1105 *ch_type = L2_CHANNEL_SDCCH;
1106 break;
1107 }
1108 }
1109
1110
1111 /*
1112 +--------------------------------------------------------------------+
1113 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1114 | STATE : code ROUTINE : dat_code_prr_channel_sms |
1115 +--------------------------------------------------------------------+
1116
1117 PURPOSE : Set the channel type and the service access point
1118 identification according to the configured channel type
1119 for short messages.
1120
1121 */
1122
1123 GLOBAL void dat_code_prr_channel_sms (T_DL_DATA_REQ *dl_data_req,
1124 UBYTE chan_type)
1125 {
1126 TRACE_FUNCTION ("dat_code_prr_channel_sms()");
1127
1128 /*
1129 * sapi is always 3
1130 */
1131 dl_data_req->sapi = SAPI_3;
1132
1133 /*
1134 * channel type is SACCH if the main channel (sapi = 0)
1135 * is FACCH, else it is SDCCH.
1136 */
1137 dl_data_req->ch_type = (chan_type < CH_SDCCH_4_0)\
1138 ? L2_CHANNEL_SACCH : L2_CHANNEL_SDCCH;
1139 }
1140
1141
1142 /*
1143 +--------------------------------------------------------------------+
1144 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1145 | STATE : code ROUTINE : dat_code_prr_bcch_info |
1146 +--------------------------------------------------------------------+
1147
1148 PURPOSE : create a list of channels from the ba_range information
1149 element of a channel release message.
1150
1151 */
1152
1153 GLOBAL void dat_code_prr_bcch_info (UBYTE v_ba_range,
1154 T_ba_range * ba_range)
1155 {
1156 T_LIST list;
1157 USHORT i;
1158 USHORT j;
1159 USHORT x1;
1160 USHORT x2;
1161
1162 TRACE_FUNCTION ("dat_code_prr_bcch_info()");
1163
1164 /*
1165 * initialization : the list is empty.
1166 */
1167 srv_clear_list (&list);
1168
1169 if (v_ba_range)
1170 {
1171 /*
1172 * only if the information element is inside the
1173 * channel release message.
1174 * Then for all ranges inside the information element.
1175 */
1176 for (i=0;i<ba_range->c_freq_range;i++)
1177 {
1178 x1 = ba_range->freq_range[i].freq_lower;
1179 x2 = ba_range->freq_range[i].freq_higher;
1180 /*
1181 * set interval borders
1182 */
1183 if (x1 > HIGH_CHANNEL_900)
1184 x1 = HIGH_CHANNEL_900;
1185 if (x2 > HIGH_CHANNEL_900)
1186 x2 = HIGH_CHANNEL_900;
1187
1188 if (x1 EQ x2)
1189 {
1190 /*
1191 * add x1 to channel list if both boarders have the same value
1192 */
1193 srv_set_channel (&list, x1);
1194 }
1195
1196 if (x1 < x2)
1197 {
1198 /*
1199 * add x1..x2 to channel list if the boarders define a range
1200 */
1201 for (j=x1;j<=x2;j++)
1202 srv_set_channel (&list, j);
1203 }
1204
1205 if (x1 > x2)
1206 {
1207 /*
1208 * add LOW_CHANNEL_900..x2 and x1..HIGH_CHANNEL_900 to channel list
1209 */
1210 for (j=LOW_CHANNEL_900;j<=HIGH_CHANNEL_900;j++)
1211 if (j <= x2 OR j>=x1)
1212 srv_set_channel (&list, j);
1213 }
1214 }
1215
1216 /*
1217 * send the resulting list to the SIM card or store it inside the PCM
1218 */
1219 }
1220 }
1221
1222
1223 /*
1224 +--------------------------------------------------------------------+
1225 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1226 | STATE : code ROUTINE : dat_send_bcchinfo_mm |
1227 +--------------------------------------------------------------------+
1228
1229 PURPOSE : Send neigbour cell description to MM
1230
1231 */
1232
1233 GLOBAL void dat_send_bcchinfo_mm (UBYTE *p)
1234 {
1235 PALLOC (sync_ind, RR_SYNC_IND);
1236 sync_ind->ciph = NOT_PRESENT_8BIT;
1237 sync_ind->chm.ch_mode = NOT_PRESENT_8BIT;
1238 sync_ind->mm_info.valid = FALSE;
1239 sync_ind->bcch_info.v_bcch = TRUE;
1240 sync_ind->synccs = NOT_PRESENT_16BIT;
1241 if (p)
1242 {
1243 memcpy (sync_ind->bcch_info.bcch, p, BA_BITMAP_SIZE);
1244 TRACE_EVENT_P4 ("BCCHINFO: send 16 byte to MM/SIM (%x,%x,%x,%x,...)", p[0], p[1], p[2], p[3]);
1245 }
1246 else
1247 {
1248 memset (sync_ind->bcch_info.bcch, 0, BA_BITMAP_SIZE);
1249 TRACE_EVENT ("BCCHINFO: clear SIM");
1250 }
1251 PSENDX (MM, sync_ind);
1252 }
1253
1254 /*
1255 +--------------------------------------------------------------------+
1256 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1257 | STATE : code ROUTINE : dat_convert_white_list |
1258 +--------------------------------------------------------------------+
1259
1260 PURPOSE : Updates White List after cell selection and cell reselection
1261 in Full service
1262 CSI-LLD section:4.1.2.2.2
1263 */
1264
1265 GLOBAL void dat_convert_white_list(void)
1266 {
1267 GET_INSTANCE_DATA;
1268 U8 *p = NULL;
1269 U8 i;
1270 T_LIST tmp_list;
1271 BUF_neigh_cell_desc cd;
1272
1273 TRACE_FUNCTION("dat_convert_white_list()");
1274
1275 if(rr_data->ms_data.rr_service EQ FULL_SERVICE)
1276 {
1277 TRACE_EVENT("CR white list -> CS white list");
1278
1279 /* Clear the old White List info */
1280 memset(&rr_data->cs_data.white_list, 0x00, sizeof(T_CS_WHITE_LIST));
1281
1282 /* copy the serving cell ARFCN */
1283 rr_data->cs_data.white_list.last_sc_arfcn = rr_data->nc_data[SC_INDEX].arfcn;
1284
1285 /* copy the serving cell region */
1286 rr_data->cs_data.white_list.region = rr_data->cs_data.region;
1287
1288 /* Copy the serving cell location area identity */
1289 memcpy(&rr_data->cs_data.white_list.last_sc_lac,&rr_data->nc_data[SC_INDEX].lai,
1290 sizeof(T_loc_area_ident));
1291
1292 /* Convert CR white list into T_LIST format and store the same */
1293 for(i=0;i<=32;i+=BA_BITMAP_SIZE)
1294 {
1295 switch(i)
1296 {
1297 case 0:
1298 p = rr_data->cr_data.cr_white_list.si2;
1299 break;
1300 case 16:
1301 p = rr_data->cr_data.cr_white_list.si2bis;
1302 break;
1303 case 32:
1304 p = rr_data->cr_data.cr_white_list.si2ter;
1305 break;
1306 default:
1307 continue;
1308 }
1309
1310 if(p NEQ NULL)
1311 {
1312 memcpy(cd.b_neigh_cell_desc,p,BA_BITMAP_SIZE);
1313 cd.o_neigh_cell_desc = 0;
1314 cd.l_neigh_cell_desc = NCELL_DESC_BIT_LEN;
1315
1316 for_create_channel_list((T_f_range *)&cd,&tmp_list);
1317 srv_merge_list(&rr_data->cs_data.white_list.list,&tmp_list);
1318 }
1319 }
1320
1321 /* Use last serving cell information also */
1322 if(rr_data->cs_data.white_list.last_sc_arfcn NEQ NOT_PRESENT_16BIT)
1323 {
1324 srv_set_channel(&rr_data->cs_data.white_list.list,
1325 rr_data->cs_data.white_list.last_sc_arfcn&ARFCN_MASK);
1326 }
1327
1328 TRACE_EVENT_P9 ( "White List:[%d]Reg,[%d]Arfcn MCC/MNC r=%x%x%x/%x%x%x/%d",
1329 rr_data->cs_data.white_list.region,
1330 rr_data->cs_data.white_list.last_sc_arfcn,
1331 rr_data->cs_data.white_list.last_sc_lac.mcc[0],
1332 rr_data->cs_data.white_list.last_sc_lac.mcc[1],
1333 rr_data->cs_data.white_list.last_sc_lac.mcc[2],
1334 rr_data->cs_data.white_list.last_sc_lac.mnc[0],
1335 rr_data->cs_data.white_list.last_sc_lac.mnc[1],
1336 rr_data->cs_data.white_list.last_sc_lac.mnc[2],
1337 rr_data->cs_data.white_list.last_sc_lac.lac);
1338
1339 } /* Full service */
1340 }
1341
1342
1343 /*
1344 +--------------------------------------------------------------------+
1345 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1346 | STATE : code ROUTINE : dat_store_neigh_cell_desc |
1347 +--------------------------------------------------------------------+
1348
1349 PURPOSE : Store neigbour cell description in case of full service
1350
1351 */
1352
1353 GLOBAL void dat_store_neigh_cell_desc (UBYTE si, UBYTE index,
1354 BUF_neigh_cell_desc *cd,
1355 T_LIST *new_neigh_list)
1356 {
1357 GET_INSTANCE_DATA;
1358 U8 *p = NULL;
1359 U16 o;
1360 U8 att_state = GET_STATE (STATE_ATT);
1361
1362 #if defined(_SIMULATION_)
1363 {
1364 BOOL plmn_ok;
1365
1366 plmn_ok = dat_plmn_equal_req (rr_data->nc_data[index].lai.mcc,
1367 rr_data->nc_data[index].lai.mnc,
1368 rr_data->ms_data.plmn.mcc,
1369 rr_data->ms_data.plmn.mnc);
1370 TRACE_EVENT_P8 ("dat_store_neigh_cell_desc(): srv:%s op:%s tried:%u, st:%s, NC%u plmn:%u CR:%d SC:%d",
1371 _rr_str_SERVICE[rr_data->ms_data.rr_service],
1372 _rr_str_FUNC[rr_data->ms_data.req_mm_service],
1373 (rr_data->cs_data.scan_mode EQ CS_SECOND_SCAN),
1374 STATE_ATT_NAME[att_state], index, plmn_ok,
1375 ((int)rr_data->nc_data[CR_INDEX].arfcn),
1376 ((int)rr_data->nc_data[SC_INDEX].arfcn));
1377 }
1378 #endif /* 0|1 */
1379
1380 if (rr_data->ms_data.req_mm_service EQ FUNC_PLMN_SRCH)
1381 {
1382 /*
1383 * In states ATT_CS2 and ATT_CS3, store BA lists from SI2, 2Bis and 2Ter
1384 * inside rr_data->cr_data
1385 */
1386 if ((att_state EQ ATT_CS2 OR att_state EQ ATT_CS3) AND (index EQ CR_INDEX))
1387 {
1388 switch (si)
1389 {
1390 case SYS_INFO_2_MSG:
1391 p = rr_data->cr_data.cr_white_list.si2;
1392 break;
1393 case SYS_INFO_2bis_MSG:
1394 p = rr_data->cr_data.cr_white_list.si2bis;
1395 break;
1396 case SYS_INFO_2ter_MSG:
1397 p = rr_data->cr_data.cr_white_list.si2ter;
1398 break;
1399 default:
1400 return;
1401 }
1402
1403 TRACE_EVENT_P3 ("BCCHINFO: store cd of [%d]i%u: si=%02x ",
1404 rr_data->nc_data[index].arfcn, index, si);
1405
1406 /* compare; store and indicate only if changed */
1407 o = cd->o_neigh_cell_desc>>3;
1408 if (p NEQ NULL)
1409 {
1410 if (memcmp (p, &cd->b_neigh_cell_desc[o], BA_BITMAP_SIZE))
1411 {
1412 memcpy (p, &cd->b_neigh_cell_desc[o], BA_BITMAP_SIZE);
1413 }
1414 }
1415 } /* CR_INDEX */
1416
1417 else if((att_state EQ ATT_IDLE) AND (index EQ SC_INDEX) AND
1418 (rr_data->ms_data.rr_service EQ FULL_SERVICE))
1419 {
1420 /* In state ATT_IDLE, store BA list directly inside the white list
1421 * (only if we are in Full Service)
1422 */
1423 srv_copy_list (&rr_data->cs_data.white_list.list, new_neigh_list,
1424 sizeof (T_LIST));
1425
1426 /* Add current serving cell to White List */
1427 srv_set_channel(&rr_data->cs_data.white_list.list,
1428 rr_data->nc_data[SC_INDEX].arfcn&ARFCN_MASK);
1429
1430 if(si EQ SYS_INFO_2_MSG)
1431 {
1432 /* In case it is the description of system information 2 (and only then)
1433 * it should be stored in the SIM card.
1434 */
1435 o = cd->o_neigh_cell_desc>>3;
1436 dat_send_bcchinfo_mm (&cd->b_neigh_cell_desc[o]);
1437 }
1438 }
1439
1440 /* additional storing of current serving cell and cell-re-selection cell */
1441 rr_data->cs_data.arfcn_sc = rr_data->nc_data[SC_INDEX].arfcn;
1442 rr_data->cs_data.arfcn_cr = rr_data->nc_data[CR_INDEX].arfcn;
1443 }
1444 }
1445
1446
1447
1448 /*
1449 +--------------------------------------------------------------------+
1450 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1451 | STATE : code ROUTINE : dat_compare_request_ref |
1452 +--------------------------------------------------------------------+
1453
1454 PURPOSE : Reference is GSM 4.08, chapter 3.3.1.1.3.1 On receipt of a
1455 CHANNEL REQUEST message
1456
1457 On receipt of an IMMEDIATE ASSIGNMENT or IMMEDIATE ASSIGNMENT
1458 EXTENDED message corresponding to one of its 3 last CHANNEL
1459 REQUEST messages, the message shall be identified as the
1460 channel description for the MS.
1461
1462 */
1463
1464 GLOBAL BOOL dat_compare_request_ref (T_req_ref *req_ref, UBYTE * index)
1465 {
1466 GET_INSTANCE_DATA;
1467 UBYTE from;
1468 UBYTE i;
1469
1470 TRACE_FUNCTION ("dat_compare_request_ref()");
1471
1472 /*
1473 * RR stores the request references for all outgoing
1474 * channel requests. The variable from indicates the
1475 * beginning of the maximum 3 last channel requests.
1476 */
1477
1478 from = (rr_data->ms_data.access_counter > 2) ?
1479 rr_data->ms_data.access_counter - 3 : 0;
1480
1481 TRACE_EVENT_P4 ("compare: %d %d %d 0x%02x",
1482 req_ref->t1, req_ref->t2, req_ref->t3, req_ref->ra);
1483
1484 TRACE_ASSERT( rr_data->ms_data.access_counter <= MAX_RACH_REQ);
1485
1486 for (i = from; i < rr_data->ms_data.access_counter; i++)
1487 {
1488 /*
1489 * RR checks the sending time T1/T2/T3 of the channel
1490 * request message and the content of the message.
1491 * If all matches the immediate assignment (extended)
1492 * message is identified for the MS.
1493 */
1494 TRACE_EVENT_P5 ("with[%u]: %d %d %d 0x%02x", i,
1495 rr_data->used_frame_no[i].t1, rr_data->used_frame_no[i].t2,
1496 rr_data->used_frame_no[i].t3, rr_data->used_channel_ref[i]);
1497
1498 if (rr_data->used_frame_no[i].t1 EQ req_ref->t1 AND
1499 rr_data->used_frame_no[i].t2 EQ req_ref->t2 AND
1500 rr_data->used_frame_no[i].t3 EQ req_ref->t3 AND
1501 rr_data->used_channel_ref[i] EQ req_ref->ra)
1502 {
1503 *index = i;
1504 return TRUE;
1505 }
1506 }
1507
1508 /*
1509 * The message is not for the MS
1510 */
1511 return FALSE;
1512 }
1513
1514 /*
1515 +--------------------------------------------------------------------+
1516 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1517 | STATE : code ROUTINE : dat_disconnect_link |
1518 +--------------------------------------------------------------------+
1519
1520 PURPOSE : After reception of a channel release message this function
1521 starts the disconnection of the link in layer 2.
1522
1523 */
1524
1525 GLOBAL void dat_disconnect_link (USHORT cause)
1526 {
1527 GET_INSTANCE_DATA;
1528 UBYTE ch_type;
1529
1530 PALLOC (dl_release_req, DL_RELEASE_REQ);
1531
1532 TRACE_FUNCTION ("dat_disconnect_link()");
1533
1534 rr_data->rel_cause = cause;
1535
1536 /*
1537 * set channel type and sapi according the configured channel
1538 * configuration
1539 */
1540 dat_code_prr_channel (&dl_release_req->ch_type,
1541 &dl_release_req->sapi,
1542 rr_data->sc_data.chan_desc.chan_type);
1543
1544 ch_type = dl_release_req->ch_type;
1545 dl_release_req->mode = DL_NORMAL_RELEASE;
1546 PSENDX (DL, dl_release_req);
1547
1548 /*
1549 * control layer 2 release. The timer shall be set in a way
1550 * that layer 2 has enough time for at least two DISC frames.
1551 * So the value of the timer depends on the channel type
1552 * (SDCCH or FACCH).
1553 */
1554 if (ch_type EQ L2_CHANNEL_SDCCH)
1555 {
1556 TIMERSTART (T3110, T3110_SDCCH_VALUE);
1557 }
1558 else
1559 {
1560 TIMERSTART (T3110, T3110_VALUE);
1561 }
1562
1563 SET_STATE (STATE_DAT, DAT_CHAN_REL);
1564 }
1565
1566 /*
1567 +--------------------------------------------------------------------+
1568 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1569 | STATE : code ROUTINE : dat_fill_mobile_identity |
1570 +--------------------------------------------------------------------+
1571
1572 PURPOSE : In several update message the mobile identity must be set.
1573 For mobile terminated message the mobile identity of
1574 the paging message must be used.
1575 For mobile originated connections the mobile identity type
1576 depends on the availability of the mobile identities in
1577 this order: TMSI, IMSI, no identity
1578
1579 */
1580
1581 static void dat_fill_mobile_identity (USHORT fill_type,
1582 T_mob_ident *moid)
1583 {
1584 GET_INSTANCE_DATA;
1585 UBYTE mobile_type;
1586
1587 TRACE_FUNCTION ("dat_fill_mobile_identity()");
1588
1589 memset (moid, 0, sizeof (T_mob_ident));
1590
1591 /*
1592 * for MTC set the type according the paging identity type.
1593 */
1594 if (fill_type EQ ESTCS_PAGING)
1595 mobile_type = rr_data->page_identity_type;
1596 else
1597 {
1598 /*
1599 * for MOC set the type according the availability
1600 */
1601 if (rr_data->ms_data.tmsi_available)
1602 mobile_type = TYPE_TMSI;
1603 else
1604 mobile_type = (rr_data->ms_data.imsi_available)
1605 ? TYPE_IMSI : TYPE_NO_ID;
1606 }
1607
1608 /*
1609 * fill the identity according the calculated type
1610 */
1611 switch (mobile_type)
1612 {
1613 case TYPE_TMSI:
1614 TRACE_EVENT ("FILL TMSI");
1615 moid->ident_type = TYPE_TMSI;
1616 moid->tmsi_1.l_tmsi_1 = 32;
1617 moid->tmsi_1.o_tmsi_1 = 0;
1618 moid->odd_even = 0;
1619 moid->v_tmsi_1 = TRUE;
1620 ccd_codeByte (moid->tmsi_1.b_tmsi_1, 0, 8, (UBYTE)(rr_data->ms_data.tmsi_binary >> 24));
1621 ccd_codeByte (moid->tmsi_1.b_tmsi_1, 8, 8, (UBYTE)(rr_data->ms_data.tmsi_binary >> 16));
1622 ccd_codeByte (moid->tmsi_1.b_tmsi_1, 16, 8, (UBYTE)(rr_data->ms_data.tmsi_binary >> 8));
1623 ccd_codeByte (moid->tmsi_1.b_tmsi_1, 24, 8, (UBYTE)rr_data->ms_data.tmsi_binary);
1624 break;
1625
1626 case TYPE_IMSI:
1627 TRACE_EVENT ("FILL IMSI");
1628 memcpy (moid, &rr_data->ms_data.imsi, sizeof (T_mob_ident));
1629 break;
1630
1631 default:
1632 TRACE_EVENT ("FILL NOTHING");
1633 memset (moid, 0, sizeof (T_mob_ident));
1634 break;
1635 }
1636 }
1637
1638
1639 /*
1640 +--------------------------------------------------------------------+
1641 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1642 | STATE : code ROUTINE : dat_check_forb_list |
1643 +--------------------------------------------------------------------+
1644
1645 PURPOSE : In automatic mode a cell shall be only selected if it is
1646 not member of a forbidden location area list.
1647 This function checks the membership in a forbidden LAI
1648 independant of the selected mode (manual or automatic).
1649
1650 */
1651
1652 LOCAL BOOL dat_check_forb_list (int list_type, UBYTE index)
1653 {
1654 GET_INSTANCE_DATA;
1655 int i;
1656 T_loc_area_ident *forb_list;
1657
1658 TRACE_FUNCTION ("dat_check_forb_list()");
1659
1660 if (list_type EQ FORBIDDEN_LIST_NORMAL)
1661 forb_list = &rr_data->ms_data.forb_lac_list[0];
1662 else
1663 forb_list = &rr_data->ms_data.roam_forb_lac_list[0];
1664
1665 TRACE_ASSERT(index < NCELL_SIZE);
1666
1667 /*
1668 *
1669 * check only in automatic mode
1670 *
1671 * if ((rr_data->ms_data.operation_mode & 0x40) EQ 0) M_MAN
1672 */
1673 {
1674 /*
1675 * check all entries of this list
1676 */
1677 for (i = 0; i < MAX_LAI; i++)
1678 {
1679 if ((rr_data->nc_data[index].lai.lac EQ forb_list[i].lac) AND
1680 dat_plmn_equal_req (rr_data->nc_data[index].lai.mcc,
1681 rr_data->nc_data[index].lai.mnc,
1682 forb_list[i].mcc,
1683 forb_list[i].mnc))/*lint !e661 !e662 (possible access/creation of out-of-bounds pointer)*/
1684 {
1685 /*
1686 * the check is failed if the location area code is stored.
1687 */
1688 return FALSE;
1689 }
1690 }
1691 }
1692 /*
1693 * the check has passed.
1694 */
1695 return TRUE;
1696 }
1697
1698
1699 /*
1700 +--------------------------------------------------------------------+
1701 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1702 | STATE : code ROUTINE : dat_forb_lai_check |
1703 +--------------------------------------------------------------------+
1704
1705 PURPOSE : In automatic mode a cell shall be only selected if it is
1706 not member of a forbidden location area list.
1707
1708 */
1709
1710 GLOBAL BOOL dat_forb_lai_check (UBYTE index)
1711 {
1712 TRACE_FUNCTION ("dat_forb_lai_check()");
1713
1714 return dat_check_forb_list (FORBIDDEN_LIST_NORMAL, index);
1715 }
1716
1717
1718 /*
1719 +--------------------------------------------------------------------+
1720 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1721 | STATE : code ROUTINE : dat_roam_forb_lai_check |
1722 +--------------------------------------------------------------------+
1723
1724 PURPOSE : In automatic mode a cell shall be only selected if it is
1725 not member of a forbidden location area list.
1726
1727 */
1728
1729 GLOBAL BOOL dat_roam_forb_lai_check (UBYTE index)
1730 {
1731 TRACE_FUNCTION ("dat_roam_forb_lai_check()");
1732
1733 return dat_check_forb_list (FORBIDDEN_LIST_ROAMING, index);
1734 }
1735
1736
1737 /*
1738 +--------------------------------------------------------------------+
1739 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1740 | STATE : code ROUTINE : dat_get_background_and_bits|
1741 +--------------------------------------------------------------------+
1742
1743 PURPOSE : The content of a channel request consists of two parts:
1744 The establishment cause and a random value. The function
1745 calculates the establishment cause (here defined as background)
1746 and the number of bits for the random value.
1747
1748 The establishment cause inside the channel request message
1749 depends on several parameters:
1750
1751 the internal used establishment cause,
1752 the last used channel
1753 the NECI-Flag in the system information message
1754 the needed channel indicated in a paging message
1755 the mobile station capabilities and
1756 whether a TCH fullrate is needed
1757
1758 The abbreviation IG means Ignore. In this case the parameter
1759 is not relevant for the calculation.
1760
1761 */
1762 #ifdef GPRS
1763 #define TABLE_SIZE 30
1764 #else
1765 #define TABLE_SIZE 21
1766 #endif
1767
1768 static const CODE_TABLE coding_table [TABLE_SIZE] =
1769 /*
1770 * establish cause last NECI channel MS TCH/F Back- Bits
1771 * channel needed cap. needed ground
1772 */
1773 { ESTCS_EMERGENCY_CALL, IG, IG, IG, IG, IG, 0xA0, 5,
1774 ESTCS_REESTABLISHMENT, TCHFCH, IG, IG, IG, IG, 0xC0, 5,
1775 ESTCS_REESTABLISHMENT, TCHHCH, 0, IG, IG, IG, 0xC0, 5,
1776 ESTCS_REESTABLISHMENT, TCHHCH, 1, IG, IG, IG, 0x68, 2,
1777 #ifdef GPRS
1778 ESTCS_GPRS_PAGING, IG, IG, ANYCH, IG, IG, 0x80, 5,
1779 ESTCS_GPRS_PAGING, IG, IG, TCHFCH, FULL, IG, 0x80, 5,
1780 ESTCS_GPRS_PAGING, IG, IG, TCHHFCH, FULL, IG, 0x80, 5,
1781 ESTCS_GPRS_PAGING, IG, IG, TCHFCH, DUAL, IG, 0x20, 4,
1782 ESTCS_GPRS_PAGING, IG, IG, TCHHFCH, DUAL, IG, 0x30, 4,
1783 ESTCS_GPRS_PAGING, IG, IG, SDCCHCH, IG, IG, 0x10, 4,
1784 ESTCS_GPRS_PAGING, IG, IG, IG, SIGN, IG, 0x10, 4,
1785 #endif
1786 ESTCS_PAGING, IG, IG, ANYCH, IG, IG, 0x80, 5,
1787 ESTCS_PAGING, IG, IG, TCHFCH, FULL, IG, 0x80, 5,
1788 ESTCS_PAGING, IG, IG, TCHHFCH, FULL, IG, 0x80, 5,
1789 ESTCS_PAGING, IG, IG, TCHFCH, DUAL, IG, 0x20, 4,
1790 ESTCS_PAGING, IG, IG, TCHHFCH, DUAL, IG, 0x30, 4,
1791 ESTCS_PAGING, IG, IG, SDCCHCH, IG, IG, 0x10, 4,
1792 ESTCS_PAGING, IG, IG, IG, SIGN, IG, 0x10, 4,
1793 ESTCS_MOC_SPEECH, IG, 0, IG, IG, IG, 0xE0, 5,
1794 ESTCS_MOC_SPEECH, IG, 1, IG, DUAL, FALSE, 0x40, 4,
1795 ESTCS_MOC_SPEECH, IG, IG, IG, IG, IG, 0xE0, 5,
1796 ESTCS_MOC_DATA, IG, 0, IG, IG, IG, 0xE0, 5,
1797 ESTCS_MOC_DATA_HR_SUFF, IG, 1, IG, DUAL, FALSE, 0x50, 4,
1798 ESTCS_MOC_DATA, IG, IG, IG, IG, IG, 0xE0, 5,
1799 ESTCS_LOCATION_UPDATING, IG, 0, IG, IG, IG, 0x00, 5, /* new */
1800 ESTCS_LOCATION_UPDATING, IG, 1, IG, IG, IG, 0x00, 4,
1801 ESTCS_MOC_SS_SMS, IG, 0, IG, IG, IG, 0xE0, 5,
1802 #ifndef GPRS
1803 ESTCS_MOC_SS_SMS, IG, 1, IG, IG, IG, 0x10, 4
1804 #else
1805 ESTCS_MOC_SS_SMS, IG, 1, IG, IG, IG, 0x10, 4,
1806 ESTCS_GPRS_1P, IG, IG, IG, IG, IG, 0x78, 3,
1807 ESTCS_GPRS_SB, IG, IG, IG, IG, IG, 0x70, 3
1808 #endif
1809 };
1810
1811 static void dat_get_background_and_bits (UBYTE *background,
1812 UBYTE *bits)
1813 {
1814 GET_INSTANCE_DATA;
1815
1816 UBYTE i;
1817 USHORT ms_capability;
1818
1819 TRACE_FUNCTION ("dat_get_background_and_bits()");
1820
1821 /*
1822 * initialise the output parameter
1823 */
1824 *background = 0;
1825 *bits = 5;
1826 ms_capability = SIGN;
1827
1828 /*
1829 * check the support of vocoder
1830 */
1831 if (FldGet(rr_data->mscap.chnMode, VocSup))
1832 {
1833 ms_capability = (FldGet (rr_data->mscap.chnMode, hrSup)) ? DUAL : FULL;
1834 }
1835
1836 /*
1837 * go through the table until all criterions are passed (or can be ignored).
1838 */
1839 for (i = 0; i < TABLE_SIZE; i++)
1840 {
1841 /*
1842 * check internal establishment cause
1843 */
1844 if (rr_data->ms_data.establish_cause NEQ coding_table[i].cause)
1845 continue;
1846
1847 /*
1848 * check last used channel if applicable
1849 */
1850 if (coding_table[i].last_channel NEQ IG)
1851 {
1852 if (rr_data->ms_data.last_used_channel NEQ
1853 coding_table[i].last_channel)
1854 continue;
1855 }
1856
1857 /*
1858 * check new establishment cause indication flag if applicable
1859 */
1860 if (coding_table[i].neci_flag NEQ IG)
1861 {
1862 if (rr_data->nc_data[SC_INDEX].select_para.neci NEQ
1863 coding_table[i].neci_flag)
1864 continue;
1865 }
1866
1867 /*
1868 * check the channel needed indication of the paging messages
1869 * if applicable
1870 */
1871 if (coding_table[i].channel_needed NEQ IG)
1872 {
1873 if (rr_data->ms_data.channel_needed NEQ
1874 coding_table[i].channel_needed)
1875 continue;
1876 }
1877
1878 /*
1879 * check the MS capability if applicable
1880 */
1881 if (coding_table[i].ms_capability NEQ IG)
1882 {
1883 if (ms_capability NEQ coding_table[i].ms_capability)
1884 continue;
1885 }
1886
1887 /*
1888 * check the TCH Fullrate needed flag is applicable.
1889 */
1890 if (coding_table[i].tch_f_needed NEQ IG)
1891 {
1892 if ((rr_data->ms_data.establish_cause NEQ ESTCS_MOC_SPEECH) AND
1893 (rr_data->ms_data.establish_cause NEQ ESTCS_MOC_DATA_HR_SUFF))
1894 continue;
1895 }
1896
1897 /*
1898 * add this point all criterions are passed, so use the table contents.
1899 */
1900 *background = coding_table[i].background;
1901 *bits = coding_table[i].bits;
1902 return;
1903 }
1904 }
1905
1906 /*
1907 +--------------------------------------------------------------------+
1908 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1909 | STATE : code ROUTINE : dat_get_burst |
1910 +--------------------------------------------------------------------+
1911
1912 PURPOSE : This functions adds a random value to the channel request
1913 content. The random value is calculated from a well distributed
1914 table.
1915
1916 */
1917 static const UBYTE random_values[32] = { 9, 27, 17, 6, 10, 15, 2, 23,
1918 29, 14, 4, 26, 18, 0, 31, 13,
1919 21, 1, 30, 22, 5, 24, 20, 8,
1920 7, 28, 16, 11, 25, 12, 3, 19
1921 };
1922 static const UBYTE mask[] = { 3, 7, 15, 31 };
1923
1924 static UBYTE dat_get_burst (UBYTE background,
1925 UBYTE bits)
1926 {
1927 GET_INSTANCE_DATA;
1928 UBYTE random_value;
1929
1930 TRACE_FUNCTION ("dat_get_burst()");
1931
1932 rr_data->ms_data.index++;
1933 rr_data->ms_data.index %= 32;
1934 random_value = random_values[rr_data->ms_data.index];
1935
1936 #ifdef GPRS
1937 if(
1938 (rr_data->ms_data.establish_cause EQ ESTCS_GPRS_1P)
1939 AND
1940 ((random_value & mask[bits - 2]) EQ 7)
1941 )
1942 {
1943
1944 return (background + 6);
1945 }
1946 #endif
1947
1948 return (background + (random_value & mask[bits - 2]));
1949 }
1950
1951 /*
1952 +--------------------------------------------------------------------+
1953 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
1954 | STATE : code ROUTINE : dat_get_delta |
1955 +--------------------------------------------------------------------+
1956
1957 PURPOSE : Reference GSM 4.08, chapter 3.3.1.1.2 Initiation of the
1958 immediate assignment procedure
1959
1960 The RR entity of the mobile station initiates the immediate
1961 assignment procedure by scheduling the sending on the
1962 RACH and leaving idle mode.
1963
1964 It then sends maximally M + 1 CHANNEL REQUEST messages on
1965 the RACH in a way such that:
1966
1967 - the number of slots belonging to the mobile station's RACH
1968 between initiation of the immediate assignment procedure and
1969 the first CHANNEL REQUEST message (excluding the slot containing
1970 the message itself) is a random value drawn randomly for each
1971 new initial assignment initiation with uniform probability
1972 distribution in the set {0, 1, ..., max (T,8) - 1};
1973
1974 - the number of slots belonging to the mobile station's RACH
1975 between two successive CHANNEL REQUEST messages (excluding
1976 the slots containing the messages themselves) is a random value
1977 drawn randomly for each new transmission with uniform probability
1978 distribution in the set {S, S + 1, ..., S + T - 1};
1979
1980 Here, T is the value of the parameter "Tx-integer" broadcast on the BCCH;
1981
1982 M is the value of the parameter "max retrans" broadcast on the BCCH;
1983
1984 S is a parameter depending on the CCCH configuration and on the value
1985 of Tx-integer as defined in table 3.1/GSM 04.08.
1986
1987 Table 3.1/GSM 04.08: Values of parameter S
1988
1989 +-----------------------------------------------------+
1990 + TX-integer + non combined CCCH + combined CCH/SDCCH +
1991 +------------+-------------------+--------------------+
1992 + 3,8,14,50 + 55 + 41 +
1993 + 4,9,16 + 76 + 52 +
1994 + 5,10,20 + 109 + 58 +
1995 + 6,11,25 + 163 + 86 +
1996 + 7,12,32 + 217 + 115 +
1997 +-----------------------------------------------------+
1998
1999 */
2000 static const CONVERT_TXINTEGER convert_table[MAX_TX_INTEGER] =
2001 /*
2002 * T S non combined S combined Tx-integer
2003 */
2004 {
2005 3, 55, 41, /* 0 */
2006 4, 76, 52, /* 1 */
2007 5, 109, 58, /* 2 */
2008 6, 163, 86, /* 3 */
2009 7, 217, 115, /* 4 */
2010 8, 55, 41, /* 5 */
2011 9, 76, 52, /* 6 */
2012 10, 109, 58, /* 7 */
2013 11, 163, 86, /* 8 */
2014 12, 217, 115, /* 9 */
2015 14, 55, 41, /* 10 */
2016 16, 76, 52, /* 11 */
2017 20, 109, 58, /* 12 */
2018 25, 163, 86, /* 13 */
2019 32, 217, 115, /* 14 */
2020 50, 55, 41 /* 15 */
2021 };
2022
2023
2024 static UBYTE dat_get_delta (UBYTE i)
2025 {
2026 GET_INSTANCE_DATA;
2027
2028 USHORT index = rr_data->nc_data[SC_INDEX].rach.tx_integer;
2029 USHORT n;
2030 USHORT result=0;
2031
2032 TRACE_FUNCTION ("dat_get_delta()");
2033
2034 /*
2035 * calculate righ boarder of the interval.
2036 */
2037 TRACE_ASSERT( index < MAX_TX_INTEGER );
2038 if( index < MAX_TX_INTEGER)
2039 {
2040 n = (i EQ 0) ? att_max (convert_table[index].t, 8) - 1
2041 : convert_table[index].t - 1;
2042
2043 /*
2044 * calculate random value
2045 */
2046 result = dat_random ((USHORT)(n+1));
2047
2048 /*
2049 * If it is not the first value, add left boarder S
2050 */
2051 if (i NEQ 0)
2052 {
2053 /*
2054 * in according to GSM 4.08, section 10.5.2.11 (Control Channel Description)
2055 * and section 3.3.1.1.2 (Initiation of the immediate assignment procedure)
2056 */
2057 result +=
2058 (rr_data->nc_data[SC_INDEX].control_descr.ccch_conf EQ COMB_CCCH_COMB)
2059 ? convert_table[index].s_combined
2060 : convert_table[index].s_non_combined;
2061 }
2062 }
2063 return (UBYTE)result;
2064 }
2065
2066
2067 /*
2068 +--------------------------------------------------------------------+
2069 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2070 | STATE : code ROUTINE : dat_get_ncell_pos |
2071 +--------------------------------------------------------------------+
2072
2073 PURPOSE : for uplink SACCH RR MEASUREMENT REPORT message the
2074 position of a cell inside the neighbourcell list must
2075 be calculated. This is done by this function.
2076
2077 */
2078
2079 static UBYTE dat_get_ncell_pos (USHORT channel)
2080 {
2081 GET_INSTANCE_DATA;
2082 UBYTE i;
2083
2084 TRACE_FUNCTION ("dat_get_ncell_pos()");
2085
2086 /*
2087 * the loop counter i is the position inside the actual
2088 * neighbourcell list.
2089 */
2090 for (i=0; i<MAX_NEIGHBOURCELLS;i++)
2091 {
2092 if (channel EQ rr_data->act_ncell_list[i])
2093 {
2094 /*
2095 * channel is found, then return the position.
2096 */
2097 return i;
2098 }
2099 }
2100 return 0;
2101 }
2102
2103 /*
2104 +--------------------------------------------------------------------+
2105 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2106 | STATE : code ROUTINE : dat_eplmn_equal_req |
2107 +--------------------------------------------------------------------+
2108
2109 PURPOSE : Compare found PLMN with all PLMNs in EPLMN list
2110
2111
2112 */
2113
2114 static BOOL dat_eplmn_equal_req(const UBYTE *mcc, const UBYTE *mnc)
2115 {
2116 GET_INSTANCE_DATA;
2117 UBYTE i;
2118
2119 TRACE_FUNCTION("dat_eplmn_equal_req");
2120
2121
2122 if(rr_data->ms_data.v_eq_plmn)
2123 {
2124 for(i = 0; i < RR_EPLMNLIST_SIZE; i++)
2125 {
2126 if(!memcmp(rr_data->ms_data.eq_plmn_list[i].mcc, mcc, SIZE_MCC) &&
2127 !memcmp(rr_data->ms_data.eq_plmn_list[i].mnc, mnc, SIZE_MNC))
2128 return TRUE;
2129 }
2130 }
2131 return FALSE;
2132 }
2133
2134 /*
2135 +--------------------------------------------------------------------+
2136 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2137 | STATE : code ROUTINE : dat_plmn_equal_req |
2138 +--------------------------------------------------------------------+
2139
2140 PURPOSE : The function checks whether the given mobile country code
2141 and the given mobile network code describes the requested
2142 PLMN, eg. the HPLMN distilled from the IMSI.
2143 This is not exactly the algorithm as shown for HPLMN
2144 matching as shown in 03.22 Normative Annex A, this version
2145 here is more universal.
2146
2147 */
2148
2149 GLOBAL BOOL dat_plmn_equal_req (const UBYTE *bcch_mcc, const UBYTE *bcch_mnc,
2150 const UBYTE *mm_mcc, const UBYTE *mm_mnc)
2151 {
2152 GET_INSTANCE_DATA;
2153 if(((rr_data->ms_data.operation_mode >> SHIFT_FOR_SEARCH_OFFSET) & 1) EQ M_AUTO &&
2154 rr_data->ms_data.req_mm_service NEQ FUNC_LIM_SERV_ST_SRCH)
2155 {
2156 /* Check for equivalent EPLMNs */
2157 if(dat_eplmn_equal_req(bcch_mcc, bcch_mnc))
2158 return TRUE;
2159 }
2160
2161 /* Check MCC */
2162 if (memcmp (mm_mcc, bcch_mcc, SIZE_MCC) NEQ 0)
2163 return FALSE;
2164
2165 /* Check first 2 MNC digits */
2166 if (memcmp (mm_mnc, bcch_mnc, 2) NEQ 0)
2167 return FALSE;
2168
2169 /* Check for full match */
2170 if (mm_mnc[2] EQ bcch_mnc[2])
2171 return TRUE;
2172
2173 /* The 3rd digit of the MNC differs */
2174 if ((bcch_mcc[0] EQ 3) AND
2175 (bcch_mcc[1] EQ 1) AND
2176 INRANGE(0,bcch_mcc[2],6))
2177 {
2178 /*
2179 * The MCC is in the range 310..316, this means North America.
2180 * The zero suffix rule applies.
2181 */
2182 return (((mm_mnc[2] EQ 0xf) AND (bcch_mnc[2] EQ 0x0)) OR
2183 ((mm_mnc[2] EQ 0x0) AND (bcch_mnc[2] EQ 0xf)));
2184 }
2185 return (bcch_mnc[2] EQ 0xf);
2186 }
2187
2188 GLOBAL BOOL dat_hplmn (const UBYTE *mcc, const UBYTE *mnc)
2189 {
2190 GET_INSTANCE_DATA;
2191 TRACE_FUNCTION ("dat_hplmn()");
2192
2193 /*
2194 * only if a SIM is inserted and an IMSI is available
2195 */
2196 if (!rr_data->ms_data.imsi_available)
2197 return FALSE;
2198
2199 if ((rr_data->ms_data.ahplmn.v_plmn EQ V_PLMN_PRES) AND
2200 (rr_data->ms_data.req_mm_service EQ FUNC_PLMN_SRCH))
2201 {
2202 /*
2203 * If AHPLMN is available
2204 * do not compare the mcc, mnc from IMSI for the HPLMN
2205 * use the AHPLMN
2206 */
2207 return dat_plmn_equal_req (mcc, mnc,
2208 rr_data->ms_data.ahplmn.mcc,
2209 rr_data->ms_data.ahplmn.mnc);
2210 }
2211
2212 return dat_plmn_equal_req (mcc, mnc,
2213 &rr_data->ms_data.imsi.ident_dig[0],
2214 &rr_data->ms_data.imsi.ident_dig[3]);
2215
2216 }
2217
2218
2219 /*
2220 +--------------------------------------------------------------------+
2221 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2222 | STATE : code ROUTINE : dat_hplmn_country |
2223 +--------------------------------------------------------------------+
2224
2225 PURPOSE : The function checks whether the given mobile country
2226 code is equal to the first three digits of the IMSI.
2227 The first three digits of the IMSI are equal to the
2228 mobile country code of the HPLMN.
2229
2230 */
2231
2232 static BOOL dat_hplmn_country (const UBYTE *mcc)
2233 {
2234 GET_INSTANCE_DATA;
2235 SHORT i;
2236 UBYTE mcc_digit;
2237
2238 TRACE_FUNCTION ("dat_hplmn_country()");
2239
2240 /*
2241 * Only if an IMSI is available
2242 */
2243 if (rr_data->ms_data.imsi_available)
2244 {
2245 /* EM_HPLMN_SEARCH_STARTED; - Not supported*/
2246 for (i = 0; i < SIZE_MCC; i++)
2247 {
2248
2249 if((rr_data->ms_data.ahplmn.v_plmn EQ V_PLMN_PRES) AND
2250 (rr_data->ms_data.req_mm_service EQ FUNC_PLMN_SRCH))
2251 {
2252 /*
2253 * If AHPLMN is available
2254 * do not compare the mcc from IMSI for the HPLMN
2255 * use the MM req HPLMN
2256 */
2257 mcc_digit = rr_data->ms_data.ahplmn.mcc[i];
2258 }
2259 else
2260 {
2261 mcc_digit = rr_data->ms_data.imsi.ident_dig[i];
2262 }
2263
2264 /*
2265 * if one of the three first digits of the IMSI is unequal to
2266 * the mobile country code, it is not the HPLMN country.
2267 */
2268 if (mcc[i] NEQ mcc_digit)
2269 {
2270 return FALSE;
2271 }
2272 }
2273
2274 EM_HPLMN_SEARCH_PASSED;
2275
2276 return TRUE;
2277 }
2278 return FALSE;
2279 }
2280
2281 /*
2282 +--------------------------------------------------------------------+
2283 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2284 | STATE : code ROUTINE : dat_imsi_mod_1000 |
2285 +--------------------------------------------------------------------+
2286
2287 PURPOSE : Calculate IMSI modulo 1000. That means take the last three
2288 digits of the IMSI. The length of the IMSI (and so the number
2289 of digits overall) is variable.
2290
2291 This value is needed for calculation of the paging group.
2292
2293 */
2294
2295 static SHORT dat_imsi_mod_1000 (void)
2296 {
2297 GET_INSTANCE_DATA;
2298 SHORT i = 0;
2299 SHORT ret = 0;
2300 int n;
2301
2302 TRACE_FUNCTION ("dat_imsi_mod_1000()");
2303
2304 while (rr_data->ms_data.imsi.ident_dig[i] < 0x0A)
2305 i++;
2306
2307 if (i)
2308 {
2309 for (n = MAXIMUM (i-3, 0); n <= MAXIMUM (i-1, 0); n++)
2310 {
2311 ret = ret * 10 + rr_data->ms_data.imsi.ident_dig[n];
2312 }
2313 }
2314 return ret;
2315
2316 }
2317
2318 /*
2319 +--------------------------------------------------------------------+
2320 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2321 | STATE : code ROUTINE : dat_no_of_paging_blocks |
2322 +--------------------------------------------------------------------+
2323
2324 PURPOSE : The function calculates the number of paging blocks.
2325
2326 For 51-Multiframe the following condition exists:
2327
2328 A non-combined CCCH configuration has 9 CCCH Blocks.
2329 A combined CCCH configuration has 3 CCCH Blocks.
2330
2331 From this n CCCH Blocks BS_AG_BLKS_RES blocks are reserved
2332 for AGCH (access grant channels for immediate assignment).
2333 The rest is reserved for PCH (Paging Channel).
2334
2335 This number must be multiplied by the BS_PA_MFRMS parameter
2336 (internally stored is the air-interface coding, add 2 for
2337 the real value).
2338
2339 The BS_PA_MFRMS parameter defines the number of 51-Multiframes
2340 until the paging blocks are repeated.
2341
2342 */
2343
2344 static SHORT dat_no_of_paging_blocks (UBYTE index)
2345 {
2346 GET_INSTANCE_DATA;
2347 TRACE_FUNCTION ("dat_no_of_paging_blocks()");
2348
2349 /* in according to GSM 4.08 section 10.5.2.11, table 10.5.33 */
2350 if (rr_data->nc_data[index].control_descr.ccch_conf EQ COMB_CCCH_COMB)
2351 {
2352 /*
2353 * combined CCCH,
2354 *
2355 * number of paging blocks = (3 - BS_AG_BLKS_RES) * BS_PA_MFRMS
2356 *
2357 * Maximum function only for security reasons, BCCH coding range is 0..7,
2358 * but allowed is only 0..2.
2359 */
2360 return ((att_max (1, (UBYTE)(3 - rr_data->nc_data[index].control_descr.
2361 bs_ag_blks_res))) *
2362 ((UBYTE)(2 + rr_data->nc_data[index].control_descr.bs_pa_mfrms)));
2363 }
2364 else
2365 {
2366 /*
2367 * non-combined CCCH,
2368 *
2369 * number of paging blocks = (9 - BS_AG_BLKS_RES) * BS_PA_MFRMS
2370 */
2371 return ((9 - rr_data->nc_data[index].control_descr.bs_ag_blks_res) *
2372 (2 + rr_data->nc_data[index].control_descr.bs_pa_mfrms));
2373 }
2374 }
2375
2376 /*
2377 +--------------------------------------------------------------------+
2378 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2379 | STATE : code ROUTINE : dat_owner_of_auth_0_to_9 |
2380 +--------------------------------------------------------------------+
2381
2382 PURPOSE : It is checked whether the MS is owner of at least one
2383 of the normal classes 0 to 9. The coding on the SIM card
2384 is in opposite to the coding on the BCCH.
2385
2386 */
2387
2388 static BOOL dat_owner_of_auth_0_to_9 (void)
2389 {
2390 GET_INSTANCE_DATA;
2391 BOOL result = FALSE;
2392
2393 /*
2394 * get bits 0 to 9 from SIM card and BCCH
2395 */
2396 USHORT ms_classes = rr_data->ms_data.access_classes & 0x3FF;
2397 USHORT plmn_classes = rr_data->nc_data[SC_INDEX].rach.ac & 0x3FF;
2398
2399 TRACE_FUNCTION ("dat_owner_of_auth_0_to_9()");
2400
2401 /*
2402 * check only if IMSI is available
2403 * else no valid classes of the SIM card available
2404 */
2405 if (rr_data->ms_data.imsi_available)
2406 {
2407 /*
2408 * check classes
2409 */
2410 if ((ms_classes & (~plmn_classes)) NEQ 0)
2411 result = TRUE;
2412 }
2413 return result;
2414 }
2415
2416 /*
2417 +--------------------------------------------------------------------+
2418 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2419 | STATE : code ROUTINE : dat_owner_of_auth_11_to_15 |
2420 +--------------------------------------------------------------------+
2421
2422 PURPOSE : It is checked whether the MS is owner of at least one
2423 of the normal classes 11 to 15. The coding on the SIM card
2424 is in opposite to the coding on the BCCH.
2425
2426 */
2427
2428 static BOOL dat_owner_of_auth_11_to_15 (void)
2429 {
2430 GET_INSTANCE_DATA;
2431 BOOL result = FALSE;
2432
2433 /*
2434 * get bits 11 to 15 from the SIM card and the BCCH.
2435 */
2436 USHORT ms_classes = rr_data->ms_data.access_classes & 0xF800;
2437 USHORT plmn_classes = rr_data->nc_data[SC_INDEX].rach.ac & 0xF800;
2438
2439 TRACE_FUNCTION ("dat_owner_of_auth_11_to_15()");
2440
2441 /*
2442 * check only if IMSI is available
2443 * else no valid classes of the SIM card available
2444 */
2445 if (rr_data->ms_data.imsi_available)
2446 {
2447 if (! dat_hplmn (rr_data->nc_data[SC_INDEX].lai.mcc,
2448 rr_data->nc_data[SC_INDEX].lai.mnc))
2449 {
2450 /*
2451 * ignore bit 11 and 15 if not in the HPLMN
2452 */
2453 ms_classes = ms_classes & 0x7000;
2454 plmn_classes = plmn_classes & 0x7000;
2455 }
2456
2457 if (! dat_hplmn_country (rr_data->nc_data[SC_INDEX].lai.mcc))
2458 {
2459 /*
2460 * ignore bit 12 to 14 if not in the HPLMN country
2461 */
2462 ms_classes = ms_classes & 0x8F00;
2463 plmn_classes = plmn_classes & 0x8F00;
2464 }
2465
2466 /*
2467 * check classes
2468 */
2469 if ((ms_classes & (~plmn_classes)) NEQ 0)
2470 result = TRUE;
2471 }
2472
2473 return result;
2474 }
2475
2476
2477 /*
2478 +--------------------------------------------------------------------+
2479 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2480 | STATE : code ROUTINE : dat_random |
2481 +--------------------------------------------------------------------+
2482
2483 PURPOSE : The function calculates a random value in the range 0..n-1.
2484 The algorithm uses the system time as a base for the random
2485 value calculation.
2486
2487 */
2488
2489 GLOBAL USHORT dat_random (USHORT n)
2490 {
2491 GET_INSTANCE_DATA;
2492 T_TIME time_val;
2493
2494 static USHORT random_value = 0;
2495
2496 TRACE_FUNCTION ("dat_random()");
2497
2498 /*
2499 * for module testing the random component can be switched off
2500 */
2501 if (rr_data->dyn_config.no_sys_time)
2502 time_val = 0;
2503 else
2504 vsi_t_time (VSI_CALLER &time_val);
2505
2506 /*
2507 * increment the base of the calculation by the system time.
2508 */
2509 random_value += (USHORT) time_val;
2510
2511 /*
2512 * calculate the value in the range 0...n.1
2513 */
2514 return (random_value % n);
2515 }
2516
2517 /*
2518 +--------------------------------------------------------------------+
2519 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2520 | STATE : code ROUTINE : dat_release_connection |
2521 +--------------------------------------------------------------------+
2522
2523 PURPOSE : The function is called after receiving MPH_STOP_DEDICATED_CNF
2524 from L1 following disconnection of L2 connection.
2525
2526 */
2527
2528 GLOBAL void dat_release_connection (void)
2529 {
2530 GET_INSTANCE_DATA;
2531 TRACE_FUNCTION ("dat_release_connection()");
2532
2533 switch (GET_STATE (STATE_DAT))
2534 {
2535 case DAT_IMM_ASS:
2536 /*
2537 * Layer 2 disconnection is initiated by MM through RR_ABORT_REQ
2538 */
2539 if(rr_data->rel_cause EQ RRCS_MM_ABORTED)
2540 {
2541 dat_rr_release_ind(RRCS_MM_ABORTED, SAPI_0);
2542 }
2543 break;
2544
2545 case DAT_IMM_ASS_1:
2546 /*
2547 * Layer 2 disconnection is initiated by MM through RR_ABORT_REQ
2548 */
2549 if(rr_data->rel_cause EQ RRCS_MM_ABORTED)
2550 {
2551 dat_rr_release_ind(RRCS_MM_ABORTED, SAPI_0);
2552 break;
2553 }
2554 /*
2555 *DL establishment failure during immediate assignment
2556 */
2557 switch (rr_data->ms_data.establish_cause)
2558 {
2559 #ifdef GPRS
2560 case ESTCS_GPRS_PAGING:
2561 dat_stop_dcch_ind ((UBYTE)rr_data->dcch_stop_cause);
2562 break;
2563 case ESTCS_PAGING:
2564 if(!rr_data->repeat_est)
2565 dat_rr_release_ind(rr_data->rel_cause, SAPI_0);
2566 #else
2567 case ESTCS_PAGING:
2568 #endif
2569 break;
2570 default:
2571 dat_rr_release_ind(rr_data->rel_cause, SAPI_0);
2572 break;
2573 }
2574 break;
2575
2576 default:
2577 dat_rr_release_ind (rr_data->rel_cause, SAPI_0);
2578 break;
2579 }
2580
2581 /*
2582 * clear state of data transfer process and start
2583 * cell reselection to come back to idle mode.
2584 * Inform GRR, and wait for CR_RSP
2585 */
2586 att_leave_dedicated();
2587 }
2588
2589 /*
2590 +--------------------------------------------------------------------+
2591 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2592 | STATE : code ROUTINE : dat_send_random_bursts |
2593 +--------------------------------------------------------------------+
2594
2595 PURPOSE : The function configures layer 1 to send 2 to 8 random
2596 bursts during connection establishment
2597
2598 */
2599
2600 /*
2601 * conversion of the air-interface coding (0..3) for the
2602 * number of random bursts to be send
2603 */
2604 static const UBYTE max_attempt[MAX_RACH_RETRANS_VAL] = { 2, 3, 5, MAX_RACH_REQ};
2605
2606 static void dat_send_random_bursts (void)
2607 {
2608 GET_INSTANCE_DATA;
2609 UBYTE i;
2610 UBYTE background;
2611 UBYTE bits;
2612
2613 PALLOC (mph_random_access_req, MPH_RANDOM_ACCESS_REQ);
2614
2615 TRACE_FUNCTION ("dat_send_random_bursts()");
2616
2617 /*
2618 * calculate the background and the number of bits for the
2619 * random part depending on the establishment cause.
2620 */
2621 dat_get_background_and_bits (&background, &bits);
2622 TRACE_EVENT("reset rej_rec");
2623 rr_data->imm_ass_rej_rec = FALSE;
2624 /*
2625 * initialize the primitive and parameter for calculation
2626 */
2627 rr_data->ms_data.access_counter = 0;
2628 TRACE_ASSERT( rr_data->nc_data[SC_INDEX].rach.max_retrans <
2629 MAX_RACH_RETRANS_VAL );
2630 rr_data->ms_data.max_attempt = max_attempt[rr_data->nc_data
2631 [SC_INDEX].rach.max_retrans];
2632 memset (&mph_random_access_req->send_mode, 0, sizeof (T_send_mode));
2633 mph_random_access_req->send_mode.no = rr_data->ms_data.max_attempt;
2634
2635 /*
2636 * for all random bursts
2637 */
2638 TRACE_ASSERT( rr_data->ms_data.max_attempt <= MAX_RACH_REQ );
2639 for (i = 0; i < rr_data->ms_data.max_attempt; i++)
2640 {
2641 /*
2642 * calculate time until the random burst must be send
2643 */
2644 mph_random_access_req->send_mode.delta[i] = dat_get_delta (i);
2645
2646 /*
2647 * calculate the random burst content and store it for
2648 * later comparision with the incoming immediate assignment
2649 * messages.
2650 */
2651 mph_random_access_req->send_mode.rach[i] = rr_data->used_channel_ref[i] =
2652 dat_get_burst (background, bits);
2653 /*
2654 TRACE_EVENT_P3 ("RA %u: ref=0x%02x delta=%u",
2655 i, rr_data->used_channel_ref[i],
2656 mph_random_access_req->send_mode.delta[i]);
2657 */
2658 }
2659
2660 /*
2661 * configure layer 1.
2662 */
2663 PSENDX (PL, mph_random_access_req);
2664 }
2665
2666
2667 /*
2668 +--------------------------------------------------------------------+
2669 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2670 | STATE : code ROUTINE : dat_set_last_used_channel |
2671 +--------------------------------------------------------------------+
2672
2673 PURPOSE : The last used channel during connection must be stored
2674 for the case of call re-establishment.
2675
2676 */
2677
2678 GLOBAL void dat_set_last_used_channel (T_chan_desc *chan_desc)
2679 {
2680 GET_INSTANCE_DATA;
2681 TRACE_FUNCTION ("dat_set_last_used_channel()");
2682
2683 /*
2684 * depending on the air-interface coding for the channel type
2685 */
2686 switch (chan_desc->chan_type)
2687 {
2688 case CH_TCH_F:
2689 /*
2690 * Traffic channel full rate
2691 */
2692 rr_data->ms_data.last_used_channel = TCHFCH;
2693 break;
2694
2695 case CH_TCH_H_1:
2696 case CH_TCH_H_2:
2697 /*
2698 * Traffic channel half rate
2699 */
2700 rr_data->ms_data.last_used_channel = TCHHCH;
2701 break;
2702
2703 default:
2704 /*
2705 * SDCCH
2706 */
2707 rr_data->ms_data.last_used_channel = SDCCHCH;
2708 break;
2709 }
2710 }
2711
2712 /*
2713 +--------------------------------------------------------------------+
2714 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2715 | STATE : code ROUTINE : dat_start_immediate_assign |
2716 +--------------------------------------------------------------------+
2717
2718 PURPOSE : start of the immediate assignment procedure after getting
2719 a RR_ESTABLISH_REQ from MM for a mobile originated connection
2720 or a MPH_PAGING_IND from layer 1 for a mobile terminated
2721 connection.
2722
2723 */
2724
2725 GLOBAL void dat_start_immediate_assign (USHORT cause)
2726 {
2727 GET_INSTANCE_DATA;
2728 TRACE_FUNCTION ("dat_start_immediate_assign()");
2729
2730 /*
2731 * synchronize attachment process to connection establishment state
2732 */
2733 att_dat_con_est ();
2734
2735 /*
2736 * initialize parameters for random access procedure
2737 */
2738 rr_data->ms_data.index = dat_random (32);
2739 rr_data->ms_data.establish_cause = cause;
2740 rr_data->ms_data.access_counter = 0;
2741 rr_data->ms_data.all_conf_received = FALSE;
2742
2743 /*
2744 * if connection is too short to get one measurement report from layer 1,
2745 * initialize the structure with the previous idle value
2746 */
2747 rr_data->ms_data.measurement_report.rx_lev_full = rr_data->nc_data[SC_INDEX].rxlev;
2748
2749 TRACE_EVENT_P1 ("imm ass SC=[%u]",rr_data->nc_data[SC_INDEX].arfcn);
2750
2751 /*
2752 * send random bursts and wait for immediate assignment
2753 */
2754 dat_send_random_bursts ();
2755 SET_STATE (STATE_DAT, DAT_IMM_ASS);
2756 }
2757
2758 /*
2759 +--------------------------------------------------------------------+
2760 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2761 | STATE : code ROUTINE : dat_start_sabm |
2762 +--------------------------------------------------------------------+
2763
2764 PURPOSE : After successful immediate assignment procedure the layer 1
2765 is configured on a dedicated control channel (SDCCH or FACCH).
2766 Now the layer 2 connection must be established. This is done
2767 by this function.
2768
2769 Layer 2 sends a Paging response in case of mobile terminated
2770 connection piggy-backed on the SABM.
2771
2772 In case of mobile terminated connection the piggy-backed layer 3
2773 message is coming from MM.
2774
2775 */
2776
2777 GLOBAL void dat_start_sabm (void)
2778 {
2779 GET_INSTANCE_DATA;
2780 TRACE_FUNCTION ("dat_start_sabm()");
2781
2782 if (rr_data->ms_data.establish_cause EQ ESTCS_PAGING
2783 #ifdef GPRS
2784 OR rr_data->ms_data.establish_cause EQ ESTCS_GPRS_PAGING
2785 #endif
2786 )
2787 {
2788 MCAST (pag_res, U_PAG_RES);
2789 PALLOC_MSG (establish_req, DL_ESTABLISH_REQ, U_PAG_RES);
2790
2791 dat_code_prr_channel (&establish_req->ch_type,
2792 &establish_req->sapi,
2793 rr_data->sc_data.chan_desc.chan_type);
2794 /*
2795 * if it is a mobile terminated connection,
2796 * fill the C-Structure for a PAGING RESPONSE message.
2797 */
2798 pag_res->msg_type = U_PAG_RES;
2799 pag_res->ciph_key_num.key_seq = rr_data->ms_data.cksn;
2800 pag_res->mob_class_2 = rr_data->ms_data.classmark2;
2801 pag_res->mob_class_2.rf_pow_cap = att_get_power ();
2802
2803 /*
2804 * fill mobile identity and send it to layer 2
2805 */
2806 dat_fill_mobile_identity (ESTCS_PAGING, &pag_res->mob_ident);
2807 for_dat_est_req_content (establish_req);
2808 }
2809 else
2810 {
2811 /*
2812 * mobile originated connection. set sdu with message from MM
2813 * and send it to layer 2.
2814 */
2815 PALLOC_SDU (establish_req, DL_ESTABLISH_REQ, ((MAX_L2_FRAME_SIZE * BITS_PER_BYTE) - ENCODE_OFFSET));
2816
2817 dat_code_prr_channel (&establish_req->ch_type,
2818 &establish_req->sapi,
2819 rr_data->sc_data.chan_desc.chan_type);
2820
2821 /*lint -e419 (Warning -- Apparent data overrun for function memcpy exceeds argument 1)*/
2822 establish_req->sdu.o_buf = rr_data->ms_data.l3msg.offset;
2823 establish_req->sdu.l_buf = rr_data->ms_data.l3msg.length;
2824 memcpy (establish_req->sdu.buf, rr_data->ms_data.l3msg.buffer, MAX_L2_FRAME_SIZE);
2825 /*lint +e419 (Warning -- Apparent data overrun for function memcpy exceeds argument 1)*/
2826 for_dat_est_req_not_coding (establish_req);
2827 }
2828 }
2829
2830 /*
2831 +--------------------------------------------------------------------+
2832 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2833 | STATE : code ROUTINE : dat_test_sim_available |
2834 +--------------------------------------------------------------------+
2835
2836 PURPOSE : The function checks whether a test SIM is available or not.
2837
2838 */
2839
2840 GLOBAL BOOL dat_test_sim_available (void)
2841 {
2842 GET_INSTANCE_DATA;
2843 TRACE_FUNCTION ("dat_test_sim_available()");
2844
2845 #if defined (_SIMULATION_)
2846 /*
2847 * some traces for debugging.
2848 */
2849 if (rr_data->ms_data.operation_mode & 0x80)
2850 {
2851 TRACE_FUNCTION ("Test SIM available");
2852 }
2853 else
2854 {
2855 TRACE_FUNCTION ("No Test SIM available");
2856 }
2857 #endif
2858
2859 return ((rr_data->ms_data.operation_mode >> SHIFT_FOR_SIM_TYPE) & 1);
2860 }
2861
2862
2863 /*
2864 +--------------------------------------------------------------------+
2865 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2866 | STATE : code ROUTINE : dat_check_sim_available |
2867 +--------------------------------------------------------------------+
2868
2869 PURPOSE : The function checks whether the SIM is available or not.
2870
2871 */
2872
2873 GLOBAL BOOL dat_check_sim_available (void)
2874 {
2875 GET_INSTANCE_DATA;
2876 TRACE_FUNCTION ("dat_check_sim_available()");
2877
2878 return ((rr_data->ms_data.operation_mode >> SHIFT_FOR_SIM_INSERTED) & 1);
2879 }
2880
2881
2882
2883 /*
2884 +--------------------------------------------------------------------+
2885 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2886 | STATE : code ROUTINE : dat_vsd_bit_set |
2887 +--------------------------------------------------------------------+
2888
2889 PURPOSE : To set the send state variable V(S) and the
2890 corresponding bit for SAPI 0 messages on FACCH or SDCCH.
2891 The following possibilities are available:
2892
2893 SET_ONLY: V(S) in incremented and the message bit is set
2894 RESET_ONLY: V(S) is initialized and the message bit is not set
2895 SET_AND_RESET: V(S) is initialized and the message bit is set.
2896
2897 */
2898
2899 GLOBAL void dat_vsd_bit_set (T_L3_SDU *m_buf,
2900 UBYTE action)
2901 {
2902 static UBYTE vsd = 0; /* Send state variable V(S) */
2903 UBYTE pd; /* protocol discriminator of the message */
2904 UBYTE * msp; /* pointer to message type for setting the bit */
2905 #ifdef REL99
2906 UBYTE mscr = 0; /* variable to hold msc release version*/
2907 #endif
2908 TRACE_FUNCTION ("dat_vsd_bit_set()");
2909
2910 /*
2911 * VSD shall be initialized
2912 */
2913 if (action NEQ SET_ONLY)
2914 vsd = 0;
2915
2916 /*
2917 * message bit shall be set
2918 */
2919 if (action NEQ RESET_ONLY)
2920 {
2921 /*
2922 * calculate message type pointer and protocol discriminator
2923 */
2924 TRACE_ASSERT( (m_buf->offset >> 3) < L3_SDU_BUF_SIZE );
2925 msp = &m_buf->buffer[m_buf->offset >> 3];
2926 pd = *msp++ & 0x0F;
2927 #ifdef REL99
2928 /*
2929 * Get MSCR of the serving MSC
2930 */
2931 get_msc_release_version(&mscr);
2932 TRACE_EVENT_P1("mscr (MSC release) version : 0x%X", mscr);
2933 #endif
2934 switch (pd)
2935 {
2936 case PD_SMS:
2937 /*
2938 * SMS on SDCCH is a SAPI 3 message and shall not be set.
2939 */
2940 break;
2941 case PD_CC:
2942 case PD_SS:
2943 case PD_MM:
2944 #ifdef REL99
2945 if (mscr EQ MSCR_99)
2946 {
2947 /* for MSC release R99 or above modulo 4 will be done.
2948 * SAPI 0 message: set bit 7th and 8th of MSG Type IE
2949 * and increment V(S) modulo 4.
2950 */
2951 *msp |= (vsd++ << 6);
2952 vsd = vsd & 0x03;
2953 }
2954 else
2955 #endif
2956 {
2957 /* for MSC release R98 or old modulo 2 will be done.
2958 * SAPI 0 message: set bit if vsd is 1, else no effect
2959 * and increment V(S) modulo 2.
2960 */
2961 *msp |= (vsd++ << 6);
2962 vsd &= 1;
2963 }
2964 }
2965 }
2966 }
2967
2968 /*
2969 +---------------------------------------------------------------------+
2970 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2971 | STATE : code ROUTINE : dat_begin_start_immediate_assign |
2972 +---------------------------------------------------------------------+
2973
2974 PURPOSE : initiate immediate assignment procedure by sending
2975 channel request
2976
2977 */
2978 GLOBAL void dat_begin_start_immediate_assign (UBYTE id_type, UBYTE chan_need)
2979 {
2980 GET_INSTANCE_DATA;
2981 TRACE_FUNCTION ("dat_begin_start_immediate_assign()");
2982
2983 rr_data->page_identity_type = id_type;
2984 rr_data->ms_data.channel_needed = chan_need;
2985 dat_vsd_bit_set (&rr_data->ms_data.l3msg, RESET_ONLY);
2986 rr_data->sc_data.first_attempt = TRUE;
2987 rr_data->repeat_est = FALSE;
2988 dat_start_immediate_assign (ESTCS_PAGING);
2989 }
2990
2991 /*
2992 +---------------------------------------------------------------------+
2993 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
2994 | STATE : code ROUTINE : dat_rr_release_ind |
2995 +---------------------------------------------------------------------+
2996
2997 PURPOSE : send RR_RELEASE_IND to MM
2998
2999 */
3000 GLOBAL void dat_rr_release_ind (USHORT relcs, UBYTE sapi)
3001 {
3002 PALLOC (rr_release_ind, RR_RELEASE_IND);
3003
3004 rr_release_ind->cause = relcs;
3005 rr_release_ind->sapi = sapi;
3006 #ifdef GPRS
3007 dat_set_gprs_resump(rr_release_ind);
3008 #endif
3009
3010 PSENDX (MM, rr_release_ind);
3011 }
3012
3013 /*
3014 +--------------------------------------------------------------------+
3015 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
3016 | STATE : code ROUTINE : dat_send_release_ind |
3017 +--------------------------------------------------------------------+
3018
3019 PURPOSE : Send RR_REELASE_IND to MM during the Access Procedure
3020
3021 */
3022
3023 GLOBAL void dat_send_release_ind (USHORT cause)
3024 {
3025 GET_INSTANCE_DATA;
3026 TRACE_FUNCTION ("dat_send_release_ind()");
3027
3028 switch (rr_data->ms_data.establish_cause)
3029 {
3030 #ifdef GPRS
3031 case ESTCS_GPRS_1P:
3032 case ESTCS_GPRS_SB:
3033 case ESTCS_GPRS_PAGING:
3034 SET_STATE(STATE_GPRS, GPRS_PIM_BCCH);
3035 break;
3036 case ESTCS_PAGING:
3037 dat_rr_release_ind(RRCS_INT_NOT_PRESENT, SAPI_0);
3038 /*
3039 * After sending a release_ind RR shall consider that GRR leaves SUSPENDED state
3040 */
3041 if(GPRS_SUSPENDED_BCCH EQ GET_STATE(STATE_GPRS))
3042 {
3043 SET_STATE(STATE_GPRS,GPRS_PIM_BCCH);
3044 }
3045 else if(GPRS_SUSPENDED_PBCCH EQ GET_STATE(STATE_GPRS))
3046 {
3047 SET_STATE(STATE_GPRS,GPRS_PIM_PBCCH);
3048 }
3049 #else
3050 case ESTCS_PAGING:
3051 #endif
3052 break;
3053
3054 default:
3055 #ifdef GPRS
3056 /*
3057 * After sending a release_ind RR shall consider that GRR leaves SUSPENDED state
3058 */
3059 if(GPRS_SUSPENDED_BCCH EQ GET_STATE(STATE_GPRS))
3060 {
3061 SET_STATE(STATE_GPRS,GPRS_PIM_BCCH);
3062 }
3063 else if(GPRS_SUSPENDED_PBCCH EQ GET_STATE(STATE_GPRS))
3064 {
3065 SET_STATE(STATE_GPRS,GPRS_PIM_PBCCH);
3066 }
3067 #endif
3068 if ( cause EQ RRCS_RND_ACC_FAIL )
3069 {
3070 if (! IS_TIMER_ACTIVE (T3122))
3071 {
3072 dat_rr_release_ind(RRCS_RND_ACC_FAIL, SAPI_0);
3073 }
3074 else
3075 {
3076 dat_rr_release_ind(RRCS_RND_ACC_DELAY, SAPI_0);
3077 }
3078 }
3079 else
3080 {
3081 dat_rr_release_ind(cause, SAPI_0);
3082 }
3083 break;
3084 }
3085 }
3086
3087 /*
3088 +---------------------------------------------------------------------+
3089 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
3090 | STATE : code ROUTINE : dat_send_assign_fail_msg |
3091 +---------------------------------------------------------------------+
3092
3093 PURPOSE : send ASSIGNMENT FAILURE to network.
3094
3095 */
3096 void dat_send_assign_fail_msg(UBYTE cause)
3097 {
3098 GET_INSTANCE_DATA;
3099 MCAST (assign_fail, U_ASSIGN_FAIL);
3100 PALLOC_MSG (dl_reconnect_req, DL_RECONNECT_REQ, U_ASSIGN_FAIL);
3101 assign_fail->msg_type = U_ASSIGN_FAIL;
3102 assign_fail->rr_cause = cause;
3103 dat_code_prr_channel (&dl_reconnect_req->ch_type,
3104 &dl_reconnect_req->sapi,
3105 rr_data->sc_data.chan_desc.chan_type);
3106
3107 /*
3108 * start reconnection in layer 2.
3109 */
3110 for_dat_reconnect_req (dl_reconnect_req);
3111 }
3112
3113 /*
3114 +---------------------------------------------------------------------+
3115 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
3116 | STATE : code ROUTINE : dat_send_rr_status_msg |
3117 +---------------------------------------------------------------------+
3118
3119 PURPOSE : send RR STATUS to network
3120
3121 */
3122 void dat_send_rr_status_msg(UBYTE cause)
3123 {
3124 GET_INSTANCE_DATA;
3125
3126 MCAST (rr_status, B_RR_STATUS);
3127 PALLOC_MSG (dl_data_req, DL_DATA_REQ, B_RR_STATUS);
3128
3129 /*
3130 * set channel type and SAPI
3131 */
3132 dat_code_prr_channel (&dl_data_req->ch_type,
3133 &dl_data_req->sapi,
3134 rr_data->sc_data.chan_desc.chan_type);
3135
3136 rr_status->msg_type = B_RR_STATUS;
3137 rr_status->rr_cause = cause;
3138
3139 EM_RR_STATUS_SEND;
3140
3141 for_dat_data_req (dl_data_req);
3142 }
3143
3144 /*
3145 +---------------------------------------------------------------------+
3146 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
3147 | STATE : code ROUTINE : dat_send_handov_fail_msg |
3148 +---------------------------------------------------------------------+
3149
3150 PURPOSE : send HANDOVER FAILURE to network
3151
3152 */
3153 void dat_send_handov_fail_msg(UBYTE cause)
3154 {
3155 GET_INSTANCE_DATA;
3156 MCAST (handov_fail, U_HANDOV_FAIL);
3157 PALLOC_MSG (dl_reconnect_req, DL_RECONNECT_REQ, U_HANDOV_FAIL);
3158
3159 /*
3160 * set channel type and sapi for the reconnection.
3161 */
3162 dat_code_prr_channel (&dl_reconnect_req->ch_type,
3163 &dl_reconnect_req->sapi,
3164 rr_data->sc_data.chan_desc.chan_type);
3165
3166 handov_fail->rr_cause = cause;
3167 handov_fail->msg_type = U_HANDOV_FAIL;
3168
3169 /*
3170 * reconnect layer 2 link.
3171 */
3172 for_dat_reconnect_req (dl_reconnect_req);
3173 }
3174
3175 #if defined (REL99) && defined (TI_PS_FF_EMR)
3176 /*
3177 +---------------------------------------------------------------------+
3178 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
3179 | STATE : code ROUTINE : dat_update_emr_data |
3180 +---------------------------------------------------------------------+
3181
3182 PURPOSE : Updates the enhanced measurement parameters, other than
3183 BSIC and reporting priority.
3184
3185 */
3186 GLOBAL void dat_update_emr_rep_para(T_emp *p_em, T_enh_para_struct *p_enh)
3187 {
3188 p_enh->scale_order = p_em->scale_ord;
3189 if (p_em->v_serv_band_rep EQ TRUE)
3190 p_enh->servingband_rep = p_em->serv_band_rep;
3191 if (p_em->v_mr EQ TRUE )
3192 p_enh->multiband_rep = p_em->mr;
3193
3194 /* Update reporting thresholds and reporting offsets*/
3195 if (p_em->v_report_900 EQ TRUE)
3196 {
3197 p_enh->enh_rep_data[0].rep_offset = p_em->report_900.rep_offset_900;
3198 p_enh->enh_rep_data[0].rep_offset = p_em->report_900.th_rep_900;
3199 }
3200 if (p_em->v_report_1800 EQ TRUE)
3201 {
3202 p_enh->enh_rep_data[1].rep_offset = p_em->report_1800.rep_offset_1800;
3203 p_enh->enh_rep_data[1].rep_offset = p_em->report_1800.th_rep_1800;
3204 }
3205 if (p_em->v_report_400 EQ TRUE)
3206 {
3207 p_enh->enh_rep_data[2].rep_offset = p_em->report_400.rep_offset_400;
3208 p_enh->enh_rep_data[2].rep_offset = p_em->report_400.th_rep_400;
3209 }
3210 if (p_em->v_report_1900 EQ TRUE)
3211 {
3212 p_enh->enh_rep_data[3].rep_offset = p_em->report_1900.rep_offset_1900;
3213 p_enh->enh_rep_data[3].rep_offset = p_em->report_1900.th_rep_1900;
3214 }
3215 if (p_em->v_report_850 EQ TRUE)
3216 {
3217 p_enh->enh_rep_data[4].rep_offset = p_em->report_850.rep_offset_850;
3218 p_enh->enh_rep_data[4].rep_offset = p_em->report_850.th_rep_850;
3219 }
3220 return;
3221 }
3222
3223 /*
3224 +---------------------------------------------------------------------+
3225 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
3226 | STATE : code ROUTINE : dat_code_enh_measure_report |
3227 +---------------------------------------------------------------------+
3228
3229 PURPOSE : Forms enhanced measurement report and sends it to DL as a
3230 message with short PD.
3231 */
3232 GLOBAL void dat_code_enh_measure_report(T_MPH_MEASUREMENT_IND *report)
3233 {
3234 GET_INSTANCE_DATA;
3235 UBYTE size_avail = MSG_SIZE_EMR - MAND_SIZE_EMR;
3236 MCAST (meas_emr, U_EMR);
3237 PALLOC_MSG (dl_data, DL_SHORT_UNITDATA_REQ, U_EMR);
3238
3239 TRACE_FUNCTION ("dat_code_enh_measure_report()");
3240 memset (&dl_data->sdu.buf[0], 0, dl_data->sdu.o_buf / BITS_PER_BYTE);
3241 /* initialize C-structure for the Uplink message */
3242 memset (meas_emr, 0, sizeof (T_U_EMR));
3243 meas_emr->msg_type = U_EMR;
3244 meas_emr->sl2h = SL2H_0;
3245
3246 if (report->valid EQ TRUE)
3247 {
3248 T_enh_para_struct *src = &rr_data->sc_data.emr_data_current.enh_para;
3249
3250 /* Fill the non-measurement paramaters */
3251 meas_emr->ba_ind = rr_data->sc_data.ba_index;
3252 meas_emr->scale = report->scale_used;
3253 /* Now fill serving cell data */
3254 if (report->rxlev_val NEQ 0)
3255 {
3256 meas_emr->v_scdata = TRUE;
3257 meas_emr->scdata.rxlev = report->rxlev_val;
3258 meas_emr->scdata.rxqual_full = report->rx_qual_full;
3259 meas_emr->scdata.mean_bep = report->mean_bep;
3260 meas_emr->scdata.cv_bep = report->cv_bep;
3261 meas_emr->scdata.nr_rcvd_bl = report->nbr_rcvd_blks;
3262 meas_emr->scdata.dtx_used = report->dtx;
3263 size_avail -= SC_INFO_SIZE_EMR;
3264 }
3265
3266 /* Fill neighbour cell measurements */
3267 if (report->ncells.no_of_ncells > 0)
3268 {
3269 UBYTE i;
3270 UBYTE j;
3271 UBYTE highest_index = 0;
3272 UBYTE index_0 = 1;/*To decrement size by 1 when index is 0*/
3273 ULONG bit_map=0;
3274
3275
3276 meas_emr->em_rep.c_rep_q_arr = meas_emr->c_i_bsic_i = 0;
3277 for (i =0; i < report->ncells.no_of_ncells; i++ )
3278 {
3279 j = report->nc_index[i];
3280 /*Decide whether it is a valid BSIC cell or not*/
3281 if ( j NEQ NOT_PRESENT_8BIT )
3282 {
3283 /*This is an valid BSIC cell*/
3284 /*Check the priority of the cell*/
3285 if ( (src->rep_rate EQ REDUCED_REP_RATE) AND
3286 (src->enh_cell_list[j].rep_priority EQ REP_PRIOR_NORM ))
3287 {
3288 /*Proceed further only if the cell has not been included-
3289 in any report till now or if it's the time to include this
3290 cell in the report*/
3291 if ( (rr_data->sc_data.rep_count[j] NEQ rr_data->sc_data.emr_count ) AND
3292 (rr_data->sc_data.rep_count[j] NEQ NOT_PRESENT_8BIT ) )
3293 {
3294 bit_map |= (1<<i);
3295 continue; /* Include this cell at the end only if size is available*/
3296 }
3297 }
3298 meas_emr->em_rep.rep_q_arr[j].rep_q = report->ncells.rx_lev[i];
3299
3300 if ( j > highest_index )
3301 {
3302 /*When the place where the RXLEV has to be filled requires
3303 additional bits in bit map, then we have to account for
3304 these single bits and additional 6 bits for RXLEV*/
3305 if (size_avail >= (j - highest_index)+6 + index_0 )
3306 {
3307 /*This means we require atleast j-highest_index+6 bits in bit map to
3308 include this rxlev*/
3309 /* 6 bits for RXLEV itself*/
3310 size_avail = size_avail- (j-highest_index+6+index_0) ;
3311 highest_index = j;
3312 meas_emr->em_rep.c_rep_q_arr = j+1; /*counter is index+1*/
3313 index_0 = 0;
3314 meas_emr->em_rep.rep_q_arr[j].v_rep_q = TRUE;
3315 rr_data->sc_data.rep_count[j] = rr_data->sc_data.emr_count;
3316 }
3317 }
3318 else if (size_avail >= 6 + index_0)
3319 {
3320 size_avail -= (6+index_0); /* size for bit map is already accounted for*/
3321 meas_emr->em_rep.c_rep_q_arr = highest_index +1;
3322 index_0 = 0;
3323 meas_emr->em_rep.rep_q_arr[j].v_rep_q = TRUE;
3324 rr_data->sc_data.rep_count[j] = rr_data->sc_data.emr_count;
3325 }
3326 } /* if j NEQ NOT_PRESENT_8BIT */
3327 else
3328 {
3329 /*This is a Invalid BSIC cell*/
3330 /*fill in invalid BSIC list since cell is not present in the neighbour cell
3331 list. Here the index that needs to be filled is index of the ARFCN in BA(list)*/
3332 if ( size_avail > NC_INVBSIC_EMR )
3333 {
3334 meas_emr->i_bsic_i[meas_emr->c_i_bsic_i].ba_start_bsic =
3335 dat_get_ncell_pos (report->ncells.arfcn[i]);
3336 meas_emr->i_bsic_i[meas_emr->c_i_bsic_i].bsic = report->ncells.bsic[i] ;
3337 meas_emr->i_bsic_i[meas_emr->c_i_bsic_i++].rxlev = report->ncells.rx_lev[i];
3338 size_avail -= NC_INVBSIC_EMR;
3339 }
3340 }
3341 if (size_avail < 6) /*no more cells can be included*/
3342 break;
3343 } /* for 'i'*/
3344
3345 /*All the low priority cells have to be filled in valid BSIC bmp reporting,
3346 if still there's size available*/
3347 i = 0;
3348 while ( (bit_map NEQ 0) AND (size_avail >= 6) )
3349 {
3350 if ( ((bit_map >> i ) & (NOT_PRESENT_32BIT)) EQ TRUE )
3351 {
3352 j = report->nc_index[i];
3353 meas_emr->em_rep.rep_q_arr[j].rep_q = report->ncells.rx_lev[i];
3354 if ( j > highest_index )
3355 {
3356 /*When the place where the RXLEV has to be filled requires
3357 additional bits in bit map, then we have to account for
3358 these single bits and additional 6 bits for RXLEV*/
3359 if (size_avail >= (j - highest_index)+6 + index_0 )
3360 {
3361 /*This means we require atleast j-highest_index+6 bits in bit map to
3362 include this rxlev*/
3363 /* 6 bits for RXLEV itself*/
3364 size_avail = size_avail- (j-highest_index+6+index_0) ;
3365 highest_index = j;
3366 meas_emr->em_rep.c_rep_q_arr = j+1; /*counter is index+1*/
3367 index_0 = 0;
3368 meas_emr->em_rep.rep_q_arr[j].v_rep_q = TRUE;
3369 rr_data->sc_data.rep_count[j] = rr_data->sc_data.emr_count;
3370 }
3371 }
3372 else if (size_avail >= 6 + index_0)
3373 {
3374 size_avail -= (6+index_0); /* size for bit map is already accounted for*/
3375 meas_emr->em_rep.c_rep_q_arr = highest_index +1;
3376 index_0 = 0;
3377 meas_emr->em_rep.rep_q_arr[j].v_rep_q = TRUE;
3378 rr_data->sc_data.rep_count[j] = rr_data->sc_data.emr_count;
3379 }
3380 else
3381 break;
3382 bit_map = bit_map & ( ~ ((ULONG)( 1 << i))); /*reset the corresponding bit in bit map*/
3383 }
3384 }/*while bit_map*/
3385 if (meas_emr->em_rep.c_rep_q_arr > 0)
3386 meas_emr->v_em_rep = TRUE;
3387 if (meas_emr->c_i_bsic_i > 0)
3388 {
3389 meas_emr->v_i_bsic_i = TRUE;
3390 meas_emr->bsic_seen = report->bsic_seen;
3391 }
3392 } /* if 'report->ncells.no_of_ncells'*/
3393
3394 #if defined (REL99) && defined (TI_PS_FF_EMR)
3395 /*Fill the report with '0's till the end of message or upto 96 cells */
3396 while ( (size_avail > 0) AND (meas_emr->em_rep.c_rep_q_arr < 96 ) )
3397 {
3398 /* There are cells in GSM NC list for which bit map has to be set to '0'
3399 earlier memset takes care of this. we just need to set the counter appropriately*/
3400 meas_emr->em_rep.c_rep_q_arr++;
3401 size_avail--;
3402 }
3403 #else
3404 if ( meas_emr->em_rep.c_rep_q_arr < src->num_valid_cells )
3405 {
3406 /* There are cells in GSM NC list for which bit map has to be set to '0'
3407 earlier memset takes care of this. we just need to set the counter appropriately*/
3408 meas_emr->em_rep.c_rep_q_arr = src->num_valid_cells;
3409 }
3410 dl_data->ccd_assist = meas_emr->em_rep.nnc = meas_emr->em_rep.c_rep_q_arr;
3411 #endif
3412 rr_data->sc_data.emr_count = (rr_data->sc_data.emr_count +1) & 0x03; /*MOD4 addition*/
3413 }
3414 else
3415 {
3416 /*
3417 * measurement report from layer 1 is invalid
3418 */
3419 TRACE_EVENT ("invalid meas_emr");
3420 /*A dummy msg with all options as FALSE will go in this case, to network.
3421 may be useful to maintain periodicity*/
3422 }
3423 /* Send the message to DL */
3424
3425 for_dat_spd_unitdata_req(dl_data);
3426 }
3427 #endif
3428
3429 #if defined (TI_PS_FF_RTD) AND defined (REL99)
3430 /*
3431 +---------------------------------------------------------------------+
3432 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
3433 | STATE : code ROUTINE : dat_update_rtd_data |
3434 +---------------------------------------------------------------------+
3435
3436 PURPOSE : Updates the real time difference parameters received on MEAS_INFO message.
3437 */
3438 GLOBAL void dat_update_rtd_data(T_D_MEAS_INF *p_mi,T_rr_enh_para *p_temp)
3439 {
3440 T_rtdd *rtdd_struct= &p_mi->rtdd;
3441 dat_update_common_rtd_struct(rtdd_struct,p_temp);
3442
3443 } /* end dat_update_rtd_data()*/
3444
3445
3446 /*
3447 +---------------------------------------------------------------------+
3448 | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
3449 | STATE : code ROUTINE : dat_update_common_rtd_struct |
3450 +---------------------------------------------------------------------+
3451
3452 PURPOSE : Common function called from for_store_rtd_data() to store
3453 rtd parameters received on si2 quater message and update the same on receiving
3454 meas_info message via function dat_update_rtd_data().
3455 */
3456
3457 GLOBAL void dat_update_common_rtd_struct(T_rtdd *rtdd,T_rr_enh_para *p_temp)
3458 {
3459 UBYTE i,j,rtd_index,max_rtd_values;
3460
3461 if(rtdd->v_rtdd6 EQ TRUE)
3462 {
3463 if(rtdd->rtdd6.v_ba_start_rtd EQ TRUE)
3464 rtd_index = rtdd->rtdd6.ba_start_rtd;
3465 else
3466 rtd_index = RTD_DEFAULT_INDEX;
3467
3468 if( rtd_index < MAX_NR_OF_NCELL)
3469 {
3470 p_temp->enh_para.enh_cell_list[rtd_index].v_rtd = TRUE;
3471 max_rtd_values = rtdd->rtdd6.rtds6.c_rtd6 > MAX_NUM_OF_RTD_VALUES ?
3472 MAX_NUM_OF_RTD_VALUES : rtdd->rtdd6.rtds6.c_rtd6;
3473 for(i = 0;i < max_rtd_values;i++)
3474 p_temp->enh_para.enh_cell_list[rtd_index].rtd[i] = rtdd->rtdd6.rtds6.rtd6[i];
3475 p_temp->enh_para.enh_cell_list[rtd_index].c_rtd= max_rtd_values;
3476 } /*if*/
3477
3478 for(j = 0;j < rtdd->rtdd6.c_rtds6_add;j++)
3479 {
3480 rtd_index++;
3481 if( rtd_index < MAX_NR_OF_NCELL)
3482 {
3483 p_temp->enh_para.enh_cell_list[rtd_index].v_rtd = TRUE;
3484 max_rtd_values = rtdd->rtdd6.rtds6_add[j].c_rtd6 > MAX_NUM_OF_RTD_VALUES ?
3485 MAX_NUM_OF_RTD_VALUES : rtdd->rtdd6.rtds6_add[j].c_rtd6;
3486 for(i = 0;i < max_rtd_values;i++)
3487 p_temp->enh_para.enh_cell_list[rtd_index].rtd[i] = rtdd->rtdd6.rtds6_add[j].rtd6[i];
3488 p_temp->enh_para.enh_cell_list[rtd_index].c_rtd= max_rtd_values;
3489 } /*if*/
3490 } /*for*/
3491 } /*if*/
3492 if(rtdd->v_rtdd12 EQ TRUE)
3493 {
3494 if(rtdd->rtdd12.v_ba_start_rtd EQ TRUE)
3495 rtd_index = rtdd->rtdd12.ba_start_rtd;
3496 else
3497 rtd_index = RTD_DEFAULT_INDEX;
3498
3499 if( rtd_index < MAX_NR_OF_NCELL)
3500 {
3501 p_temp->enh_para.enh_cell_list[rtd_index].v_rtd = TRUE;
3502 max_rtd_values = rtdd->rtdd12.rtds12.c_rtd12 > MAX_NUM_OF_RTD_VALUES ?
3503 MAX_NUM_OF_RTD_VALUES: rtdd->rtdd12.rtds12.c_rtd12;
3504 for(i = 0;i < max_rtd_values;i++)
3505 {
3506 p_temp->enh_para.enh_cell_list[rtd_index].rtd[i] =RTD_12BIT;
3507 p_temp->enh_para.enh_cell_list[rtd_index].rtd[i] |= rtdd->rtdd12.rtds12.rtd12[i];
3508 } /*for*/
3509 p_temp->enh_para.enh_cell_list[rtd_index].c_rtd= max_rtd_values;
3510 } /*if*/
3511 for(j = 0;j < rtdd->rtdd12.c_rtds12_add;j++)
3512 {
3513 rtd_index++;
3514 if(rtd_index < MAX_NR_OF_NCELL)
3515 {
3516 p_temp->enh_para.enh_cell_list[rtd_index].v_rtd = TRUE;
3517 max_rtd_values = rtdd->rtdd12.rtds12_add[j].c_rtd12 > MAX_NUM_OF_RTD_VALUES ?
3518 MAX_NUM_OF_RTD_VALUES : rtdd->rtdd12.rtds12_add[j].c_rtd12;
3519 for(i = 0;i < max_rtd_values;i++)
3520 {
3521 p_temp->enh_para.enh_cell_list[rtd_index].rtd[i] = RTD_12BIT;
3522 p_temp->enh_para.enh_cell_list[rtd_index].rtd[i] |= rtdd->rtdd12.rtds12_add[j].rtd12[i];
3523 } /*for*/
3524 p_temp->enh_para.enh_cell_list[rtd_index].c_rtd= max_rtd_values;
3525 } /*if*/
3526 } /*for*/
3527 } /*if*/
3528 } /* end of dat_update_common_rtd_struct() */
3529
3530
3531 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
3532
3533 #endif