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