FreeCalypso > hg > fc-tourmaline
comparison src/g23m-gsm/rr/rr_forf.c @ 1:fa8dc04885d8
src/g23m-*: import from Magnetite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 06:25:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:4e78acac3d88 | 1:fa8dc04885d8 |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : | |
4 | Modul : | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2002 Texas Instruments Berlin, AG | |
7 | All rights reserved. | |
8 | | |
9 | This file is confidential and a trade secret of Texas | |
10 | Instruments Berlin, AG | |
11 | The receipt of or possession of this file does not convey | |
12 | any rights to reproduce or disclose its contents or to | |
13 | manufacture, use, or sell anything it may describe, in | |
14 | whole, or in part, without the specific written consent of | |
15 | Texas Instruments Berlin, AG. | |
16 +----------------------------------------------------------------------------- | |
17 | Purpose : Handling of Common Information Elements. | |
18 +----------------------------------------------------------------------------- | |
19 */ | |
20 | |
21 | |
22 #ifndef RR_FORF_C | |
23 #define RR_FORF_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 | |
46 /*==== EXPORT =====================================================*/ | |
47 | |
48 /*==== PRIVATE =====================================================*/ | |
49 static BOOL for_create_delta_list (T_freq_chan_seq_after *delta_list, | |
50 T_LIST *hop_list); | |
51 static void for_decode_param (const T_W_PARAM *param, | |
52 SHORT *w, | |
53 T_f_range *cha, | |
54 USHORT initial_value); | |
55 static void for_decode_param_1024 (SHORT *w, | |
56 T_f_range *cha); | |
57 static USHORT for_get_generation (USHORT value); | |
58 static void for_decode_frequencies (SHORT original_range, | |
59 SHORT *w, | |
60 T_LIST *f, | |
61 SHORT offset); | |
62 static LONG for_modulo (LONG a, | |
63 LONG b); | |
64 static LONG for_smodulo (LONG a, | |
65 LONG b); | |
66 static void for_set_conditional_error (void); | |
67 | |
68 #if defined (TI_PS_FF_EMR) AND defined (GPRS) | |
69 static void for_store_nc_para(T_nc_meas_para *p_nc,T_rr_enh_para *p_em); | |
70 #endif | |
71 LOCAL void for_frequency_list(T_freq_list *freq_list_starting_time_cmd, | |
72 T_f_range *freq_list_starting_time_para, | |
73 T_LIST *hop_list_starting_time); | |
74 | |
75 | |
76 LOCAL void for_decode_param_freq(USHORT range ,T_f_range *cha_list_descr, | |
77 T_LIST *cha_list); | |
78 | |
79 /*==== GLOBAL VARIABLES ===========================================*/ | |
80 /*==== VARIABLES ==================================================*/ | |
81 /*==== FUNCTIONS ==================================================*/ | |
82 | |
83 /* | |
84 * ------------------------------------------------------------------- | |
85 * Procedures | |
86 * ------------------------------------------------------------------- | |
87 */ | |
88 /* | |
89 +--------------------------------------------------------------------+ | |
90 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
91 | STATE : code ROUTINE : for_check_ba_range | | |
92 +--------------------------------------------------------------------+ | |
93 | |
94 PURPOSE : The function checks the content of a ba range information | |
95 element which is used in the channel release message. | |
96 | |
97 */ | |
98 | |
99 GLOBAL BOOL for_check_ba_range (T_ba_range *ba_range) | |
100 { | |
101 USHORT i = 0; | |
102 UBYTE bands_used; | |
103 | |
104 TRACE_FUNCTION ("for_check_ba_range()"); | |
105 | |
106 /* | |
107 * for all ranges | |
108 */ | |
109 for (i = 0; i < ba_range->c_freq_range; i++) | |
110 { | |
111 /* | |
112 * check the lower range boarder | |
113 */ | |
114 bands_used = for_check_frequency (ba_range->freq_range[i].freq_lower); | |
115 if (bands_used <= INVALID_BAND_USED) | |
116 return FALSE; | |
117 | |
118 /* | |
119 * check the upper range boarder | |
120 */ | |
121 bands_used = for_check_frequency (ba_range->freq_range[i].freq_higher); | |
122 if (bands_used <= INVALID_BAND_USED) | |
123 return FALSE; | |
124 } | |
125 return TRUE; | |
126 } | |
127 | |
128 /* | |
129 +--------------------------------------------------------------------+ | |
130 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
131 | STATE : code ROUTINE : for_check_assign_cmd | | |
132 +--------------------------------------------------------------------+ | |
133 | |
134 PURPOSE : Content check of assignment command message. | |
135 | |
136 */ | |
137 | |
138 typedef struct | |
139 { | |
140 UBYTE count_before; | |
141 UBYTE count_after; | |
142 T_LIST cell_chan_desc; | |
143 T_LIST hop_list_after; | |
144 T_LIST hop_list_before; | |
145 T_f_range freq_list_after; | |
146 T_f_range freq_list_before; | |
147 } T_ASSIGN_PARA; | |
148 | |
149 GLOBAL void for_check_assign_cmd (T_DL_DATA_IND * dl_data_ind, | |
150 T_D_ASSIGN_CMD *assign_cmd) | |
151 { | |
152 GET_INSTANCE_DATA; | |
153 T_ASSIGN_PARA * a_para; | |
154 MALLOC (a_para, sizeof (T_ASSIGN_PARA)); | |
155 | |
156 a_para->count_before = 0; | |
157 a_para->count_after = 0; | |
158 | |
159 TRACE_EVENT ("for_check_assign_cmd()"); | |
160 | |
161 /* | |
162 * initialize several lists for frequency hopping purposes | |
163 */ | |
164 srv_clear_list (&a_para->cell_chan_desc); | |
165 srv_clear_list (&a_para->hop_list_after); | |
166 srv_clear_list (&a_para->hop_list_before); | |
167 | |
168 /* | |
169 * check the channel description | |
170 */ | |
171 for_check_channel_descr (&assign_cmd->chan_desc); | |
172 | |
173 if (assign_cmd->v_cell_chan_desc) | |
174 { | |
175 /* | |
176 * if a cell channel description is inserted | |
177 * create the cell channel list and check it. | |
178 */ | |
179 for_create_channel_list ((T_f_range *)&assign_cmd->cell_chan_desc, | |
180 &a_para->cell_chan_desc); | |
181 } | |
182 | |
183 if (assign_cmd->chan_desc.hop AND assign_cmd->v_freq_list_after) | |
184 { | |
185 /* | |
186 * if the message contains a frequency list | |
187 */ | |
188 /* Implements RR Clone findings #5 */ | |
189 for_frequency_list(&assign_cmd->freq_list_after, | |
190 &a_para->freq_list_after, | |
191 &a_para->hop_list_after); | |
192 | |
193 } | |
194 | |
195 | |
196 | |
197 /* | |
198 * check the channel mode, if available. | |
199 */ | |
200 if (assign_cmd->v_chan_mode) | |
201 for_check_channel_mode (assign_cmd->chan_mode); | |
202 | |
203 /* | |
204 * if the message contains a channel mode information element which | |
205 * indicates AMR, check the multirate configuration information element. | |
206 * or if no channel mode is present but we have been using AMR before | |
207 * check the supplied mulitrate configuration | |
208 */ | |
209 if ( ( assign_cmd->v_chan_mode AND (assign_cmd->chan_mode EQ CM_AMR)) OR | |
210 (!assign_cmd->v_chan_mode AND (rr_data->sc_data.ch_mode EQ CM_AMR)) | |
211 ) | |
212 { | |
213 if (assign_cmd->v_multirate_conf) | |
214 for_check_multirate_conf( &assign_cmd->multirate_conf, assign_cmd->chan_desc.chan_type); | |
215 | |
216 /* | |
217 * check if during initial assignment the multirate configuration element is present | |
218 * otherwise remain on the current channel and use the old channel description. | |
219 */ | |
220 if ( (rr_data->sc_data.ch_mode NEQ CM_AMR) AND (!assign_cmd->v_multirate_conf) ) | |
221 for_set_content_error (RRC_CHANNEL_MODE); | |
222 | |
223 /* | |
224 * If the assignment is related to an intra-cell handover from a multi-rate speech codec | |
225 * to a multi-rate speech codec, the MultiRate Configuration IE shall be included in the | |
226 * case of full rate to half rate. If not included in this case, the mobile station shall | |
227 * behave as if the MultiRate Configuration IE was inconsistent. | |
228 */ | |
229 if ( rr_data->sc_data.ch_mode EQ CM_AMR AND | |
230 rr_data->sc_data.chan_desc.chan_type EQ TCH_F AND | |
231 assign_cmd->chan_mode EQ CM_AMR AND | |
232 (assign_cmd->chan_desc.chan_type EQ TCH_H_S0 OR | |
233 assign_cmd->chan_desc.chan_type EQ TCH_H_S1) AND | |
234 assign_cmd->v_multirate_conf EQ 0 ) | |
235 { | |
236 for_set_content_error (RRC_CHANNEL_MODE); | |
237 } | |
238 } | |
239 | |
240 /* | |
241 * check the cipher mode setting if available | |
242 */ | |
243 if (assign_cmd->v_ciph_mode_set) | |
244 { | |
245 for_check_cipher_mode_set (&assign_cmd->ciph_mode_set); | |
246 } | |
247 | |
248 a_para->count_after = assign_cmd->v_freq_list_after + | |
249 assign_cmd->v_mob_alloc_after; | |
250 | |
251 if (assign_cmd->chan_desc.hop) | |
252 { | |
253 /* | |
254 * In case of frequency hopping, check whether more | |
255 * then one possibility is defined to build a frequency | |
256 * hopping list -> this means inconsistency and is | |
257 * a conditional error. | |
258 */ | |
259 if (a_para->count_after NEQ 1) | |
260 { | |
261 for_set_conditional_error (); | |
262 } | |
263 } | |
264 | |
265 if (assign_cmd->v_start_time) | |
266 { | |
267 /* | |
268 * If a starting time is present, some | |
269 * elements before starting time must be set. | |
270 */ | |
271 a_para->count_before = assign_cmd->v_chan_desc_before + | |
272 assign_cmd->v_freq_list_before + | |
273 assign_cmd->v_mob_alloc_before + | |
274 assign_cmd->v_freq_chan_seq; | |
275 | |
276 if (a_para->count_before NEQ 0 AND | |
277 assign_cmd->v_chan_desc_before EQ FALSE) | |
278 { | |
279 /* | |
280 * a frequency hopping definition is available, | |
281 * but no channel description before starting time. | |
282 * then use the channel description after starting time. | |
283 */ | |
284 memcpy (&assign_cmd->chan_desc_before, | |
285 &assign_cmd->chan_desc, | |
286 sizeof (T_chan_desc)); | |
287 assign_cmd->v_chan_desc_before = TRUE; | |
288 } | |
289 | |
290 if (assign_cmd->v_chan_desc_before) | |
291 { | |
292 /* | |
293 * if a channel description before starting time | |
294 * is available. | |
295 */ | |
296 if (assign_cmd->chan_desc_before.hop) | |
297 { | |
298 /* | |
299 * if the channel description before starting time | |
300 * uses a frequency hopping list, count the possible | |
301 * variants of building a frequency hopping list. | |
302 */ | |
303 a_para->count_before = assign_cmd->v_freq_list_before + | |
304 assign_cmd->v_mob_alloc_before + | |
305 assign_cmd->v_freq_chan_seq; | |
306 | |
307 switch (a_para->count_before) | |
308 { | |
309 /* | |
310 * no before elements to build a hopping list | |
311 */ | |
312 case 0: | |
313 if (a_para->count_after EQ 1) | |
314 { | |
315 /* | |
316 * use the after starting time variant also | |
317 * for the before starting time frequency list. | |
318 */ | |
319 memcpy (&assign_cmd->freq_list_before, | |
320 &assign_cmd->freq_list_after, | |
321 sizeof (T_freq_list)); | |
322 assign_cmd->v_freq_list_before = assign_cmd->v_freq_list_after; | |
323 memcpy (&assign_cmd->mob_alloc_before, | |
324 &assign_cmd->mob_alloc_after, | |
325 sizeof (T_mob_alloc_after)); | |
326 assign_cmd->v_mob_alloc_before = assign_cmd->v_mob_alloc_after; | |
327 } | |
328 else | |
329 { | |
330 /* | |
331 * A conditional error is detected. The channel description | |
332 * before starting time shall use frequency hopping, but no | |
333 * frequency hopping list can be created. | |
334 */ | |
335 for_set_conditional_error (); | |
336 } | |
337 break; | |
338 | |
339 case 1: | |
340 /* | |
341 * There is just one variant to build the frequency | |
342 * hopping list before starting time. | |
343 */ | |
344 break; | |
345 | |
346 default: | |
347 /* | |
348 * There are more then one variant to build the | |
349 * frequency hopping list before starting time. | |
350 * This is detected as a conditional error. | |
351 */ | |
352 for_set_conditional_error (); | |
353 break; | |
354 } | |
355 } | |
356 else | |
357 { /* IEs are unnecessary */ | |
358 assign_cmd->v_freq_list_before = | |
359 assign_cmd->v_mob_alloc_before = | |
360 assign_cmd->v_freq_chan_seq = 0; | |
361 } | |
362 } | |
363 } | |
364 else | |
365 { /* IEs are unnecessary */ | |
366 assign_cmd->v_chan_desc_before = | |
367 assign_cmd->v_freq_list_before = | |
368 assign_cmd->v_mob_alloc_before = | |
369 assign_cmd->v_freq_chan_seq = 0; | |
370 } | |
371 | |
372 if (assign_cmd->v_chan_desc_before) | |
373 { | |
374 /* | |
375 * check the channel description before starting time | |
376 * if available. | |
377 */ | |
378 for_check_channel_descr ((T_chan_desc *)&assign_cmd->chan_desc_before); | |
379 } | |
380 | |
381 if (assign_cmd->v_freq_list_before) | |
382 { | |
383 | |
384 /* Implements RR Clone findings #5 */ | |
385 for_frequency_list (&assign_cmd->freq_list_before, | |
386 &a_para->freq_list_after, | |
387 &a_para->hop_list_before); | |
388 } | |
389 | |
390 | |
391 | |
392 if (assign_cmd->v_freq_chan_seq) | |
393 { | |
394 /* | |
395 * if a frequency channel sequence information element is | |
396 * available, build a frequency hopping list. | |
397 */ | |
398 if (!for_create_delta_list ((T_freq_chan_seq_after *) | |
399 &assign_cmd->freq_chan_seq, | |
400 &a_para->hop_list_before)) | |
401 { | |
402 /* | |
403 * set a content error if the frequency hopping list | |
404 * contains channel numbers which are not supported. | |
405 */ | |
406 for_set_content_error (RRC_FREQ_NOT_IMPL); | |
407 } | |
408 } | |
409 | |
410 /* | |
411 * configure layer 1 for the new channel | |
412 */ | |
413 dat_for_assign_cmd (dl_data_ind, assign_cmd, &a_para->hop_list_after, | |
414 &a_para->hop_list_before, &a_para->cell_chan_desc); | |
415 | |
416 /* | |
417 * de-allocate the dynamic memory | |
418 */ | |
419 MFREE (a_para); | |
420 } | |
421 | |
422 /* | |
423 +--------------------------------------------------------------------+ | |
424 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
425 | STATE : code ROUTINE : for_check_cell_descr | | |
426 +--------------------------------------------------------------------+ | |
427 | |
428 PURPOSE : check the content of the information element cell | |
429 description. | |
430 | |
431 */ | |
432 | |
433 GLOBAL void for_check_cell_descr (T_cell_desc *cell_desc) | |
434 { | |
435 USHORT bcch_arfcn; | |
436 UBYTE result; | |
437 | |
438 TRACE_FUNCTION ("for_check_cell_desc()"); | |
439 | |
440 /* | |
441 * calculate the BCCH channel number | |
442 */ | |
443 bcch_arfcn = (cell_desc->bcch_arfcn_hi << 8) + | |
444 cell_desc->bcch_arfcn_lo; | |
445 | |
446 /* | |
447 * check the BCCH channel number. | |
448 * If the number is not a GSM channel number set the cause | |
449 * INCORRECT MESSAGE. | |
450 * If the number is a GSM channel number, but not supported | |
451 * by the mobile, set the cause FREQUENCY NOT IMPLEMENTED. | |
452 */ | |
453 result = for_check_frequency (bcch_arfcn); | |
454 if (result EQ UNKNOWN_BAND_USED) | |
455 for_set_content_error (RRC_INCORRECT_MSG); | |
456 else if( result EQ INVALID_BAND_USED ) | |
457 for_set_content_error (RRC_FREQ_NOT_IMPL); | |
458 } | |
459 | |
460 /* | |
461 +--------------------------------------------------------------------+ | |
462 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
463 | STATE : code ROUTINE : for_check_channel_descr | | |
464 +--------------------------------------------------------------------+ | |
465 | |
466 PURPOSE : check the content of the information element channel | |
467 description. | |
468 | |
469 */ | |
470 | |
471 GLOBAL void for_check_channel_descr (T_chan_desc *chan_desc) | |
472 { | |
473 GET_INSTANCE_DATA; | |
474 BOOL result = TRUE; | |
475 | |
476 TRACE_FUNCTION ("for_check_channel_descr()"); | |
477 | |
478 /* | |
479 * check the channel type | |
480 */ | |
481 switch (chan_desc->chan_type) | |
482 { | |
483 case TCH_H_S0: | |
484 case TCH_H_S1: | |
485 /* | |
486 * TCH Halfrate channels | |
487 * check against the mobile capabilities in PCM | |
488 * (halfrate support) | |
489 */ | |
490 if (FldGet(rr_data->mscap.chnMode, hrSup) EQ 0) | |
491 for_set_content_error (RRC_CHANNEL_MODE); | |
492 break; | |
493 | |
494 default: | |
495 /* | |
496 * 1 (= TCH Fullrate) or 4..15 (= SDCCH) | |
497 * are allowed values. Any other value | |
498 * is not supported. | |
499 */ | |
500 if ((chan_desc->chan_type EQ 0) | |
501 OR (chan_desc->chan_type > CH_SDCCH_8_7)) | |
502 for_set_content_error (RRC_CHANNEL_MODE); | |
503 break; | |
504 } | |
505 | |
506 if (chan_desc->hop EQ 0) | |
507 { | |
508 /* | |
509 * without frequency hopping. | |
510 * Then check the channel number of the channel | |
511 * description. | |
512 * If the number is not a GSM channel number set the cause | |
513 * INCORRECT MESSAGE. | |
514 * If the number is a GSM channel number, but not supported | |
515 * by the mobile, set the cause FREQUENCY NOT IMPLEMENTED. | |
516 */ | |
517 result = for_check_frequency (chan_desc->arfcn); | |
518 if (result EQ UNKNOWN_BAND_USED) | |
519 for_set_content_error (RRC_INCORRECT_MSG); | |
520 else if (result EQ INVALID_BAND_USED) | |
521 for_set_content_error (RRC_FREQ_NOT_IMPL); | |
522 } | |
523 } | |
524 | |
525 /* | |
526 +------------------------------------------------------------------------------ | |
527 | Function : for_check_multirate_conf | |
528 +------------------------------------------------------------------------------ | |
529 | Description : Set the new multi-rate speech codec elements | |
530 | | |
531 | Parameters : amr_conf - MultiRate configuration IEI | |
532 | | |
533 | Return : void | |
534 | | |
535 +------------------------------------------------------------------------------ | |
536 */ | |
537 GLOBAL void for_check_multirate_conf (T_multirate_conf * multirate_conf, UBYTE chan_type) | |
538 { | |
539 UBYTE acs = multirate_conf->set_amr; | |
540 UBYTE i=0, num_acs=0; | |
541 | |
542 TRACE_FUNCTION ("for_check_multirate_conf()"); | |
543 | |
544 /* | |
545 * Check number of codec modes inside the set of AMR codec mode mask | |
546 */ | |
547 for(i=0; i<8; i++) | |
548 { | |
549 if( (0x01<<i) & acs ) | |
550 { | |
551 num_acs++; | |
552 TRACE_EVENT_P1("AMR no. acs %d", num_acs); | |
553 } | |
554 } | |
555 | |
556 /* | |
557 * From 3GPP TS 04.18 | |
558 * | |
559 * The MultiRate Configuration IE shall be considered as inconsistent by the MS if: | |
560 * | |
561 * - the active set does not include any codec mode or the active set includes more than four codec modes; or | |
562 * - one or more codec modes of the active codec set are not supported by the assigned channel; or | |
563 * - the threshold and hysteresis values are not set according to requirements given in 3GPP TS 05.09. | |
564 * | |
565 * Refer to 3GPP TS 05.05 for codec modes supported by different channels. | |
566 */ | |
567 | |
568 if( | |
569 ((chan_type EQ CH_TCH_H_1) OR (chan_type EQ CH_TCH_H_2)) | |
570 AND | |
571 ((acs & SET_AMR_10_2) OR (acs & SET_AMR_12_2)) | |
572 ) | |
573 { | |
574 TRACE_EVENT_P2(" chan_type = %d acs = %d, invalid acs for TCH AHS", chan_type, acs); | |
575 for_set_content_error (RRC_CHANNEL_MODE); | |
576 return; | |
577 } | |
578 | |
579 /* | |
580 * The active set does not include any codec mode or the active set includes more than four | |
581 * codec modes. | |
582 */ | |
583 if( (num_acs > MAX_NO_ACS) OR (num_acs EQ 0) ) | |
584 { | |
585 TRACE_EVENT("AMR ((num_acs > MAX_NO_ACS) OR (num_acs EQ 0))"); | |
586 for_set_content_error (RRC_CHANNEL_MODE); | |
587 return; | |
588 } | |
589 | |
590 /* | |
591 * One or mode codec modes of the active codec set are not supported by | |
592 * the assigned channel. | |
593 */ | |
594 if ( num_acs < multirate_conf->st_mode ) | |
595 { | |
596 /* | |
597 * The start mode is not supported by the acs, e.g. CODEC_MODE_4 is requested but only 3 | |
598 * codec modes are part of the acs. | |
599 */ | |
600 TRACE_EVENT("(num_acs < multirate_conf->st_mode)"); | |
601 for_set_content_error (RRC_CHANNEL_MODE); | |
602 return; | |
603 } | |
604 | |
605 /* | |
606 * The threshold and hysteresis values are not set according to requirements in 3GPP TS 05.09 | |
607 */ | |
608 /* | |
609 * Number of codec modes minus one must be equal to number of thresholds and hysteresis | |
610 */ | |
611 if( ((num_acs-1) NEQ multirate_conf->c_cod_prop) ) | |
612 { | |
613 TRACE_EVENT("((num_acs-1) NEQ multirate_conf->c_cod_prop))"); | |
614 for_set_content_error (RRC_CHANNEL_MODE); | |
615 return; | |
616 } | |
617 | |
618 /* | |
619 * Check if the thresholds and hysteresis values are in consistent order | |
620 */ | |
621 for(i=0; i<(multirate_conf->c_cod_prop-1); i++) | |
622 { | |
623 if(multirate_conf->cod_prop[i].codec_thr > multirate_conf->cod_prop[i+1].codec_thr) | |
624 { | |
625 /* Implements Measure#32: Row 252 */ | |
626 TRACE_EVENT_P2("cod_prop[%d].codec_thr > cod_prop[%d+1].codec_thr",i,i); | |
627 for_set_content_error (RRC_CHANNEL_MODE); | |
628 } | |
629 else | |
630 { | |
631 if( (multirate_conf->cod_prop[i].codec_thr + multirate_conf->cod_prop[i].codec_hyst) > | |
632 (multirate_conf->cod_prop[i+1].codec_thr + multirate_conf->cod_prop[i+1].codec_hyst) ) | |
633 { | |
634 /* Implements Measure#32: Row 251 */ | |
635 TRACE_EVENT_P4("cod_prop[%d].codec_thr+cod_prop[%d].codec_hyst>cod_prop[%d+1].codec_thr+cod_prop[%d+1].codec_hyst", i,i,i,i); | |
636 for_set_content_error (RRC_CHANNEL_MODE); | |
637 } | |
638 } | |
639 } | |
640 } | |
641 | |
642 /* | |
643 +--------------------------------------------------------------------+ | |
644 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
645 | STATE : code ROUTINE : for_check_channel_mode | | |
646 +--------------------------------------------------------------------+ | |
647 | |
648 PURPOSE : check the information element channel mode. | |
649 | |
650 */ | |
651 | |
652 GLOBAL void for_check_channel_mode (UBYTE ch_mod) | |
653 { | |
654 GET_INSTANCE_DATA; | |
655 TRACE_FUNCTION ("for_check_channel_mode()"); | |
656 | |
657 /* | |
658 * Reads the ms bearer caps a second time after a config primitive was sent | |
659 * during a test case. Otherwise the new data will be ignored. | |
660 */ | |
661 #if defined (_SIMULATION_) | |
662 rr_csf_ms_cap (); | |
663 #endif | |
664 | |
665 /* | |
666 * depending on the channel mode. | |
667 */ | |
668 switch (ch_mod) | |
669 { | |
670 case CM_DATA_12_0: /* data 12 k */ | |
671 case CM_DATA_6_0: /* data 6 k */ | |
672 case CM_DATA_3_6: /* data 3.6 k */ | |
673 /* | |
674 * check against the data capabilities of the | |
675 * mobile. The PCM record must indicate data | |
676 * support. | |
677 */ | |
678 if (FldGet(rr_data->mscap.datCap1, datSup) EQ 0) | |
679 for_set_content_error (RRC_CHANNEL_MODE); | |
680 break; | |
681 | |
682 case CM_DATA_14_4: /* data 14.4 k */ | |
683 /* | |
684 * check against the data capabilities of the | |
685 * mobile. The PCM record must indicate 14.4 k data | |
686 * support. | |
687 */ | |
688 if (FldGet(rr_data->mscap.datCap1, Dr14_4Sup) EQ 0) | |
689 for_set_content_error (RRC_CHANNEL_MODE); | |
690 break; | |
691 | |
692 case CM_EFR: /* enhanced full rate */ | |
693 /* | |
694 * check against the mobile capabilities | |
695 * The PCM record must indicate support for | |
696 * enhanced fullrate. | |
697 */ | |
698 if (FldGet(rr_data->mscap.chnMode, EFRSupV2) EQ 0) | |
699 for_set_content_error (RRC_CHANNEL_MODE); | |
700 break; | |
701 | |
702 case CM_AMR: /* speech full rate / half rate version 3 - AMR */ | |
703 /* | |
704 * check against the mobile capabilities | |
705 * The PCM record must indicate support for | |
706 * speech version 3. | |
707 */ | |
708 if ( (FldGet(rr_data->mscap.chnMode, AHS) EQ 0) AND (FldGet(rr_data->mscap.chnMode, AFS) EQ 0)) | |
709 for_set_content_error (RRC_CHANNEL_MODE); | |
710 break; | |
711 | |
712 case CM_SIG_ONLY: /* signalling only */ | |
713 break; | |
714 case CM_SPEECH: /* speech full or halfrate */ | |
715 /* If a speech mode is intended, but the MS is a data only unit, then error */ | |
716 if( !( rr_data->mscap.chnMode & ( spchSupV1m | HR_EFRSupm | EFRSupV3m | AHSm | AFSm ))) | |
717 { | |
718 for_set_content_error (RRC_CHANNEL_MODE); | |
719 } | |
720 break; | |
721 | |
722 default: | |
723 /* | |
724 * a non-supported channel mode is detected. | |
725 */ | |
726 for_set_content_error (RRC_CHANNEL_MODE); | |
727 break; | |
728 } | |
729 } | |
730 | |
731 /* | |
732 +--------------------------------------------------------------------+ | |
733 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
734 | STATE : code ROUTINE : for_check_cipher_mode_set | | |
735 +--------------------------------------------------------------------+ | |
736 | |
737 PURPOSE : check cipher mode setting information element. | |
738 | |
739 */ | |
740 | |
741 GLOBAL void for_check_cipher_mode_set (T_ciph_mode_set *ciph_mode_set) | |
742 { | |
743 GET_INSTANCE_DATA; | |
744 TRACE_FUNCTION ("for_check_cipher_mode_set()"); | |
745 | |
746 if (ciph_mode_set->algo_ident EQ 7) | |
747 { | |
748 /* | |
749 * check whether the algorithm identifier contains | |
750 * the reserved value. | |
751 */ | |
752 for_set_content_error (RRC_INCORRECT_MSG); | |
753 } | |
754 | |
755 /* | |
756 * If ciphering is set, check the ciphering algorithm against the mobile's | |
757 * capabilities. Regard message as incorrect if the requested algorithm is | |
758 * not supported by the mobile. | |
759 */ | |
760 if (ciph_mode_set->sc EQ START_CIPH_YES) | |
761 { | |
762 switch (ciph_mode_set->algo_ident) | |
763 { | |
764 case ALGO_A5_1: | |
765 if (!rr_data->ms_data.rf_cap.a5_bits.a5_1) | |
766 for_set_content_error (RRC_INCORRECT_MSG); | |
767 break; | |
768 case ALGO_A5_2: | |
769 if (!rr_data->ms_data.rf_cap.a5_bits.a5_2) | |
770 for_set_content_error (RRC_INCORRECT_MSG); | |
771 break; | |
772 case ALGO_A5_3: | |
773 if (!rr_data->ms_data.rf_cap.a5_bits.a5_3) | |
774 for_set_content_error (RRC_INCORRECT_MSG); | |
775 break; | |
776 case ALGO_A5_4: | |
777 if (!rr_data->ms_data.rf_cap.a5_bits.a5_4) | |
778 for_set_content_error (RRC_INCORRECT_MSG); | |
779 break; | |
780 case ALGO_A5_5: | |
781 if (!rr_data->ms_data.rf_cap.a5_bits.a5_5) | |
782 for_set_content_error (RRC_INCORRECT_MSG); | |
783 break; | |
784 case ALGO_A5_6: | |
785 if (!rr_data->ms_data.rf_cap.a5_bits.a5_6) | |
786 for_set_content_error (RRC_INCORRECT_MSG); | |
787 break; | |
788 case ALGO_A5_7: | |
789 if (!rr_data->ms_data.rf_cap.a5_bits.a5_7) | |
790 for_set_content_error (RRC_INCORRECT_MSG); | |
791 break; | |
792 default: /* Reserved value received, already handled above */ | |
793 break; | |
794 } | |
795 } | |
796 } | |
797 | |
798 /* | |
799 +--------------------------------------------------------------------+ | |
800 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
801 | STATE : code ROUTINE : for_check_frequency | | |
802 +--------------------------------------------------------------------+ | |
803 | |
804 PURPOSE : The function checks a frequency. The return value is TRUE | |
805 if the channel number is a GSM channel number. The output | |
806 variable range indicates whether the channel number is | |
807 supported by the mobile depending on the frequency standard. | |
808 | |
809 Return Values : | |
810 | |
811 if (arfcn) is not a valid GSM Channel :- | |
812 UNKNOWN_BAND_USED | |
813 | |
814 if (arfcn) is valid GSM Channel then depending upon (std) one of the | |
815 4 values are returned : | |
816 LOW_BAND_USED | |
817 HIGH_BAND_USED | |
818 EXT_BAND_USED | |
819 INVALID_BAND_USED | |
820 | |
821 | |
822 */ | |
823 | |
824 GLOBAL UBYTE for_check_frequency (USHORT channel) | |
825 { | |
826 | |
827 TRACE_FUNCTION ("for_check_frequency()"); | |
828 | |
829 /* | |
830 * check whether the channel number is a GSM channel number | |
831 * the check is a little bit too simple, but it seems not | |
832 * to be worst to check it. | |
833 */ | |
834 if (channel >= HIGH_CHANNEL_EGSM) | |
835 { | |
836 return UNKNOWN_BAND_USED; | |
837 } | |
838 | |
839 /* | |
840 * a more efficient way of range checking for ARM | |
841 * (according to application note 34, ARM DAI 0034A, January 1998) | |
842 * | |
843 * For the following code: | |
844 * if (channel >= low_channel AND channel <= high_channel) | |
845 * bitposition = ...; | |
846 * | |
847 * exist the faster way to implemented this: | |
848 * if ((unsigned)(channel - low_channel) <= (high_channel - low_channel) | |
849 * bitposition = ...; | |
850 * | |
851 * Future versions of the compiler will perform this optimization | |
852 * automatically. | |
853 * | |
854 * We use the follwing macro: | |
855 * #define INRANGE(min, x, max) ((unsigned)(x-min) <= (max-min)) | |
856 * | |
857 */ | |
858 | |
859 /* | |
860 * depending on the frequency standard | |
861 */ | |
862 switch (std) | |
863 { | |
864 case STD_900: | |
865 /* | |
866 if (channel >= LOW_CHANNEL_900 AND channel <= HIGH_CHANNEL_900) | |
867 *range = TRUE; | |
868 */ | |
869 if (INRANGE(LOW_CHANNEL_900,channel,HIGH_CHANNEL_900)) | |
870 { | |
871 return LOW_BAND_USED; | |
872 } | |
873 break; | |
874 | |
875 case STD_EGSM: | |
876 /* | |
877 if (channel EQ CHANNEL_0) | |
878 channel = CHANNEL_0_INTERNAL; | |
879 if (channel >= LOW_CHANNEL_900 AND channel <= HIGH_CHANNEL_900) | |
880 *range = TRUE; | |
881 else if (channel >= LOW_CHANNEL_EGSM AND channel <= HIGH_CHANNEL_EGSM) | |
882 *range = TRUE; | |
883 */ | |
884 if (channel EQ CHANNEL_0) | |
885 channel = CHANNEL_0_INTERNAL; | |
886 if (INRANGE(LOW_CHANNEL_900,channel,HIGH_CHANNEL_900)) | |
887 { | |
888 return LOW_BAND_USED; | |
889 } | |
890 else if (INRANGE(LOW_CHANNEL_EGSM,channel,HIGH_CHANNEL_EGSM)) | |
891 { | |
892 return EXT_BAND_USED; | |
893 } | |
894 break; | |
895 | |
896 case STD_1900: | |
897 /* | |
898 if (channel >= LOW_CHANNEL_1900 AND channel <= HIGH_CHANNEL_1900) | |
899 *range = TRUE; | |
900 */ | |
901 if (INRANGE(LOW_CHANNEL_1900,channel,HIGH_CHANNEL_1900)) | |
902 { | |
903 return HIGH_BAND_USED; | |
904 } | |
905 break; | |
906 | |
907 case STD_1800: | |
908 /* | |
909 if (channel >= LOW_CHANNEL_1800 AND channel <= HIGH_CHANNEL_1800) | |
910 *range = TRUE; | |
911 */ | |
912 if (INRANGE(LOW_CHANNEL_1800,channel,HIGH_CHANNEL_1800)) | |
913 { | |
914 return HIGH_BAND_USED; | |
915 } | |
916 break; | |
917 | |
918 case STD_DUAL: | |
919 /* | |
920 if (channel >= LOW_CHANNEL_900 AND channel <= HIGH_CHANNEL_900) | |
921 *range = TRUE; | |
922 else if (channel >= LOW_CHANNEL_1800 AND channel <= HIGH_CHANNEL_1800) | |
923 *range = TRUE; | |
924 */ | |
925 if (INRANGE(LOW_CHANNEL_900,channel,HIGH_CHANNEL_900)) | |
926 { | |
927 return LOW_BAND_USED; | |
928 } | |
929 else if (INRANGE(LOW_CHANNEL_1800,channel,HIGH_CHANNEL_1800)) | |
930 { | |
931 return HIGH_BAND_USED; | |
932 } | |
933 break; | |
934 | |
935 case STD_DUAL_EGSM: | |
936 /* | |
937 if (channel EQ CHANNEL_0) | |
938 channel = CHANNEL_0_INTERNAL; | |
939 if (channel >= LOW_CHANNEL_900 AND channel <= HIGH_CHANNEL_900) | |
940 *range = TRUE; | |
941 else if (channel >= LOW_CHANNEL_1800 AND channel <= HIGH_CHANNEL_1800) | |
942 *range = TRUE; | |
943 else if (channel >= LOW_CHANNEL_EGSM AND channel <= HIGH_CHANNEL_EGSM) | |
944 *range = TRUE; | |
945 */ | |
946 if (channel EQ CHANNEL_0) | |
947 channel = CHANNEL_0_INTERNAL; | |
948 if (INRANGE(LOW_CHANNEL_900,channel,HIGH_CHANNEL_900)) | |
949 { | |
950 return LOW_BAND_USED; | |
951 } | |
952 else if (INRANGE(LOW_CHANNEL_1800,channel,HIGH_CHANNEL_1800)) | |
953 { | |
954 return HIGH_BAND_USED; | |
955 } | |
956 else if (INRANGE(LOW_CHANNEL_EGSM,channel,HIGH_CHANNEL_EGSM)) | |
957 { | |
958 return EXT_BAND_USED; | |
959 } | |
960 break; | |
961 | |
962 case STD_850: | |
963 /* | |
964 if (channel >= LOW_CHANNEL_850 AND channel <= HIGH_CHANNEL_850) | |
965 *range = TRUE; | |
966 */ | |
967 if (INRANGE(LOW_CHANNEL_850,channel,HIGH_CHANNEL_850)) | |
968 { | |
969 return LOW_BAND_USED; | |
970 } | |
971 break; | |
972 | |
973 case STD_DUAL_US: | |
974 /* | |
975 if (channel >= LOW_CHANNEL_850 AND channel <= HIGH_CHANNEL_850) | |
976 *range = TRUE; | |
977 else if (channel >= LOW_CHANNEL_1900 AND channel <= HIGH_CHANNEL_1900) | |
978 *range = TRUE; | |
979 */ | |
980 if (INRANGE(LOW_CHANNEL_850,channel,HIGH_CHANNEL_850)) | |
981 { | |
982 return LOW_BAND_USED; | |
983 } | |
984 else if (INRANGE(LOW_CHANNEL_1900,channel,HIGH_CHANNEL_1900)) | |
985 { | |
986 return HIGH_BAND_USED; | |
987 } | |
988 break; | |
989 | |
990 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT | |
991 case STD_850_1800: | |
992 if (INRANGE(LOW_CHANNEL_850,channel,HIGH_CHANNEL_850)) | |
993 { | |
994 return LOW_BAND_USED; | |
995 } | |
996 else if (INRANGE(LOW_CHANNEL_1800,channel,HIGH_CHANNEL_1800)) | |
997 { | |
998 return HIGH_BAND_USED; | |
999 } | |
1000 break; | |
1001 | |
1002 case STD_900_1900: | |
1003 if (channel EQ CHANNEL_0) | |
1004 channel = CHANNEL_0_INTERNAL; | |
1005 if (INRANGE(LOW_CHANNEL_900,channel,HIGH_CHANNEL_900)) | |
1006 { | |
1007 return LOW_BAND_USED; | |
1008 } | |
1009 else if (INRANGE(LOW_CHANNEL_1900,channel,HIGH_CHANNEL_1900)) | |
1010 { | |
1011 return HIGH_BAND_USED; | |
1012 } | |
1013 else if (INRANGE(LOW_CHANNEL_EGSM,channel,HIGH_CHANNEL_EGSM)) | |
1014 { | |
1015 return EXT_BAND_USED; | |
1016 } | |
1017 break; | |
1018 | |
1019 case STD_850_900_1800: | |
1020 if (channel EQ CHANNEL_0) | |
1021 channel = CHANNEL_0_INTERNAL; | |
1022 if (INRANGE(LOW_CHANNEL_900,channel,HIGH_CHANNEL_900)) | |
1023 { | |
1024 return LOW_BAND_USED; | |
1025 } | |
1026 else if (INRANGE(LOW_CHANNEL_1800,channel,HIGH_CHANNEL_1800)) | |
1027 { | |
1028 return HIGH_BAND_USED; | |
1029 } | |
1030 else if (INRANGE(LOW_CHANNEL_EGSM,channel,HIGH_CHANNEL_EGSM)) | |
1031 { | |
1032 return EXT_BAND_USED; | |
1033 } | |
1034 else if (INRANGE(LOW_CHANNEL_850,channel,HIGH_CHANNEL_850)) | |
1035 { | |
1036 return LOW_BAND_USED; | |
1037 } | |
1038 break; | |
1039 | |
1040 case STD_850_900_1900: | |
1041 if (channel EQ CHANNEL_0) | |
1042 channel = CHANNEL_0_INTERNAL; | |
1043 if (INRANGE(LOW_CHANNEL_900,channel,HIGH_CHANNEL_900)) | |
1044 { | |
1045 return LOW_BAND_USED; | |
1046 } | |
1047 else if (INRANGE(LOW_CHANNEL_1900,channel,HIGH_CHANNEL_1900)) | |
1048 { | |
1049 return HIGH_BAND_USED; | |
1050 } | |
1051 else if (INRANGE(LOW_CHANNEL_EGSM,channel,HIGH_CHANNEL_EGSM)) | |
1052 { | |
1053 return EXT_BAND_USED; | |
1054 } | |
1055 else if (INRANGE(LOW_CHANNEL_850,channel,HIGH_CHANNEL_850)) | |
1056 { | |
1057 return LOW_BAND_USED; | |
1058 } | |
1059 break; | |
1060 #endif | |
1061 | |
1062 } | |
1063 | |
1064 return INVALID_BAND_USED; | |
1065 } | |
1066 | |
1067 /* | |
1068 +--------------------------------------------------------------------+ | |
1069 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
1070 | STATE : code ROUTINE : for_check_handov_cmd | | |
1071 +--------------------------------------------------------------------+ | |
1072 | |
1073 PURPOSE : Content check of handover command message. | |
1074 | |
1075 */ | |
1076 | |
1077 typedef struct | |
1078 { | |
1079 | |
1080 UBYTE count_after; | |
1081 UBYTE count_before; | |
1082 T_LIST cell_chan_desc; | |
1083 T_LIST hop_list_after; | |
1084 T_LIST hop_list_before; | |
1085 T_f_range freq_short_list_after; | |
1086 T_f_range freq_list_after; | |
1087 T_f_range freq_short_list_before; | |
1088 T_f_range freq_list_before; | |
1089 } T_HANDOVER_PARA; | |
1090 | |
1091 GLOBAL void for_check_handov_cmd (T_DL_DATA_IND * dl_data_ind, | |
1092 T_D_HANDOV_CMD * handov_cmd) | |
1093 { | |
1094 GET_INSTANCE_DATA; | |
1095 T_HANDOVER_PARA * h_para; | |
1096 MALLOC (h_para, sizeof (T_HANDOVER_PARA)); | |
1097 | |
1098 h_para->count_after = 0; | |
1099 h_para->count_before= 0; | |
1100 | |
1101 /* | |
1102 * clear several lists for building frequency hopping lists, | |
1103 */ | |
1104 srv_clear_list (&h_para->hop_list_after); | |
1105 srv_clear_list (&h_para->hop_list_before); | |
1106 srv_clear_list (&h_para->cell_chan_desc); | |
1107 | |
1108 /* | |
1109 * check the content of the cell description information element. | |
1110 */ | |
1111 for_check_cell_descr (&handov_cmd->cell_desc); | |
1112 | |
1113 /* | |
1114 * check the content of the channel description information element | |
1115 */ | |
1116 for_check_channel_descr ((T_chan_desc *) | |
1117 &handov_cmd->chan_desc_after); | |
1118 | |
1119 if (handov_cmd->v_freq_short_list_after) | |
1120 { | |
1121 /* | |
1122 * the message contains a frequency short list information element | |
1123 * for after starting time channel description | |
1124 */ | |
1125 | |
1126 /* | |
1127 * clear the local variable. | |
1128 */ | |
1129 | |
1130 | |
1131 memset (&h_para->freq_short_list_after, 0, | |
1132 sizeof (T_f_range)); | |
1133 | |
1134 /* | |
1135 * copy the content of the information element | |
1136 */ | |
1137 memcpy (&h_para->freq_short_list_after, | |
1138 &handov_cmd->freq_short_list_after, | |
1139 sizeof (BUF_freq_short_list_after)); | |
1140 | |
1141 /* | |
1142 * build a frequency hopping list for layer 1. | |
1143 */ | |
1144 for_create_channel_list (&h_para->freq_short_list_after, | |
1145 &h_para->hop_list_after); | |
1146 /* check if all frequencies are in one band */ | |
1147 if(! srv_check_frequencies_in_list (&h_para->hop_list_after)) | |
1148 { | |
1149 for_set_content_error(RRC_FREQ_NOT_IMPL); | |
1150 } | |
1151 } | |
1152 | |
1153 | |
1154 | |
1155 if (handov_cmd->v_freq_list_after) | |
1156 { | |
1157 /* | |
1158 * the message contains a frequency list information element. | |
1159 */ | |
1160 | |
1161 /* | |
1162 * clear the local variable | |
1163 */ | |
1164 /* Implements RR Clone findings #6 */ | |
1165 for_frequency_list (&handov_cmd->freq_list_after, | |
1166 &h_para->freq_list_after, | |
1167 &h_para->hop_list_after); | |
1168 | |
1169 } | |
1170 | |
1171 | |
1172 if (handov_cmd->v_cell_chan_desc) | |
1173 { | |
1174 /* | |
1175 * the message contains a cell channel description information | |
1176 * element. Build a list for layer 1. | |
1177 */ | |
1178 for_create_channel_list ((T_f_range *)&handov_cmd->cell_chan_desc, | |
1179 &h_para->cell_chan_desc); | |
1180 } | |
1181 | |
1182 /* | |
1183 * if the message contains a channel mode information element, | |
1184 * check the channel mode against the mobile capabilities. | |
1185 */ | |
1186 if (handov_cmd->v_chan_mode) | |
1187 for_check_channel_mode (handov_cmd->chan_mode); | |
1188 | |
1189 /* | |
1190 * if the message contains a channel mode information element which | |
1191 * indicates AMR, check the multirate configuration information element. | |
1192 * or if no channel mode is present but we have been using AMR before | |
1193 * check the supplied mulitrate configuration | |
1194 */ | |
1195 if ( ( handov_cmd->v_chan_mode AND (handov_cmd->chan_mode EQ CM_AMR)) OR | |
1196 (!handov_cmd->v_chan_mode AND (rr_data->sc_data.ch_mode EQ CM_AMR)) | |
1197 ) | |
1198 { | |
1199 if (handov_cmd->v_multirate_conf) | |
1200 for_check_multirate_conf( &handov_cmd->multirate_conf, | |
1201 handov_cmd->chan_desc_after.chan_type); | |
1202 | |
1203 /* | |
1204 * check if the multirate configuration element is present | |
1205 */ | |
1206 if ( (rr_data->sc_data.ch_mode NEQ CM_AMR) AND (!handov_cmd->v_multirate_conf) ) | |
1207 for_set_content_error (RRC_CHANNEL_MODE); | |
1208 | |
1209 /* | |
1210 * The MultiRate Configuration IE shall be included in the case of full rate channel | |
1211 * to half rate channel handover. If not included in this case, the mobile station | |
1212 * shall behave as if the MultiRate Configuration IE was inconsistent. | |
1213 */ | |
1214 | |
1215 if ( rr_data->sc_data.ch_mode EQ CM_AMR AND | |
1216 rr_data->sc_data.chan_desc.chan_type EQ TCH_F AND | |
1217 handov_cmd->chan_mode EQ CM_AMR AND | |
1218 (handov_cmd->chan_desc_after.chan_type EQ TCH_H_S0 OR | |
1219 handov_cmd->chan_desc_after.chan_type EQ TCH_H_S1) AND | |
1220 handov_cmd->v_multirate_conf EQ 0 ) | |
1221 { | |
1222 for_set_content_error (RRC_CHANNEL_MODE); | |
1223 } | |
1224 } | |
1225 | |
1226 if (handov_cmd->v_freq_chan_seq_after) | |
1227 { | |
1228 /* | |
1229 * the message contains a frequency channel sequence information | |
1230 * element. Build a frequency hopping list from this information. | |
1231 */ | |
1232 if (!for_create_delta_list (&handov_cmd->freq_chan_seq_after, | |
1233 &h_para->hop_list_after)) | |
1234 { | |
1235 /* | |
1236 * set a content error if the frequency hopping list | |
1237 * contains channel numbers which are not supported. | |
1238 */ | |
1239 for_set_content_error (RRC_FREQ_NOT_IMPL); | |
1240 } | |
1241 } | |
1242 | |
1243 if (handov_cmd->v_ciph_mode_set) | |
1244 { | |
1245 /* | |
1246 * if the message contains cipher mode information, | |
1247 * check the content. | |
1248 */ | |
1249 for_check_cipher_mode_set (&handov_cmd->ciph_mode_set); | |
1250 } | |
1251 | |
1252 if (handov_cmd->chan_desc_after.hop) | |
1253 { | |
1254 /* | |
1255 * the channel description after starting time uses | |
1256 * frequency hopping. It is counted the number of | |
1257 * used variants for building a frequency hopping list | |
1258 * after starting time. | |
1259 */ | |
1260 h_para->count_after = handov_cmd->v_freq_list_after + | |
1261 handov_cmd->v_freq_short_list_after + | |
1262 handov_cmd->v_mob_alloc_after + | |
1263 handov_cmd->v_freq_chan_seq_after; | |
1264 | |
1265 /* | |
1266 * If no or more then one variant is defined, | |
1267 * RR detects a conditional error. | |
1268 */ | |
1269 if (h_para->count_after NEQ 1) | |
1270 for_set_conditional_error (); | |
1271 | |
1272 /* | |
1273 * If the message contains a mobile allocation but no | |
1274 * cell channel description, it is not possible to | |
1275 * build a frequency hopping list: indicate a conditional | |
1276 * error. | |
1277 */ | |
1278 if (handov_cmd->v_mob_alloc_after AND | |
1279 handov_cmd->v_cell_chan_desc EQ FALSE) | |
1280 for_set_conditional_error (); | |
1281 } | |
1282 else | |
1283 { | |
1284 /* | |
1285 * the frequency lists after aren't needed | |
1286 * for hopping after starting time (GSM 04.08 section 9.1.15.5) | |
1287 * now check whether the frequency lists after time are needed | |
1288 * for hopping before starting time (GSM 04.08 section 9.1.15.6) | |
1289 */ | |
1290 if ( !( handov_cmd->v_start_time AND /* there is a starting time */ | |
1291 ( handov_cmd->v_chan_desc_before AND /* there is required hopping before time */ | |
1292 handov_cmd->chan_desc_before.hop /* explicitly, if using the chan_desc_after (see below) */ | |
1293 ) /* hopping before is implicitly checked above */ | |
1294 ) OR | |
1295 handov_cmd->v_freq_list_before OR /* hopping before time (if present) uses one of its "own" lists */ | |
1296 handov_cmd->v_freq_short_list_before OR | |
1297 handov_cmd->v_mob_alloc_before OR | |
1298 handov_cmd->v_freq_chan_seq_before ) | |
1299 { | |
1300 /* the frequency lists after time aren't needed */ | |
1301 handov_cmd->v_freq_list_after = | |
1302 handov_cmd->v_freq_short_list_after = | |
1303 handov_cmd->v_mob_alloc_after = | |
1304 handov_cmd->v_freq_chan_seq_after = 0; | |
1305 } | |
1306 } | |
1307 | |
1308 /* | |
1309 * In case of pseudo-synchronized handover it is | |
1310 * mandatory to have a time difference information | |
1311 * element, else set a conditional error. | |
1312 */ | |
1313 if (handov_cmd->v_time_diff EQ FALSE AND | |
1314 handov_cmd->synch_ind.si EQ SYI_PSEUDO_SYNCH) | |
1315 for_set_conditional_error (); | |
1316 | |
1317 if (handov_cmd->v_start_time) | |
1318 { | |
1319 h_para->count_before = handov_cmd->v_chan_desc_before + | |
1320 handov_cmd->v_freq_list_before + | |
1321 handov_cmd->v_freq_short_list_before + | |
1322 handov_cmd->v_mob_alloc_before + | |
1323 handov_cmd->v_freq_chan_seq_before; | |
1324 | |
1325 if (h_para->count_before NEQ 0) | |
1326 { | |
1327 /* | |
1328 * The message contains a starting time information element. | |
1329 */ | |
1330 if (handov_cmd->v_chan_desc_before EQ FALSE) | |
1331 { | |
1332 /* | |
1333 * if the message contains no channel description | |
1334 * before starting time element, use the | |
1335 * channel description after starting time instead. | |
1336 */ | |
1337 memcpy (&handov_cmd->chan_desc_before, | |
1338 &handov_cmd->chan_desc_after, | |
1339 sizeof (T_chan_desc)); | |
1340 handov_cmd->v_chan_desc_before = TRUE; | |
1341 } | |
1342 | |
1343 if (handov_cmd->chan_desc_before.hop) | |
1344 { | |
1345 /* | |
1346 * if the channel description before starting time | |
1347 * contains a frequency hopping list, count the | |
1348 * number of possible variants. | |
1349 */ | |
1350 h_para->count_before = handov_cmd->v_freq_list_before + | |
1351 handov_cmd->v_freq_short_list_before + | |
1352 handov_cmd->v_mob_alloc_before + | |
1353 handov_cmd->v_freq_chan_seq_before; | |
1354 | |
1355 switch (h_para->count_before) | |
1356 { | |
1357 case 0: | |
1358 /* | |
1359 * no before elements for hopping list then use the | |
1360 * elements of the after starting time. | |
1361 */ | |
1362 if (h_para->count_after EQ 1) | |
1363 { | |
1364 /* | |
1365 * copy the frequency list after starting time | |
1366 * if available | |
1367 */ | |
1368 memcpy (&handov_cmd->freq_list_before, | |
1369 &handov_cmd->freq_list_after, | |
1370 sizeof (T_freq_list)); | |
1371 handov_cmd->v_freq_list_before = handov_cmd->v_freq_list_after; | |
1372 | |
1373 /* | |
1374 * copy the frequency short list after starting time if available | |
1375 */ | |
1376 memcpy (&handov_cmd->freq_short_list_before, | |
1377 &handov_cmd->freq_short_list_after, | |
1378 sizeof (BUF_freq_short_list_after)); | |
1379 handov_cmd->v_freq_short_list_before = handov_cmd->v_freq_short_list_after; | |
1380 | |
1381 /* | |
1382 * copy mobile allocation after starting time if available | |
1383 */ | |
1384 memcpy (&handov_cmd->mob_alloc_before, | |
1385 &handov_cmd->mob_alloc_after, | |
1386 sizeof (T_mob_alloc_after)); | |
1387 handov_cmd->v_mob_alloc_before = handov_cmd->v_mob_alloc_after; | |
1388 | |
1389 /* | |
1390 * copy frequency channel sequence after starting time if available | |
1391 */ | |
1392 memcpy (&handov_cmd->freq_chan_seq_before, | |
1393 &handov_cmd->freq_chan_seq_after, | |
1394 sizeof (T_freq_chan_seq_after)); | |
1395 handov_cmd->v_freq_chan_seq_before = handov_cmd->v_freq_chan_seq_after; | |
1396 } | |
1397 else | |
1398 { | |
1399 /* | |
1400 * more then one possibility to build a frequency hopping list. | |
1401 * This means an inconsistent message. | |
1402 */ | |
1403 for_set_conditional_error (); | |
1404 } | |
1405 break; | |
1406 | |
1407 case 1: | |
1408 /* | |
1409 * Just one variant to build a frequency hopping list before | |
1410 * starting time. | |
1411 */ | |
1412 break; | |
1413 | |
1414 default: | |
1415 /* | |
1416 * more then one possibility to build a frequency hopping list. | |
1417 * This means an inconsistent message. | |
1418 */ | |
1419 for_set_conditional_error (); | |
1420 break; | |
1421 } | |
1422 } | |
1423 } | |
1424 } | |
1425 else | |
1426 { /* IEs are unnecessary */ | |
1427 handov_cmd->v_chan_desc_before = | |
1428 handov_cmd->v_freq_list_before = | |
1429 handov_cmd->v_freq_short_list_before = | |
1430 handov_cmd->v_mob_alloc_before = | |
1431 handov_cmd->v_freq_chan_seq_before = 0; | |
1432 } | |
1433 | |
1434 /* | |
1435 * the message contains a mobile allocation but no cell channel description. | |
1436 * It is not possible to build a frequency hopping list. | |
1437 */ | |
1438 if (handov_cmd->v_mob_alloc_before AND | |
1439 handov_cmd->v_cell_chan_desc EQ FALSE) | |
1440 for_set_conditional_error (); | |
1441 | |
1442 /* | |
1443 * If the message contains a channel description before starting time, | |
1444 * check the content. | |
1445 */ | |
1446 if (handov_cmd->v_chan_desc_before) | |
1447 for_check_channel_descr ((T_chan_desc *) | |
1448 &handov_cmd->chan_desc_before); | |
1449 | |
1450 if (handov_cmd->v_freq_short_list_before) | |
1451 { | |
1452 /* | |
1453 * build a frequency hopping list for the channel description before | |
1454 * starting time from the frequency short list information element. | |
1455 */ | |
1456 | |
1457 /* | |
1458 * clear the local variable. | |
1459 */ | |
1460 memset (&h_para->freq_short_list_before, 0, | |
1461 sizeof (T_f_range)); | |
1462 | |
1463 /* | |
1464 * copy the content of the information element. | |
1465 */ | |
1466 memcpy (&h_para->freq_short_list_before, | |
1467 &handov_cmd->freq_short_list_before, | |
1468 sizeof (BUF_freq_short_list_before)); | |
1469 | |
1470 /* | |
1471 * build a list for layer 1. | |
1472 */ | |
1473 for_create_channel_list (&h_para->freq_short_list_before, | |
1474 &h_para->hop_list_before); | |
1475 /* check if all frequencies are in one band */ | |
1476 if(! srv_check_frequencies_in_list (&h_para->hop_list_before)) | |
1477 { | |
1478 for_set_content_error(RRC_FREQ_NOT_IMPL); | |
1479 } | |
1480 } | |
1481 | |
1482 if (handov_cmd->v_freq_list_before) | |
1483 { | |
1484 | |
1485 /* Implements RR Clone findings #7 */ | |
1486 for_frequency_list (&handov_cmd->freq_list_before, | |
1487 &h_para->freq_list_before, | |
1488 &h_para->hop_list_before); | |
1489 | |
1490 | |
1491 } | |
1492 | |
1493 | |
1494 | |
1495 if (handov_cmd->v_freq_chan_seq_before) | |
1496 { | |
1497 /* | |
1498 * the message contains a frequency channel sequence element to | |
1499 * build the frequency hopping list. | |
1500 */ | |
1501 if (!for_create_delta_list ((T_freq_chan_seq_after *) | |
1502 &handov_cmd->freq_chan_seq_before, | |
1503 &h_para->hop_list_before)) | |
1504 { | |
1505 /* | |
1506 * set a content error if the frequency hopping list | |
1507 * contains channel numbers which are not supported. | |
1508 */ | |
1509 for_set_content_error (RRC_FREQ_NOT_IMPL); | |
1510 } | |
1511 } | |
1512 | |
1513 /* | |
1514 * handle the message, configure layer 1 etc. | |
1515 */ | |
1516 dat_for_handov_cmd (dl_data_ind, handov_cmd, &h_para->cell_chan_desc, | |
1517 &h_para->hop_list_after, &h_para->hop_list_before); | |
1518 /* | |
1519 * de-allocate the dynamic memory | |
1520 */ | |
1521 MFREE (h_para); | |
1522 } | |
1523 | |
1524 | |
1525 /* | |
1526 +--------------------------------------------------------------------+ | |
1527 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
1528 | STATE : code ROUTINE : for_create_channel_list | | |
1529 +--------------------------------------------------------------------+ | |
1530 | |
1531 PURPOSE : The function creates a frequency hopping list from one of | |
1532 the following information elements according GSM 4.08: | |
1533 | |
1534 cell channel description | |
1535 frequency list | |
1536 frequency short list | |
1537 neighbour cell description | |
1538 | |
1539 The format identifier of the information element is defined as: | |
1540 | |
1541 FORMAT-ID, Format Identifier | |
1542 | |
1543 Bit Bit Bit Bit Bit format notation | |
1544 8 7 4 3 2 | |
1545 | |
1546 0 0 X X X bit map 0 | |
1547 1 0 0 X X 1024 range | |
1548 1 0 1 0 0 512 range | |
1549 1 0 1 0 1 256 range | |
1550 1 0 1 1 0 128 range | |
1551 1 0 1 1 1 variable bit map | |
1552 | |
1553 */ | |
1554 | |
1555 GLOBAL void for_create_channel_list (T_f_range * cha_list_descr, | |
1556 T_LIST * cha_list) | |
1557 { | |
1558 /* | |
1559 * set a pointer to the begin of the array | |
1560 */ | |
1561 UBYTE *cha_ptr = &cha_list_descr-> | |
1562 b_f[cha_list_descr->o_f>>3]; | |
1563 | |
1564 TRACE_FUNCTION ("for_create_channel_list()"); | |
1565 | |
1566 /* | |
1567 * clear result list | |
1568 */ | |
1569 srv_clear_list (cha_list); | |
1570 | |
1571 if ((*cha_ptr & 0x80) EQ 0) | |
1572 { | |
1573 /* | |
1574 * Bitmap 0 format | |
1575 * only for GSM 900 or GSM 850 bands !!!! | |
1576 */ | |
1577 switch (std) | |
1578 { | |
1579 case STD_900: | |
1580 case STD_EGSM: | |
1581 case STD_DUAL: | |
1582 case STD_DUAL_EGSM: | |
1583 case STD_850: | |
1584 case STD_DUAL_US: | |
1585 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT | |
1586 case STD_850_1800: | |
1587 case STD_900_1900: | |
1588 case STD_850_900_1800: | |
1589 case STD_850_900_1900: | |
1590 #endif | |
1591 /* | |
1592 * clear the format identifier | |
1593 */ | |
1594 *cha_ptr = *cha_ptr & 0x0F; | |
1595 | |
1596 TRACE_EVENT_WIN ("bitmap 0 format"); | |
1597 /* | |
1598 * resulting list has bitmap 0 format ! | |
1599 * copy only the content of the GSM 900 or GSM 850 channels | |
1600 * equal to the first 16 byte. | |
1601 */ | |
1602 memcpy (&cha_list->channels[T_LIST_MAX_SIZE-16], cha_ptr, 16); | |
1603 break; | |
1604 | |
1605 default: | |
1606 /* | |
1607 * for PCS 1900 or DCS 1800 ignore the information element. | |
1608 */ | |
1609 break; | |
1610 } | |
1611 } | |
1612 else | |
1613 { | |
1614 if ((*cha_ptr &0x8E) EQ 0x8C) | |
1615 { | |
1616 | |
1617 /* Implements RR Clone findings #20 */ | |
1618 for_decode_param_freq(128,cha_list_descr,cha_list); | |
1619 | |
1620 } | |
1621 | |
1622 if ((*cha_ptr &0x8E) EQ 0x8A) | |
1623 { | |
1624 /* | |
1625 * RANGE 256 | |
1626 * | |
1627 * Use dynamic memory for calculation instead of global memory or stack. | |
1628 */ | |
1629 /* Implements RR Clone findings #20 */ | |
1630 for_decode_param_freq(256,cha_list_descr,cha_list); | |
1631 | |
1632 } | |
1633 | |
1634 if ((*cha_ptr &0x8E) EQ 0x88) | |
1635 { | |
1636 /* | |
1637 * RANGE 512 | |
1638 * | |
1639 * Use dynamic memory for calculation instead of global memory or stack. | |
1640 */ | |
1641 /* Implements RR Clone findings #21 */ | |
1642 for_decode_param_freq(512,cha_list_descr,cha_list); | |
1643 | |
1644 | |
1645 } | |
1646 | |
1647 if ((*cha_ptr &0x88) EQ 0x80) | |
1648 { | |
1649 /* | |
1650 * RANGE 1024 | |
1651 * | |
1652 * Use dynamic memory for calculation instead of global memory or stack. | |
1653 */ | |
1654 UBYTE f0; | |
1655 | |
1656 SHORT *w; | |
1657 MALLOC (w, 257 * sizeof (USHORT)); | |
1658 | |
1659 TRACE_EVENT_WIN ("range 1024 format"); | |
1660 | |
1661 /* | |
1662 * get the f0 indicator. It indicates whether channel 0 is part | |
1663 * of the frequency hopping list or not. | |
1664 */ | |
1665 ccd_decodeByte (cha_list_descr->b_f, | |
1666 (USHORT)(cha_list_descr->o_f+5), | |
1667 1, &f0); | |
1668 | |
1669 /* | |
1670 * decode the W-parameter | |
1671 */ | |
1672 for_decode_param_1024 (w, cha_list_descr); | |
1673 | |
1674 /* | |
1675 * If indicated add channel 0 to the list | |
1676 */ | |
1677 if (f0) | |
1678 srv_set_channel (cha_list, CHANNEL_0); | |
1679 | |
1680 /* | |
1681 * decode and set the remaining channel number according the | |
1682 * algorithm described in GSM 4.08. | |
1683 */ | |
1684 for_decode_frequencies (1023, &w[0], cha_list, 0); | |
1685 | |
1686 /* | |
1687 * free the dynamic allocated memory. | |
1688 */ | |
1689 MFREE (w); | |
1690 } | |
1691 | |
1692 if ((*cha_ptr &0x8E) EQ 0x8E) | |
1693 { | |
1694 /* | |
1695 * RANGE variable | |
1696 * | |
1697 * The format is similar to the bitmap 0 format. The | |
1698 * calculation starts from a base channel number svalue | |
1699 * instead of channel number 1. | |
1700 */ | |
1701 ULONG lvalue; | |
1702 USHORT svalue; | |
1703 UBYTE bvalue; | |
1704 USHORT i; | |
1705 | |
1706 TRACE_EVENT_WIN ("range variable format"); | |
1707 | |
1708 /* | |
1709 * get the first channel number | |
1710 */ | |
1711 ccd_decodeLong (cha_list_descr->b_f, 7, 10, &lvalue); | |
1712 | |
1713 /* | |
1714 * copy lvalue to svalue to set the correct channel | |
1715 */ | |
1716 svalue = (USHORT)lvalue; | |
1717 srv_set_channel (cha_list, svalue); | |
1718 | |
1719 for (i=1;i<112;i++) | |
1720 { | |
1721 /* | |
1722 * get the value of the next bit | |
1723 */ | |
1724 ccd_decodeByte (cha_list_descr->b_f,(USHORT)(i+16),1, &bvalue); | |
1725 | |
1726 if (bvalue) | |
1727 { | |
1728 /* | |
1729 * If the bit is set, set channel i+svalue | |
1730 */ | |
1731 srv_set_channel (cha_list, (USHORT)for_modulo(i+svalue, 1024)); | |
1732 } | |
1733 } | |
1734 } | |
1735 } | |
1736 } | |
1737 | |
1738 /* | |
1739 +--------------------------------------------------------------------+ | |
1740 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
1741 | STATE : code ROUTINE : for_create_delta_list | | |
1742 +--------------------------------------------------------------------+ | |
1743 | |
1744 PURPOSE : The function creates a frequency hopping list from the | |
1745 frequency channel sequence information element. This | |
1746 information element contains only GSM 900 channel numbers. | |
1747 | |
1748 The first channel number is stored in low_arfcn. The several | |
1749 increments are defined by the information element which are | |
1750 added to this starting frequency. | |
1751 | |
1752 */ | |
1753 | |
1754 static BOOL for_create_delta_list (T_freq_chan_seq_after *delta_list, | |
1755 T_LIST *cha_list) | |
1756 { | |
1757 USHORT i; | |
1758 UBYTE result = TRUE; | |
1759 USHORT delta; | |
1760 | |
1761 /* | |
1762 * set the first cannel number. | |
1763 */ | |
1764 USHORT cha_num = delta_list->low_arfcn; | |
1765 | |
1766 TRACE_FUNCTION ("for_create_delta_list()"); | |
1767 | |
1768 /* | |
1769 * Check whether it is a GSM 900 channel number | |
1770 */ | |
1771 if (cha_num < LOW_CHANNEL_900 OR | |
1772 cha_num > HIGH_CHANNEL_900) | |
1773 result = FALSE; | |
1774 | |
1775 /* | |
1776 * clear the output parameter for the calculated frequency hopping list. | |
1777 */ | |
1778 srv_clear_list (cha_list); | |
1779 | |
1780 /* | |
1781 * set the first channel number. | |
1782 */ | |
1783 srv_set_channel (cha_list, cha_num); | |
1784 | |
1785 /* | |
1786 * for the 16 possible increments | |
1787 */ | |
1788 for (i = 0; i < 16; i++) | |
1789 { | |
1790 /* | |
1791 * get the delta | |
1792 */ | |
1793 delta = (USHORT) delta_list->inc_skip[i]; | |
1794 | |
1795 /* | |
1796 * if delta is equal to 0, add 15 to the base, but | |
1797 * do not store in the output list. | |
1798 */ | |
1799 if (! delta) | |
1800 cha_num += 15; | |
1801 else | |
1802 { | |
1803 /* | |
1804 * add the delta to the base | |
1805 */ | |
1806 cha_num += delta; | |
1807 | |
1808 /* | |
1809 * Check whether it is a GSM 900 channel number | |
1810 */ | |
1811 if (cha_num < LOW_CHANNEL_900 OR | |
1812 cha_num > HIGH_CHANNEL_900) | |
1813 result = FALSE; | |
1814 | |
1815 /* | |
1816 * set the new frequency | |
1817 */ | |
1818 srv_set_channel (cha_list, cha_num); | |
1819 } | |
1820 } | |
1821 | |
1822 return result; | |
1823 } | |
1824 | |
1825 /* | |
1826 +--------------------------------------------------------------------+ | |
1827 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
1828 | STATE : code ROUTINE : for_decode_param_1024 | | |
1829 +--------------------------------------------------------------------+ | |
1830 | |
1831 PURPOSE : The W-parameter in the 1024 range start from bit 6 of the | |
1832 information element. The following table indicate the number | |
1833 of W-parameters and their length in bits. A length of zero | |
1834 indicated the end of the table. | |
1835 | |
1836 */ | |
1837 | |
1838 static const T_W_PARAM param_1024[9] = | |
1839 { | |
1840 /* | |
1841 * length count | |
1842 */ | |
1843 10, 1, | |
1844 9, 2, | |
1845 8, 4, | |
1846 7, 8, | |
1847 6, 16, | |
1848 5, 32, | |
1849 4, 64, | |
1850 3, 128, | |
1851 0, 0 | |
1852 }; | |
1853 | |
1854 | |
1855 static void for_decode_param_1024 (SHORT *w, | |
1856 T_f_range *cha) | |
1857 { | |
1858 TRACE_FUNCTION ("for_decode_param_1024"); | |
1859 | |
1860 /* | |
1861 * the algorithm for the several ranges is the same with different | |
1862 * tables. The W-parameter start with bit 6. | |
1863 */ | |
1864 for_decode_param (param_1024, w, cha, 6); | |
1865 } | |
1866 | |
1867 /* | |
1868 +--------------------------------------------------------------------+ | |
1869 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
1870 | STATE : code ROUTINE : for_decode_param_512 | | |
1871 +--------------------------------------------------------------------+ | |
1872 | |
1873 PURPOSE : The W-parameter in the 512 range start from bit 7 of the | |
1874 information element. The following table indicate the number | |
1875 of W-parameters and their length in bits. A length of zero | |
1876 indicated the end of the table. | |
1877 | |
1878 */ | |
1879 | |
1880 static const T_W_PARAM param_512[10] = | |
1881 { | |
1882 /* | |
1883 * length count | |
1884 */ | |
1885 10, 1, | |
1886 9, 1, | |
1887 8, 2, | |
1888 7, 4, | |
1889 6, 8, | |
1890 5, 16, | |
1891 4, 32, | |
1892 3, 64, | |
1893 2, 128, | |
1894 0, 0 | |
1895 }; | |
1896 | |
1897 | |
1898 /* | |
1899 +--------------------------------------------------------------------+ | |
1900 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
1901 | STATE : code ROUTINE : for_decode_param_256 | | |
1902 +--------------------------------------------------------------------+ | |
1903 | |
1904 PURPOSE : The W-parameter in the 256 range start from bit 7 of the | |
1905 information element. The following table indicate the number | |
1906 of W-parameters and their length in bits. A length of zero | |
1907 indicated the end of the table. | |
1908 | |
1909 */ | |
1910 | |
1911 static const T_W_PARAM param_256[10] = | |
1912 { | |
1913 /* | |
1914 * length count | |
1915 */ | |
1916 10, 1, | |
1917 8, 1, | |
1918 7, 2, | |
1919 6, 4, | |
1920 5, 8, | |
1921 4, 16, | |
1922 3, 32, | |
1923 2, 64, | |
1924 1, 128, | |
1925 0, 0 | |
1926 }; | |
1927 | |
1928 | |
1929 | |
1930 /* | |
1931 +--------------------------------------------------------------------+ | |
1932 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
1933 | STATE : code ROUTINE : for_decode_param_128 | | |
1934 +--------------------------------------------------------------------+ | |
1935 | |
1936 PURPOSE : The W-parameter in the 128 range start from bit 7 of the | |
1937 information element. The following table indicate the number | |
1938 of W-parameters and their length in bits. A length of zero | |
1939 indicated the end of the table. | |
1940 | |
1941 */ | |
1942 | |
1943 static const T_W_PARAM param_128[9] = | |
1944 { | |
1945 /* | |
1946 * length count | |
1947 */ | |
1948 10, 1, | |
1949 7, 1, | |
1950 6, 2, | |
1951 5, 4, | |
1952 4, 8, | |
1953 3, 16, | |
1954 2, 32, | |
1955 1, 64, | |
1956 0, 0 | |
1957 }; | |
1958 | |
1959 | |
1960 | |
1961 /* | |
1962 +--------------------------------------------------------------------+ | |
1963 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
1964 | STATE : code ROUTINE : for_decode_param | | |
1965 +--------------------------------------------------------------------+ | |
1966 | |
1967 PURPOSE : The information element contains a list of W-parameter. | |
1968 The table param indicates how many W-parameter from each | |
1969 length shall be inside. The function converts the bitstream | |
1970 of the W-parameter to an array of W-parameter 16 bit values. | |
1971 | |
1972 */ | |
1973 | |
1974 static void for_decode_param (const T_W_PARAM *param, | |
1975 SHORT *w, | |
1976 T_f_range *cha, | |
1977 USHORT initial_offset) | |
1978 { | |
1979 UBYTE end_detected = FALSE; | |
1980 USHORT w_index = 0; | |
1981 USHORT offset = cha->o_f + initial_offset; | |
1982 USHORT length = cha->l_f - initial_offset; | |
1983 USHORT act_length = param->length; | |
1984 USHORT act_counter = param->count; | |
1985 ULONG lvalue; | |
1986 UBYTE bvalue; | |
1987 | |
1988 TRACE_FUNCTION ("for_decode_param()"); | |
1989 | |
1990 /* | |
1991 * Until the end of the information element is detected. | |
1992 */ | |
1993 while (!end_detected) | |
1994 { | |
1995 if (act_length > 8) | |
1996 { | |
1997 /* | |
1998 * the length of the next W-parameter is greater than eight bits | |
1999 * so use the ccd_decodeLong function. | |
2000 */ | |
2001 ccd_decodeLong (cha->b_f, offset, act_length, &lvalue); | |
2002 w[w_index++] = (SHORT)lvalue; | |
2003 } | |
2004 else | |
2005 { | |
2006 /* | |
2007 * else use the ccd_decodeByte function to extract the W-parameter | |
2008 * from the bitstream. | |
2009 */ | |
2010 ccd_decodeByte (cha->b_f, offset, act_length, &bvalue); | |
2011 w[w_index++] = (SHORT)bvalue; | |
2012 } | |
2013 | |
2014 /* | |
2015 * w = 0 is equal to end of list if it is not the w(0) !!! | |
2016 */ | |
2017 if (w_index NEQ 1) | |
2018 if (w[w_index-1] EQ 0) | |
2019 end_detected = TRUE; | |
2020 | |
2021 /* | |
2022 * end of buffer is equal to end of list | |
2023 */ | |
2024 if (length > act_length) | |
2025 { | |
2026 length -= act_length; | |
2027 offset += act_length; | |
2028 } | |
2029 else | |
2030 end_detected = TRUE; | |
2031 | |
2032 /* | |
2033 * all w parameter of one size read | |
2034 */ | |
2035 if (--act_counter EQ 0) | |
2036 { | |
2037 param++; | |
2038 act_length = param->length; | |
2039 act_counter = param->count; | |
2040 } | |
2041 /* | |
2042 * End of parameter table | |
2043 */ | |
2044 if ((act_length EQ 0) OR (length < act_length)) | |
2045 end_detected = TRUE; | |
2046 } | |
2047 | |
2048 /* | |
2049 * add an end identifier | |
2050 */ | |
2051 w[w_index++] = 0; | |
2052 } | |
2053 | |
2054 | |
2055 /* | |
2056 +--------------------------------------------------------------------+ | |
2057 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
2058 | STATE : code ROUTINE : for_decode_frequencies | | |
2059 +--------------------------------------------------------------------+ | |
2060 | |
2061 PURPOSE : The algorithm is according GSM 4.08 Annex J. It calculates | |
2062 a frequency hopping list from the W-parameter. | |
2063 | |
2064 */ | |
2065 | |
2066 static void for_decode_frequencies (SHORT original_range, | |
2067 SHORT *w, | |
2068 T_LIST *f, | |
2069 SHORT offset) | |
2070 { | |
2071 SHORT g; | |
2072 SHORT k; | |
2073 SHORT j; | |
2074 SHORT index; | |
2075 SHORT n; | |
2076 SHORT range; | |
2077 | |
2078 TRACE_FUNCTION ("for_decode_frequencies()"); | |
2079 | |
2080 for (k = 1; w[k-1]; k++) | |
2081 { | |
2082 /* | |
2083 * The next loop follows the tree from child to parent, | |
2084 * from the node of index K to the root (index 1). For each iteration the | |
2085 * node of index INDEX is tackled. The corresponding range is RANGE, and N | |
2086 * is the value of the element in the range defined by the node. | |
2087 * | |
2088 * The data are set to their initial values | |
2089 */ | |
2090 index = k; | |
2091 n = w[index-1]; | |
2092 g = for_get_generation (index); | |
2093 j = (1 << (g-1)); | |
2094 range = original_range / j; | |
2095 | |
2096 while (index > 1) | |
2097 { | |
2098 /* | |
2099 * Due to the assumption that the original range is a power of two minus one, | |
2100 * the range for the parent node can be easily computed, and does not depend | |
2101 * upon whether the current node is a left or right child | |
2102 */ | |
2103 g = for_get_generation (index); | |
2104 j = (1 << (g-1)); | |
2105 range = 2 * range + 1; | |
2106 | |
2107 /* | |
2108 * Let us note J := 2 g-1 , g being the generation of node INDEX. We have J = | |
2109 * GREATEST_POWER_OF_2_LESSER_OR_EQUAL_TO(INDEX). The numbering used in the tree | |
2110 * is such that the nodes of index J to J + J/2 - 1 are left children, and the nodes | |
2111 * of index J/2 to J+J-1 are right children. Hence an easy test to | |
2112 * distinguish left and right children: | |
2113 */ | |
2114 if (2 * index < 3 * j) | |
2115 { | |
2116 /* | |
2117 * The next computation gives the index of the parent node of the node of index | |
2118 * INDEX, for a left child : | |
2119 */ | |
2120 index = index - j / 2; | |
2121 | |
2122 /* | |
2123 * The next formula is the inverse of the renumbering appearing in the encoding | |
2124 * for a left child. It gives the value of the parent node in the range defined | |
2125 * by the grand-parent node: | |
2126 */ | |
2127 n = (SHORT)for_smodulo (n + w[index-1] + (range-1) / 2, range); | |
2128 } | |
2129 else | |
2130 { | |
2131 /* | |
2132 * The next computation gives the index of the parent node of the node of index | |
2133 * INDEX, for a right child : | |
2134 */ | |
2135 index = index - j; | |
2136 | |
2137 /* | |
2138 * The next formula is the inverse of the renumbering appearing in the encoding | |
2139 * for a right child: | |
2140 */ | |
2141 n = (SHORT)for_smodulo (n + w[index-1], range); | |
2142 } | |
2143 } | |
2144 | |
2145 /* | |
2146 * set the calculated channel number. | |
2147 */ | |
2148 srv_set_channel (f, (USHORT)for_modulo (n+offset, 1024)); | |
2149 } | |
2150 } | |
2151 | |
2152 | |
2153 /* | |
2154 +--------------------------------------------------------------------+ | |
2155 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
2156 | STATE : code ROUTINE : for_get_generation | | |
2157 +--------------------------------------------------------------------+ | |
2158 | |
2159 PURPOSE : The function calculates the greatest power of 2 of the given | |
2160 value. The algorithm simply looks to the position of the | |
2161 highest bit. | |
2162 | |
2163 */ | |
2164 | |
2165 static USHORT for_get_generation (USHORT value) | |
2166 { | |
2167 int result = 0; | |
2168 int i; | |
2169 | |
2170 | |
2171 /* | |
2172 * check all 16 bit positions. | |
2173 */ | |
2174 for (i = 0; i < 16; i++) | |
2175 { | |
2176 /* | |
2177 * if bit is set, store the position. | |
2178 */ | |
2179 if (value & 1) | |
2180 result = i + 1; | |
2181 | |
2182 /* | |
2183 * shift value to have the next bit for | |
2184 * comparision. | |
2185 */ | |
2186 value = value >> 1; | |
2187 } | |
2188 | |
2189 /* | |
2190 * return the highest position. | |
2191 */ | |
2192 return result; | |
2193 } | |
2194 | |
2195 /* | |
2196 +--------------------------------------------------------------------+ | |
2197 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
2198 | STATE : code ROUTINE : for_modulo | | |
2199 +--------------------------------------------------------------------+ | |
2200 | |
2201 PURPOSE : A modulo calculation function. The standard C-Operator | |
2202 fails for negative values ! (e.g. -4 mod 6 is 2 and not 4). | |
2203 | |
2204 */ | |
2205 | |
2206 static LONG for_modulo (LONG a, LONG b) | |
2207 { | |
2208 long result; | |
2209 | |
2210 /* | |
2211 * use standard C-Operator for calculation | |
2212 */ | |
2213 result = a % b; | |
2214 | |
2215 /* | |
2216 * correct the result for negative values. | |
2217 */ | |
2218 if (result < 0) | |
2219 result += b; | |
2220 | |
2221 return result; | |
2222 } | |
2223 | |
2224 /* | |
2225 +--------------------------------------------------------------------+ | |
2226 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
2227 | STATE : code ROUTINE : for_smodulo | | |
2228 +--------------------------------------------------------------------+ | |
2229 | |
2230 PURPOSE : Similar to the modulo operator, but 0 smod n is n and | |
2231 not 0. Same problem for negative values with the standard | |
2232 C-Operator. | |
2233 | |
2234 */ | |
2235 | |
2236 static LONG for_smodulo (LONG a, LONG b) | |
2237 { | |
2238 long result; | |
2239 | |
2240 /* | |
2241 * use standard C-Operator for calculation | |
2242 */ | |
2243 result = a % b; | |
2244 | |
2245 /* | |
2246 * correct the result for negative values. | |
2247 */ | |
2248 if (result < 0) | |
2249 result += b; | |
2250 | |
2251 /* | |
2252 * special handling for result equal 0 | |
2253 */ | |
2254 if (result EQ 0) | |
2255 result = b; | |
2256 | |
2257 return result; | |
2258 } | |
2259 | |
2260 /* | |
2261 +--------------------------------------------------------------------+ | |
2262 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
2263 | STATE : code ROUTINE : for_set_conditional_error | | |
2264 +--------------------------------------------------------------------+ | |
2265 | |
2266 PURPOSE : set a conditional error. | |
2267 | |
2268 */ | |
2269 | |
2270 static void for_set_conditional_error (void) | |
2271 { | |
2272 GET_INSTANCE_DATA; | |
2273 TRACE_FUNCTION ("for_set_conditional_error()"); | |
2274 | |
2275 switch (rr_data->ms_data.error.cs) | |
2276 { | |
2277 /* case RRC_INVALID_MAN_INFO: this value is currently never set */ | |
2278 case RRC_INCORRECT_MSG: | |
2279 break; | |
2280 | |
2281 default: | |
2282 /* | |
2283 * set the conditional information element error. | |
2284 */ | |
2285 rr_data->ms_data.error.cs = RRC_COND_IE_ERROR; | |
2286 break; | |
2287 } | |
2288 } | |
2289 | |
2290 /* | |
2291 +--------------------------------------------------------------------+ | |
2292 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
2293 | STATE : code ROUTINE : for_set_content_error | | |
2294 +--------------------------------------------------------------------+ | |
2295 | |
2296 PURPOSE : set a content error. | |
2297 | |
2298 */ | |
2299 | |
2300 GLOBAL void for_set_content_error (UBYTE value) | |
2301 { | |
2302 GET_INSTANCE_DATA; | |
2303 TRACE_FUNCTION ("for_set_content_error()"); | |
2304 | |
2305 switch (rr_data->ms_data.error.cs) | |
2306 { | |
2307 /* case RRC_INVALID_MAN_INFO: this value is currently never set */ | |
2308 case RRC_COND_IE_ERROR: | |
2309 case RRC_INCORRECT_MSG: | |
2310 /* | |
2311 * Ignore a content error, if already an error with higher | |
2312 * priority has been detected. | |
2313 */ | |
2314 break; | |
2315 | |
2316 default: | |
2317 /* | |
2318 * store the content error. | |
2319 */ | |
2320 rr_data->ms_data.error.cs = RRC_INCORRECT_MSG; | |
2321 rr_data->ms_data.error.val = value; | |
2322 break; | |
2323 } | |
2324 } | |
2325 | |
2326 /* | |
2327 +--------------------------------------------------------------------+ | |
2328 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
2329 | STATE : code ROUTINE : for_suspend_layer_2 | | |
2330 +--------------------------------------------------------------------+ | |
2331 | |
2332 PURPOSE : suspend layer 2 in case of assignment or handover command. | |
2333 | |
2334 */ | |
2335 | |
2336 GLOBAL void for_suspend_layer_2 (void) | |
2337 { | |
2338 GET_INSTANCE_DATA; | |
2339 PALLOC (dl_suspend_req, DL_SUSPEND_REQ); | |
2340 | |
2341 TRACE_FUNCTION ("for_suspend_layer_2()"); | |
2342 | |
2343 /* | |
2344 * set channel type and SAPI for layer 2. | |
2345 */ | |
2346 dat_code_prr_channel (&dl_suspend_req->ch_type, | |
2347 &dl_suspend_req->sapi, | |
2348 rr_data->sc_data.chan_desc.chan_type); | |
2349 | |
2350 PSENDX (DL, dl_suspend_req); | |
2351 } | |
2352 | |
2353 | |
2354 /* | |
2355 +--------------------------------------------------------------------+ | |
2356 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
2357 | STATE : code ROUTINE : for_frequency_list | | |
2358 +--------------------------------------------------------------------+ | |
2359 | |
2360 PURPOSE : This function creates a frequency list and channel list | |
2361 | |
2362 */ | |
2363 LOCAL void for_frequency_list(T_freq_list *freq_list_starting_time_cmd, | |
2364 T_f_range *freq_list_starting_time_para, | |
2365 T_LIST *hop_list_starting_time) | |
2366 { | |
2367 TRACE_FUNCTION("for_frequency_list()"); | |
2368 | |
2369 memset (freq_list_starting_time_para, 0, sizeof (T_f_range)); | |
2370 memcpy (freq_list_starting_time_para->b_f, | |
2371 freq_list_starting_time_cmd->flist, | |
2372 freq_list_starting_time_cmd->c_flist); | |
2373 freq_list_starting_time_para->l_f = 8*freq_list_starting_time_cmd->c_flist; | |
2374 | |
2375 /* | |
2376 * create a frequency list. | |
2377 */ | |
2378 for_create_channel_list (freq_list_starting_time_para, hop_list_starting_time); | |
2379 | |
2380 /* check if all frequencies are in one band */ | |
2381 if(! srv_check_frequencies_in_list (hop_list_starting_time)) | |
2382 { | |
2383 for_set_content_error(RRC_FREQ_NOT_IMPL); | |
2384 } | |
2385 } | |
2386 | |
2387 /* | |
2388 +--------------------------------------------------------------------+ | |
2389 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
2390 | STATE : code ROUTINE : for_decode_param_freq | | |
2391 +--------------------------------------------------------------------+ | |
2392 | |
2393 PURPOSE : This function decodes the frequency parameter from the channel | |
2394 description IE | |
2395 | |
2396 */ | |
2397 LOCAL void for_decode_param_freq(USHORT range ,T_f_range *cha_list_descr, | |
2398 T_LIST *cha_list) | |
2399 { | |
2400 SHORT *w; | |
2401 SHORT size_mul; | |
2402 const T_W_PARAM *param_ptr; | |
2403 | |
2404 TRACE_FUNCTION("for_decode_param_freq()"); | |
2405 /* | |
2406 * RANGE 128/256/512 | |
2407 * | |
2408 * Use dynamic memory for calculation instead of global memory or stack. | |
2409 */ | |
2410 switch(range) | |
2411 { | |
2412 case 128: | |
2413 TRACE_EVENT_WIN ("range 128 format"); | |
2414 size_mul = 129; | |
2415 param_ptr = param_128; | |
2416 | |
2417 break; | |
2418 case 256: | |
2419 TRACE_EVENT_WIN ("range 256 format"); | |
2420 size_mul = 257; | |
2421 param_ptr = param_256; | |
2422 break; | |
2423 case 512: | |
2424 TRACE_EVENT_WIN ("range 512 format"); | |
2425 size_mul = 257; | |
2426 param_ptr = param_512; | |
2427 break; | |
2428 default: | |
2429 size_mul = 0; | |
2430 param_ptr = NULL; | |
2431 break; | |
2432 } | |
2433 | |
2434 MALLOC (w, size_mul * sizeof (USHORT)); | |
2435 for_decode_param (param_ptr, w, cha_list_descr, 7); | |
2436 | |
2437 /* | |
2438 * W[0] contains the first channel number | |
2439 */ | |
2440 srv_set_channel (cha_list, w[0]); | |
2441 | |
2442 /* | |
2443 * decode and set the remaining channel number according the | |
2444 * algorithm described in GSM 4.08. | |
2445 */ | |
2446 for_decode_frequencies ((range -1), &w[1], cha_list, w[0]); | |
2447 | |
2448 /* | |
2449 * free the dynamic allocated memory. | |
2450 */ | |
2451 MFREE (w); | |
2452 } | |
2453 | |
2454 #if defined (REL99) && defined (TI_PS_FF_EMR) | |
2455 /*[xgiridha] : EMR */ | |
2456 /* | |
2457 +------------------------------------------------------------------------------ | |
2458 | Function : for_process_si2quater | |
2459 +------------------------------------------------------------------------------ | |
2460 | Description : Process SI-2quater information and store it in enh_para of serving cell | |
2461 | This is a multi instance message. check whether all the instances are | |
2462 | received or not before indicating to ALR and to GRR,if required. | |
2463 | | |
2464 | Parameters : SI-2quater rest octets | |
2465 | | |
2466 +------------------------------------------------------------------------------ | |
2467 */ | |
2468 GLOBAL BOOL for_process_si2quater(T_si_2qua_octets *p_si2q) | |
2469 { | |
2470 GET_INSTANCE_DATA; | |
2471 T_rr_enh_para *p_cur = &rr_data->sc_data.emr_data_current; | |
2472 T_rr_enh_para *p_temp = &rr_data->sc_data.emr_data_temp; | |
2473 BOOL send_enh_para = FALSE; | |
2474 T_gprs_rep_prio *p_rep = NULL; | |
2475 T_gprs_bsic *p_bsic = NULL; | |
2476 | |
2477 #if defined (TI_PS_FF_RTD) AND defined (REL99) | |
2478 UBYTE i,j; | |
2479 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */ | |
2480 | |
2481 | |
2482 TRACE_FUNCTION ("for_process_si2quater"); | |
2483 | |
2484 /* Step 1: Check if we received right BA_IND */ | |
2485 if((rr_data->sc_data.ba_index NEQ NOT_PRESENT_8BIT) AND (p_si2q->ba_ind NEQ rr_data->sc_data.ba_index )) | |
2486 { | |
2487 /* re-read si2qtr*/ | |
2488 | |
2489 if(rr_data->sc_data.cd.si2quater_status EQ SI2QUATER_ABSENT OR | |
2490 rr_data->sc_data.cd.si2quater_status EQ SI2QUATER_ACQ_PENDING) | |
2491 { | |
2492 TRACE_EVENT("This is not the right BA_IND set that we have. So,ignore this SI-2quater"); | |
2493 rr_data->sc_data.cd.si2quater_status = SI2QUATER_ACQ_WRONG_BAIND; | |
2494 { | |
2495 PALLOC(mph_mon_ctrl_req, MPH_MON_CTRL_REQ ); | |
2496 mph_mon_ctrl_req->action = STOP_MON_BCCH; | |
2497 mph_mon_ctrl_req->si_to_read = UPDATE_SI2QUATER_AGAIN; | |
2498 PSENDX (PL, mph_mon_ctrl_req); | |
2499 } | |
2500 } | |
2501 else | |
2502 { | |
2503 TRACE_EVENT("This is not the right BA_IND set that we have.Re-read SI-2quater"); | |
2504 rr_data->sc_data.cd.si2quater_status = SI2QUATER_ACQ_PENDING; | |
2505 { | |
2506 PALLOC(mph_mon_ctrl_req, MPH_MON_CTRL_REQ ); | |
2507 if ( rr_data->sc_data.cd.si2quater_pos EQ SI2QUATER_ON_EBCCH ) | |
2508 { | |
2509 mph_mon_ctrl_req->action = START_MON_EBCCH; | |
2510 } | |
2511 else | |
2512 { | |
2513 mph_mon_ctrl_req->action = START_MON_NBCCH; | |
2514 } | |
2515 mph_mon_ctrl_req->si_to_read = UPDATE_SI2QUATER_AGAIN; | |
2516 PSENDX (PL, mph_mon_ctrl_req); | |
2517 } | |
2518 } | |
2519 return send_enh_para; | |
2520 } | |
2521 | |
2522 /* Step 2: Check report type. | |
2523 IMPORTANT ASSUMPTION: We process only NC PARA (if present) if report type is Normal*/ | |
2524 if( !(( (p_si2q->v_gprs_meas_para EQ TRUE) AND (p_si2q->gprs_meas_para.report_type EQ ENHANCED_MEAS)) OR | |
2525 ( (p_si2q->v_meas_para EQ TRUE) AND (p_si2q->meas_para.report_type EQ ENHANCED_MEAS )) ) ) | |
2526 { | |
2527 /*check whether there are enhanced parameters and BA list already. | |
2528 If present then it means that report type is changing from | |
2529 Enhanced to Normal*/ | |
2530 if ( p_cur->is_data_valid EQ TRUE ) | |
2531 { | |
2532 for_set_default_emr_data(p_cur); | |
2533 #ifdef GPRS | |
2534 if (p_si2q->v_nc_meas_para EQ TRUE) | |
2535 for_store_nc_para(&p_si2q->nc_meas_para, p_cur); | |
2536 #endif | |
2537 return TRUE; /*send enh para update to indicate change in report type and NC para*/ | |
2538 } | |
2539 else | |
2540 return send_enh_para; | |
2541 } | |
2542 | |
2543 /* Step 3: Check if we already have enh_para in current or temp | |
2544 and if there is change in parameters or continuation of reception*/ | |
2545 if(p_temp->is_data_valid EQ FALSE ) | |
2546 { | |
2547 /*This means we were not in the process of receiving. Check whether there | |
2548 is already information in current and if so, is there change in mp_change_mark*/ | |
2549 if( (p_cur->mp_change_mark NEQ NOT_PRESENT_8BIT) AND | |
2550 (p_cur->mp_change_mark EQ p_si2q->mp_change_mark ) ) | |
2551 { | |
2552 TRACE_EVENT("No change in Enhanced measurement parameters -ignore "); | |
2553 return TRUE; | |
2554 } | |
2555 /* decode rest of the parameters*/ | |
2556 p_temp->is_data_valid = TRUE; | |
2557 rr_data->sc_data.enh_para_status = ENH_PARA_INVALID_STATE; | |
2558 p_temp->enh_para.ncc_permitted = rr_data->sc_data.cd.ncc_permitted; | |
2559 rr_data->sc_data.ba_index = p_si2q->ba_ind; | |
2560 } | |
2561 /*Note :If different values occur for the same parameter in different instances of a message, | |
2562 the instance with the highest index shall be used (sec.3.4.1.2.1, 4.18)*/ | |
2563 if ( (p_si2q->si2qua_index > rr_data->sc_data.prev_highest_index ) OR | |
2564 (rr_data->sc_data.prev_highest_index EQ NOT_PRESENT_8BIT) ) | |
2565 { | |
2566 p_temp->mp_change_mark = p_si2q->mp_change_mark; | |
2567 p_temp->msg_count = p_si2q->si2qua_count; | |
2568 for_update_emr_rep_para(p_si2q,p_temp); /* This is updation of parameters other than BSIC list*/ | |
2569 rr_data->sc_data.prev_highest_index = p_si2q->si2qua_index; | |
2570 #if defined (TI_PS_FF_RTD) AND defined (REL99) | |
2571 if(p_si2q->v_rtdd) | |
2572 for_store_rtd_data(p_si2q,p_temp); | |
2573 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */ | |
2574 | |
2575 } | |
2576 | |
2577 if(p_si2q->v_gprs_rep_prio EQ TRUE) | |
2578 p_rep = &p_si2q->gprs_rep_prio; | |
2579 | |
2580 if(p_si2q->v_gprs_bsic EQ TRUE) | |
2581 p_bsic = &p_si2q->gprs_bsic; | |
2582 | |
2583 if (for_process_common_emr_data(p_rep,p_bsic,p_si2q->si2qua_index, | |
2584 rr_data->sc_data.ba_list_idle) ) | |
2585 { | |
2586 rr_data->sc_data.enh_para_status = ENH_PARA_IDLE; | |
2587 #if defined (TI_PS_FF_RTD) AND defined (REL99) | |
2588 /* store the RTD values received in all instances of SI2quater in permanent location */ | |
2589 if(p_si2q->v_rtdd) | |
2590 { | |
2591 memcpy(p_cur,p_temp,MAX_NR_OF_NCELL*sizeof(USHORT)); | |
2592 /* reset the temporary storage to RTD value not available */ | |
2593 for(j = 0;j < MAX_NR_OF_NCELL; j++ ) | |
2594 { | |
2595 p_temp->enh_para.enh_cell_list[j].v_rtd = FALSE; | |
2596 for(i = 0;i < MAX_NUM_OF_RTD_VALUES; i++) | |
2597 p_temp->enh_para.enh_cell_list[j].rtd[i]= RTD_NOT_AVAILABLE; | |
2598 }/*for*/ | |
2599 }/*if*/ | |
2600 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */ | |
2601 | |
2602 if ( rr_data->sc_data.ba_list_idle EQ TRUE) | |
2603 send_enh_para = TRUE; | |
2604 } | |
2605 return send_enh_para; | |
2606 } | |
2607 | |
2608 /* | |
2609 +------------------------------------------------------------------------------ | |
2610 | Function : for_update_emr_rep_para | |
2611 +------------------------------------------------------------------------------ | |
2612 | Description : This function updates all the miscelaneous parameters related | |
2613 | to enhanced measurements. This doesn't include BSIC and Report priority | |
2614 | list. | |
2615 | Parameters : SI-2quater rest octets, target location where to store data | |
2616 +------------------------------------------------------------------------------ | |
2617 */ | |
2618 GLOBAL void for_update_emr_rep_para(T_si_2qua_octets *p_si2q,T_rr_enh_para *p_em) | |
2619 { | |
2620 #ifdef GPRS | |
2621 UBYTE state; | |
2622 GET_INSTANCE_DATA; | |
2623 #endif | |
2624 /*Decide whether to use GPRS part of measurement parameters or RR part*/ | |
2625 TRACE_FUNCTION ("for_update_emr_rep_para"); | |
2626 | |
2627 #ifdef GPRS | |
2628 state = GET_STATE(STATE_GPRS); | |
2629 if( (state EQ GPRS_PIM_BCCH) OR (state EQ GPRS_PAM_BCCH) OR | |
2630 (state EQ GPRS_PTM_BCCH)) | |
2631 { | |
2632 /*Use GPRS part*/ | |
2633 if(p_si2q->v_gprs_meas_para EQ TRUE ) | |
2634 { | |
2635 p_em->grr_rep_type = p_si2q->gprs_meas_para.report_type; | |
2636 p_em->enh_para.inv_bsic_enabled = p_si2q->gprs_meas_para.inv_bsic_rep; | |
2637 if ( p_si2q->gprs_meas_para.v_serv_band_rep EQ TRUE) | |
2638 p_em->enh_para.servingband_rep = p_si2q->gprs_meas_para.serv_band_rep; | |
2639 if( p_si2q->gprs_meas_para.v_mr EQ TRUE ) | |
2640 p_em->enh_para.multiband_rep = p_si2q->gprs_meas_para.mr; | |
2641 p_em->enh_para.scale_order = p_si2q->gprs_meas_para.scale_ord; | |
2642 p_em->enh_para.rep_rate = p_si2q->gprs_meas_para.reporting_rate; | |
2643 | |
2644 /* Update reporting thresholds and reporting offsets*/ | |
2645 if (p_si2q->gprs_meas_para.v_report_900 EQ TRUE) | |
2646 { | |
2647 p_em->enh_para.enh_rep_data[0].rep_offset = | |
2648 p_si2q->gprs_meas_para.report_900.rep_offset_900; | |
2649 p_em->enh_para.enh_rep_data[0].rep_offset = | |
2650 p_si2q->gprs_meas_para.report_900.th_rep_900; | |
2651 } | |
2652 if (p_si2q->gprs_meas_para.v_report_1800 EQ TRUE) | |
2653 { | |
2654 p_em->enh_para.enh_rep_data[1].rep_offset = | |
2655 p_si2q->gprs_meas_para.report_1800.rep_offset_1800; | |
2656 p_em->enh_para.enh_rep_data[1].rep_offset = | |
2657 p_si2q->gprs_meas_para.report_1800.th_rep_1800; | |
2658 } | |
2659 if (p_si2q->gprs_meas_para.v_report_400 EQ TRUE) | |
2660 { | |
2661 p_em->enh_para.enh_rep_data[2].rep_offset = | |
2662 p_si2q->gprs_meas_para.report_400.rep_offset_400; | |
2663 p_em->enh_para.enh_rep_data[2].rep_offset = | |
2664 p_si2q->gprs_meas_para.report_400.th_rep_400; | |
2665 } | |
2666 if (p_si2q->gprs_meas_para.v_report_1900 EQ TRUE) | |
2667 { | |
2668 p_em->enh_para.enh_rep_data[3].rep_offset = | |
2669 p_si2q->gprs_meas_para.report_1900.rep_offset_1900; | |
2670 p_em->enh_para.enh_rep_data[3].rep_offset = | |
2671 p_si2q->gprs_meas_para.report_1900.th_rep_1900; | |
2672 } | |
2673 if (p_si2q->gprs_meas_para.v_report_850 EQ TRUE) | |
2674 { | |
2675 p_em->enh_para.enh_rep_data[4].rep_offset = | |
2676 p_si2q->gprs_meas_para.report_850.rep_offset_850; | |
2677 p_em->enh_para.enh_rep_data[4].rep_offset = | |
2678 p_si2q->gprs_meas_para.report_850.th_rep_850; | |
2679 } | |
2680 } | |
2681 /*Update Network Control (NC) parameters */ | |
2682 if (p_si2q->v_nc_meas_para EQ TRUE ) | |
2683 for_store_nc_para(&p_si2q->nc_meas_para,p_em); | |
2684 } | |
2685 else | |
2686 { | |
2687 #endif | |
2688 /* Use RR part */ | |
2689 if(p_si2q->v_meas_para EQ TRUE ) | |
2690 { | |
2691 p_em->rep_type = p_si2q->meas_para.report_type; | |
2692 p_em->enh_para.servingband_rep = p_si2q->meas_para.serv_band_rep; | |
2693 } | |
2694 #ifdef GPRS | |
2695 } | |
2696 #endif | |
2697 return; | |
2698 } | |
2699 | |
2700 #ifdef GPRS | |
2701 static void for_store_nc_para(T_nc_meas_para *p_nc,T_rr_enh_para *p_em) | |
2702 { | |
2703 TRACE_FUNCTION ("for_store_nc_para"); | |
2704 p_em->nc_para.nco = p_nc->nco; | |
2705 if(p_nc->v_nc_meas_struct EQ TRUE ) | |
2706 { | |
2707 p_em->nc_para.is_valid = TRUE; | |
2708 p_em->nc_para.nc_non_drx = p_nc->nc_meas_struct.nc_non_drx; | |
2709 p_em->nc_para.nc_rep_per_i = p_nc->nc_meas_struct.nc_rep_i; | |
2710 p_em->nc_para.nc_rep_per_t = p_nc->nc_meas_struct.nc_rep_t; | |
2711 } | |
2712 return; | |
2713 } | |
2714 #endif | |
2715 | |
2716 /* | |
2717 +------------------------------------------------------------------------------ | |
2718 | Function : for_set_default_emr_data | |
2719 +------------------------------------------------------------------------------ | |
2720 | Description : This function performs the default intialization of emr data | |
2721 | Parameters : target location where to initialize | |
2722 +------------------------------------------------------------------------------ | |
2723 */ | |
2724 GLOBAL void for_set_default_emr_data(T_rr_enh_para *p_em) | |
2725 { | |
2726 GET_INSTANCE_DATA; | |
2727 UBYTE i; | |
2728 | |
2729 TRACE_FUNCTION ("for_set_default_emr_data"); | |
2730 | |
2731 memset(p_em, 0, sizeof(T_rr_enh_para)); | |
2732 /*But there are some parameters whose default value is not 0, so we | |
2733 need to set them explicitly*/ | |
2734 p_em->grr_rep_type = p_em->rep_type = NORMAL_MEAS; /*Default*/ | |
2735 | |
2736 #ifdef GPRS | |
2737 p_em->nc_para.nco = NCO_EMPTY; /*If GRR receives this value, it should not use | |
2738 entire nc parameters*/ | |
2739 p_em->nc_para.is_valid = TRUE; | |
2740 p_em->nc_para.nc_non_drx = NC_0_48S; | |
2741 p_em->nc_para.nc_rep_per_i = NC_I_3_84S; /*see rr.aim for details*/ | |
2742 p_em->nc_para.nc_rep_per_t = NC_I_61_44S; | |
2743 #endif | |
2744 | |
2745 p_em->enh_para.scale_order = SCALE_0dB; | |
2746 p_em->enh_para.inv_bsic_enabled = FALSE; | |
2747 p_em->enh_para.rep_rate = NORMAL_RATE; | |
2748 p_em->enh_para.servingband_rep = DEFAULT_SERV_BAND_REP; /*Default value (3) */ | |
2749 p_em->mp_change_mark = NOT_PRESENT_8BIT; | |
2750 | |
2751 /* Default initialization of Reporting thresholds and offsets */ | |
2752 for ( i=0; i<MAX_NUM_BANDS; i++) | |
2753 { | |
2754 p_em->enh_para.enh_rep_data[i].rep_threshold = REP_THRESHOLD_NONE; | |
2755 p_em->enh_para.enh_rep_data[i].rep_offset = REP_OFFSET_0; | |
2756 } | |
2757 rr_data->sc_data.rep_bmp = 0; | |
2758 rr_data->sc_data.instance_bmp = 0; | |
2759 rr_data->sc_data.prev_highest_index = NOT_PRESENT_8BIT; | |
2760 memset(rr_data->sc_data.bsic_list,0,MAX_MULTI_INST * sizeof(T_bsic_list)); | |
2761 return; | |
2762 } | |
2763 | |
2764 /* | |
2765 +------------------------------------------------------------------------------ | |
2766 | Function : for_send_enh_para | |
2767 +------------------------------------------------------------------------------ | |
2768 | Description : This function calls the functions needed to send ENH PARA to GRR | |
2769 | and ALR, under suitable conditions. | |
2770 | Parameters : enh para structure of RR | |
2771 +------------------------------------------------------------------------------ | |
2772 */ | |
2773 GLOBAL void for_send_enh_para(T_rr_enh_para *p_src) | |
2774 { | |
2775 UBYTE rep_type = p_src->rep_type; | |
2776 #ifdef GPRS | |
2777 GET_INSTANCE_DATA; | |
2778 #endif | |
2779 TRACE_FUNCTION ("for_send_enh_para"); | |
2780 /* GRR is updated only in PIM/PAM/PTM when PBCCH is absent | |
2781 ALR is updated always with enhanced measurement parameters, | |
2782 it can be decided in ALR whether to use this information while | |
2783 sending report depending on report type*/ | |
2784 | |
2785 #ifdef GPRS | |
2786 { | |
2787 UBYTE state; | |
2788 state = GET_STATE(STATE_GPRS); | |
2789 if( (state EQ GPRS_PIM_BCCH) OR (state EQ GPRS_PAM_BCCH) OR | |
2790 (state EQ GPRS_PTM_BCCH)) | |
2791 { | |
2792 att_send_enh_para_to_grr(p_src); | |
2793 if (p_src->grr_rep_type EQ REP_TYPE_ENH) | |
2794 rep_type = REP_TYPE_ENH; | |
2795 } | |
2796 } | |
2797 #endif | |
2798 attf_send_enh_para_to_alr(rep_type,&p_src->enh_para); | |
2799 return; | |
2800 } | |
2801 | |
2802 /* | |
2803 +------------------------------------------------------------------------------ | |
2804 | Function : for_perform_ba_bsic_mapping | |
2805 +------------------------------------------------------------------------------ | |
2806 | Description : This function performs the BA list to BSIC list mapping, by taking BSIC list from | |
2807 | each instance of SI-2quater/MI-message and BA list. Here we store only the index into | |
2808 | BA list for ARFCN. | |
2809 | Parameters : Input: | |
2810 | BSIC list from air message | |
2811 | Output: | |
2812 | Update Enhanced cell list with BA indices. | |
2813 +------------------------------------------------------------------------------ | |
2814 */ | |
2815 LOCAL void for_perform_ba_bsic_mapping(T_gprs_bsic *p_bsic, T_enh_para_struct *p_enh ) | |
2816 { | |
2817 UBYTE i=0; | |
2818 UBYTE j; | |
2819 UBYTE k=0; | |
2820 | |
2821 TRACE_FUNCTION ("for_perform_ba_bsic_mapping"); | |
2822 j = p_enh->num_valid_cells; /*If some cells were already filled from a previous instance, | |
2823 then this would be non-zero. We have to start updating this enhanced list from here*/ | |
2824 if ( j >= MAX_NEIGHBOURCELLS ) | |
2825 return; /* we cannot store any more neighbour cells, we only support GSM cells*/ | |
2826 | |
2827 if (p_bsic->v_ba_start_bsic EQ TRUE ) | |
2828 i = p_bsic->ba_start_bsic; | |
2829 else | |
2830 i = 0; | |
2831 | |
2832 /* Note : here we only store indices of ARFCNs*/ | |
2833 /* Update from first BSIC, which is given outside the recursive structure*/ | |
2834 p_enh->enh_cell_list[j].arfcn = i; | |
2835 p_enh->enh_cell_list[j].bsic = p_bsic->bsic; | |
2836 j++; | |
2837 | |
2838 k = 0; | |
2839 if ( p_bsic->rem_bsic > 0) | |
2840 { | |
2841 while ( (k < p_bsic->rem_bsic) AND j < MAX_NEIGHBOURCELLS ) | |
2842 { | |
2843 if (p_bsic->bsic_struct[k].freq_scroll EQ SCROL_NO) | |
2844 /* This means same frequency as before */ | |
2845 p_enh->enh_cell_list[j].arfcn = i; | |
2846 else | |
2847 p_enh->enh_cell_list[j].arfcn = ++i; | |
2848 p_enh->enh_cell_list[j].bsic = p_bsic->bsic_struct[k].bsic; | |
2849 j++; | |
2850 k++; | |
2851 } | |
2852 } | |
2853 if ( j >= MAX_NEIGHBOURCELLS ) | |
2854 p_enh->num_valid_cells = MAX_NEIGHBOURCELLS; /* we will not monitor more than 32 cells*/ | |
2855 else | |
2856 p_enh->num_valid_cells = j; | |
2857 return; | |
2858 } | |
2859 | |
2860 /* | |
2861 +------------------------------------------------------------------------------ | |
2862 | Function : for_update_enh_cell_list | |
2863 +------------------------------------------------------------------------------ | |
2864 | Description : This function updates the enhanced cell list with actual ARFCNs from | |
2865 | BA list. Note that this updation is always with respect to temp data base | |
2866 | and will be moved to current only if updation is successful. | |
2867 | If there are any indices pointing to unavailable ARFCN (due to SI-5ter) | |
2868 | then the updation is continued by marking that these need to be updated | |
2869 | later. In this case we still consider, updation to be successful. | |
2870 | Parameters : Input: | |
2871 | Stored BA list | |
2872 | Output: | |
2873 | TRUE - Updation successful | |
2874 | FALSE - Updation unsuccessful | |
2875 +------------------------------------------------------------------------------ | |
2876 */ | |
2877 GLOBAL BOOL for_update_enh_cell_list (USHORT *p_list) | |
2878 { | |
2879 GET_INSTANCE_DATA; | |
2880 T_rr_enh_para *p_enh = &rr_data->sc_data.emr_data_temp; | |
2881 T_rr_enh_para *p_cur = &rr_data->sc_data.emr_data_current; | |
2882 UBYTE i; | |
2883 UBYTE j; | |
2884 ULONG rep_bmp = rr_data->sc_data.rep_bmp; | |
2885 ULONG ba_bitmap = 0; | |
2886 | |
2887 TRACE_FUNCTION ("for_update_enh_cell_list"); | |
2888 /*First check whether BSIC list was given or it's only updation | |
2889 of parameters*/ | |
2890 if (p_enh->enh_para.num_valid_cells EQ 0) | |
2891 { | |
2892 /*There should be enhanced cell list atleast in current*/ | |
2893 if ( (p_cur->is_data_valid EQ TRUE) AND (p_cur->enh_para.num_valid_cells > 0) ) | |
2894 { | |
2895 /*This copy is actually over head, but done to maintain uniformity in | |
2896 copying after this function returns*/ | |
2897 p_enh->enh_para.num_valid_cells = p_cur->enh_para.num_valid_cells; | |
2898 memcpy(p_enh->enh_para.enh_cell_list,p_cur->enh_para.enh_cell_list, | |
2899 p_cur->enh_para.num_valid_cells * sizeof(T_enh_cell_list)); | |
2900 return TRUE; | |
2901 } | |
2902 else | |
2903 { | |
2904 TRACE_EVENT("BSIC Information required for enhanced reporting, is missing"); | |
2905 return FALSE; | |
2906 } | |
2907 } | |
2908 | |
2909 /*Under the conditions when this function is called, the | |
2910 enhanced cell list contains the index of the ARFCN in neighbourcell list*/ | |
2911 for (i = 0; i < p_enh->enh_para.num_valid_cells; i++ ) | |
2912 { | |
2913 j = (UBYTE)p_enh->enh_para.enh_cell_list[i].arfcn; | |
2914 p_enh->enh_para.enh_cell_list[i].rep_priority = (UBYTE) ((rep_bmp >> i) & 1); | |
2915 if ( p_list[j] NEQ NOT_PRESENT_16BIT ) | |
2916 { | |
2917 ba_bitmap |= (1 << j); | |
2918 p_enh->enh_para.enh_cell_list[i].arfcn = p_list[j]; | |
2919 } | |
2920 else | |
2921 { | |
2922 /*This indicates that we received BSIC for an unknown ARFCN. This ambiguity | |
2923 may be resolved once we receive SI-5ter*/ | |
2924 p_enh->ba2bsic_map_pending |= ( 1<<i); /*set the bit of the corresponding index of enh-cell-list*/ | |
2925 /*Index to BA(list) is retained as it is and actual ARFCN from this index is copied after receiving | |
2926 SI-5ter*/ | |
2927 } | |
2928 } | |
2929 | |
2930 /*verify whether the mapping is complete*/ | |
2931 i = 0; | |
2932 while (p_list[i] NEQ NOT_PRESENT_16BIT) | |
2933 { | |
2934 if (( (ba_bitmap >> i) & 1) NEQ TRUE ) | |
2935 { | |
2936 /* This indicates that there are still some ARFCN in BA list | |
2937 that doesn't have a corresponding BSIC */ | |
2938 TRACE_EVENT("BA - BSIC list mapping is incorrect : IGNORE the message "); | |
2939 return FALSE; | |
2940 } | |
2941 i++; | |
2942 } | |
2943 | |
2944 return TRUE; | |
2945 } | |
2946 | |
2947 /* | |
2948 +------------------------------------------------------------------------------ | |
2949 | Function : for_store_rep_priority | |
2950 +------------------------------------------------------------------------------ | |
2951 | Description : This function stores the report priority temporarily in the form | |
2952 | of bit map. | |
2953 | Parameters : Input: | |
2954 | Reporting prioirty list from air message | |
2955 +------------------------------------------------------------------------------ | |
2956 */ | |
2957 LOCAL void for_store_rep_priority ( T_gprs_rep_prio *p_rp) | |
2958 { | |
2959 GET_INSTANCE_DATA; | |
2960 ULONG rep_bmp = 0; | |
2961 UBYTE i; | |
2962 | |
2963 TRACE_FUNCTION ("for_store_rep_priority"); | |
2964 /*IMPORTANT ASSUMPTION: since there is no index information | |
2965 associated explicitly with REPORT PRIORITY information, it's | |
2966 more likely that entire report priority info is given in one instance*/ | |
2967 /* Only GSM neighbor cells upto 32 are supported */ | |
2968 if (p_rp->num_cells > (MAX_NEIGHBOURCELLS -1) ) | |
2969 p_rp->num_cells = MAX_NEIGHBOURCELLS -1; | |
2970 | |
2971 for ( i = 0; i < p_rp->num_cells; i++ ) | |
2972 { | |
2973 rep_bmp |= ( (p_rp->rep_priority[i] & 1) << i ); | |
2974 } | |
2975 rr_data->sc_data.rep_bmp = rep_bmp; | |
2976 return; | |
2977 } | |
2978 | |
2979 /* | |
2980 +------------------------------------------------------------------------------ | |
2981 | Function : for_process_common_emr_data | |
2982 +------------------------------------------------------------------------------ | |
2983 | Description : This function processes the EMR parameters that are common in | |
2984 | SI-2quater and MI messages. | |
2985 | Parameters : Input: | |
2986 | Reporting prioirty list from air message | |
2987 | BSIC list from air message | |
2988 | Enhanced para structure, where the data needs to be updated | |
2989 | message instance number | |
2990 | Output | |
2991 | TRUE - processing successful | |
2992 | FALSE - processing unsuccessful | |
2993 +------------------------------------------------------------------------------ | |
2994 */ | |
2995 GLOBAL BOOL for_process_common_emr_data (T_gprs_rep_prio *p_rep, | |
2996 T_gprs_bsic *p_bsic, | |
2997 UBYTE msg_index, | |
2998 BOOL ba_available) | |
2999 { | |
3000 GET_INSTANCE_DATA; | |
3001 T_bsic_list *p_bl = &rr_data->sc_data.bsic_list[0]; | |
3002 T_rr_enh_para *p_enh = &rr_data->sc_data.emr_data_temp; | |
3003 | |
3004 TRACE_FUNCTION ("for_process_common_emr_data"); | |
3005 /*check for duplication of instance */ | |
3006 if ( ((rr_data->sc_data.instance_bmp >> msg_index) & (0x01)) EQ TRUE ) | |
3007 return FALSE; /*This instance was already received, so need to process | |
3008 it again*/ | |
3009 | |
3010 /*set the bit of the received instance in the bit map */ | |
3011 rr_data->sc_data.instance_bmp |= (1 << msg_index); | |
3012 | |
3013 /*Store report priority: Ref. sec.3.4.1.2.1.5, 4.18 | |
3014 Report Priority information can be received in one instance of the MEASUREMENT INFORMATION message*/ | |
3015 if(p_rep NEQ NULL) | |
3016 for_store_rep_priority(p_rep); | |
3017 | |
3018 if(p_bsic NEQ NULL ) | |
3019 { | |
3020 /*BSIC list is available, store it to perform BA-BSIC mapping at the end */ | |
3021 p_bl[msg_index].is_valid = TRUE; | |
3022 p_bl[msg_index].bsic_info = *p_bsic; | |
3023 } | |
3024 | |
3025 /*check whether all the instances are received or not | |
3026 Number of 1's in instance_bmp should equal msg_count+1 | |
3027 Eg: if msg_count = 3, instance_bmp = 0000 0000 0000 1111 = 15 | |
3028 2^(3+1)-1 = 15 */ | |
3029 if ( rr_data->sc_data.instance_bmp EQ ( (1 << (p_enh->msg_count+1))-1) ) | |
3030 { | |
3031 UBYTE i; | |
3032 /*all the instances are received, perform updations from temp --> current */ | |
3033 | |
3034 /* BA-BSIC mapping makes sense only if enhanced measurement reporting is enabled*/ | |
3035 if ((p_enh->rep_type EQ ENHANCED_MEAS) OR (p_enh->grr_rep_type EQ ENHANCED_MEAS) ) | |
3036 { | |
3037 for ( i= 0; i <= p_enh->msg_count; i++ ) | |
3038 { | |
3039 if ( p_bl[i].is_valid EQ TRUE ) | |
3040 for_perform_ba_bsic_mapping(&p_bl[i].bsic_info, &p_enh->enh_para); | |
3041 } | |
3042 | |
3043 if ( ba_available EQ TRUE ) | |
3044 { | |
3045 /*First we update the enhanced cell list in the temp and then store | |
3046 into current, if the updation is successful*/ | |
3047 if ( for_update_enh_cell_list( rr_data->act_ncell_list) EQ TRUE) | |
3048 { | |
3049 rr_data->sc_data.emr_data_current = *p_enh; | |
3050 memset (rr_data->sc_data.rep_count, NOT_PRESENT_8BIT, MAX_NEIGHBOURCELLS); | |
3051 for_set_default_emr_data(p_enh); | |
3052 return TRUE; | |
3053 } | |
3054 else | |
3055 { | |
3056 /*Updation of enhanced cell list is unsuccesful, so flush temp | |
3057 and ignore the entire message */ | |
3058 for_set_default_emr_data(p_enh); | |
3059 return FALSE; | |
3060 } | |
3061 } | |
3062 } | |
3063 else | |
3064 { | |
3065 /*If we recieved SI2q without Enhanced para, Update the CM value in the emr_current*/ | |
3066 rr_data->sc_data.emr_data_current.mp_change_mark = p_enh->mp_change_mark; | |
3067 /*After cell reselection the first si2qtr received must be processed, | |
3068 for this is_data_valid flag should be reset */ | |
3069 rr_data->sc_data.emr_data_current.is_data_valid = TRUE; | |
3070 for_set_default_emr_data(p_enh); | |
3071 } | |
3072 return TRUE; | |
3073 } | |
3074 return FALSE; | |
3075 } | |
3076 | |
3077 GLOBAL void for_mon_si2quater_req(UBYTE action) | |
3078 { | |
3079 PALLOC(mph_mon_ctrl_req, MPH_MON_CTRL_REQ ); | |
3080 TRACE_FUNCTION ("for_mon_si2quater_req"); | |
3081 mph_mon_ctrl_req->action = action; | |
3082 mph_mon_ctrl_req->si_to_read = UPDATE_SI2QUATER; | |
3083 PSENDX (PL, mph_mon_ctrl_req); | |
3084 return; | |
3085 } | |
3086 | |
3087 /* | |
3088 +------------------------------------------------------------------------------ | |
3089 | Function : for_update_ba_ind | |
3090 +------------------------------------------------------------------------------ | |
3091 | Description : | |
3092 | | |
3093 | Parameters : Input: | |
3094 | | |
3095 +------------------------------------------------------------------------------ | |
3096 */ | |
3097 GLOBAL void for_update_ba_ind (UBYTE index, UBYTE ba_ind) | |
3098 { | |
3099 GET_INSTANCE_DATA; | |
3100 if( index EQ SC_INDEX ) | |
3101 { | |
3102 T_rr_enh_para *p_cur = &rr_data->sc_data.emr_data_current; | |
3103 if ( rr_data->sc_data.ba_index NEQ ba_ind) | |
3104 { | |
3105 rr_data->sc_data.ba_index = ba_ind; | |
3106 /*Received SI-2 on serving cell: this indicates there is change in | |
3107 SI-2 ==> store an indication that SI-2quater also has to be configured. | |
3108 Once the BA list is received completely, then we will configure ALR for receiving | |
3109 SI-2quater*/ | |
3110 if (rr_data->sc_data.cd.si2quater_status NEQ SI2QUATER_ABSENT) | |
3111 rr_data->sc_data.cd.si2quater_status = SI2QUATER_CONFIGURE; | |
3112 if ( p_cur->is_data_valid ) | |
3113 { | |
3114 memset (rr_data->sc_data.rep_count, NOT_PRESENT_8BIT, MAX_NEIGHBOURCELLS); | |
3115 for_set_default_emr_data(p_cur); | |
3116 /*Indicate to GRR and ALR that current enhanced para are not valid*/ | |
3117 for_send_enh_para(p_cur); | |
3118 } | |
3119 } | |
3120 } | |
3121 else | |
3122 rr_data->cr_data.ba_index = ba_ind; | |
3123 } | |
3124 | |
3125 /* | |
3126 +------------------------------------------------------------------------------ | |
3127 | Function : for_check_and_configure_si2quater | |
3128 +------------------------------------------------------------------------------ | |
3129 | Description : | |
3130 | | |
3131 | Parameters : Input: | |
3132 | | |
3133 +------------------------------------------------------------------------------ | |
3134 */ | |
3135 GLOBAL void for_check_and_configure_si2quater (UBYTE index) | |
3136 { | |
3137 GET_INSTANCE_DATA; | |
3138 T_rr_enh_para *p_temp = &rr_data->sc_data.emr_data_temp; | |
3139 T_rr_enh_para *p_cur = &rr_data->sc_data.emr_data_current; | |
3140 | |
3141 if ( index EQ SC_INDEX) | |
3142 { | |
3143 UBYTE si2_read = (SYS_INFO_2_READ | SYS_INFO_2BIS_READ |SYS_INFO_2TER_READ ); | |
3144 rr_data->sc_data.ba_list_idle = FALSE; /*This makes sure that we wait till SI-2,2bis/2ter | |
3145 are received before configuring L1 for SI-2quater, | |
3146 when it is on E-BCCH.If it's on N-BCCH, SI-2quater | |
3147 will be stored in temp database, till BA(BCCH) is complete*/ | |
3148 | |
3149 if ( ((rr_data->sc_data.cd.sys_info_read ) & si2_read) EQ si2_read ) | |
3150 { | |
3151 /*This indicates that all required SI-2 have been read*/ | |
3152 rr_data->sc_data.ba_list_idle = TRUE; | |
3153 rr_data->sc_data.ba_list_ded = FALSE; | |
3154 /*configure SI-2quater if either configuration is pending or previously | |
3155 acquired and needs fresh acquisition due to change in SI-2/2bis*/ | |
3156 if ( (rr_data->sc_data.cd.si2quater_status NEQ SI2QUATER_ABSENT ) AND | |
3157 (rr_data->sc_data.cd.si2quater_status NEQ SI2QUATER_ACQ_PENDING) ) | |
3158 { | |
3159 if (p_cur->is_data_valid EQ TRUE) | |
3160 { | |
3161 memset (rr_data->sc_data.rep_count, NOT_PRESENT_8BIT, MAX_NEIGHBOURCELLS); | |
3162 for_set_default_emr_data(p_cur); | |
3163 /*Indicate to GRR and ALR that current enhanced para are not valid*/ | |
3164 for_send_enh_para(p_cur); | |
3165 } | |
3166 /*configure ALR for acquiring SI-2quater if it is scheduled on E-BCCH. | |
3167 If it's on N-BCCH, it would have been acquired already or we might | |
3168 be in the process of acquiring*/ | |
3169 if ( rr_data->sc_data.cd.si2quater_pos EQ SI2QUATER_ON_EBCCH ) | |
3170 { | |
3171 for_mon_si2quater_req(START_MON_EBCCH); | |
3172 rr_data->sc_data.cd.si2quater_status = SI2QUATER_ACQ_PENDING; | |
3173 } | |
3174 else | |
3175 { | |
3176 if((rr_data->sc_data.cd.sys_info_read & SYS_INFO_2QUATER_READ) NEQ SYS_INFO_2QUATER_READ) /* SI 2qtr not yet read */ | |
3177 { | |
3178 rr_data->sc_data.cd.si2quater_status = SI2QUATER_ACQ_PENDING; | |
3179 if((rr_data->sc_data.cd.sys_info_read & ALL_SYS_INFO_READ) EQ ALL_SYS_INFO_READ) | |
3180 { | |
3181 /*All other sys info has been read*/ | |
3182 for_mon_si2quater_req(START_MON_NBCCH); | |
3183 } | |
3184 /*else | |
3185 { | |
3186 There are other SI that have not been read yet on Normal BCCH, just continue to read normal BCCH | |
3187 } | |
3188 */ | |
3189 | |
3190 }/*if*/ | |
3191 } | |
3192 } | |
3193 } | |
3194 } | |
3195 | |
3196 if ( rr_data->sc_data.enh_para_status EQ ENH_PARA_DEDICATED) | |
3197 { | |
3198 /*The enhanced parameters are from previous state: reset them */ | |
3199 memset (rr_data->sc_data.rep_count, NOT_PRESENT_8BIT, MAX_NEIGHBOURCELLS); | |
3200 for_set_default_emr_data(p_cur); | |
3201 for_set_default_emr_data(p_temp); | |
3202 for_send_enh_para(p_cur); | |
3203 rr_data->sc_data.enh_para_status = ENH_PARA_INVALID_STATE; | |
3204 } | |
3205 /*When BA(BCCH) is ready, check whether there are enhanced parameters in | |
3206 temp that needs attention*/ | |
3207 if ( (rr_data->sc_data.ba_list_idle EQ TRUE ) AND | |
3208 ( rr_data->sc_data.enh_para_status EQ ENH_PARA_IDLE) AND | |
3209 (p_temp->is_data_valid EQ TRUE)) | |
3210 { | |
3211 /* This means enhanced parameters were received before BA list - so | |
3212 update the enhanced list with actual ARFCN and update current EMR data*/ | |
3213 if ( for_update_enh_cell_list( rr_data->act_ncell_list) EQ TRUE) | |
3214 { | |
3215 *p_cur = *p_temp; | |
3216 for_send_enh_para(p_temp); | |
3217 } | |
3218 /*Reset temporary, irrespective of whether updation is succesful or not*/ | |
3219 for_set_default_emr_data(p_temp); | |
3220 if ((rr_data->sc_data.cd.si2quater_status EQ SI2QUATER_ACQ_PENDING) OR | |
3221 (rr_data->sc_data.cd.si2quater_status EQ SI2QUATER_ACQ_WRONG_BAIND)) | |
3222 { | |
3223 for_mon_si2quater_req(STOP_MON_BCCH); | |
3224 rr_data->sc_data.cd.si2quater_status = SI2QUATER_ACQ_COMP; | |
3225 } | |
3226 } | |
3227 | |
3228 return; | |
3229 } | |
3230 #endif | |
3231 | |
3232 #if defined (TI_PS_FF_RTD) AND defined (REL99) | |
3233 /* | |
3234 +------------------------------------------------------------------------------ | |
3235 | Function : for_store_rtd_data | |
3236 +------------------------------------------------------------------------------ | |
3237 | Description : This function stores the rtd parameters received in si2quarter. | |
3238 | Parameters : RTD information/data,target enh para struct where we store RTD para | |
3239 +------------------------------------------------------------------------------ | |
3240 */ | |
3241 GLOBAL void for_store_rtd_data(T_si_2qua_octets *p_si2q,T_rr_enh_para *p_temp) | |
3242 { | |
3243 T_rtdd *rtdd_struct= &p_si2q->rtdd; | |
3244 dat_update_common_rtd_struct(rtdd_struct,p_temp); | |
3245 } /* end for_store_rtd_data() */ | |
3246 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */ | |
3247 | |
3248 | |
3249 #endif |