FreeCalypso > hg > freecalypso-citrine
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 |