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