comparison g23m-gsm/rr/rr_datf.c @ 0:75a11d740a02

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