FreeCalypso > hg > tcs211-l1-reconst
comparison g23m/condat/com/src/comlib/cl_list.c @ 0:509db1a7b7b8
initial import: leo2moko-r1
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 01 Jun 2015 03:24:05 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:509db1a7b7b8 |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : | |
4 | Modul : | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2002 Texas Instruments Berlin, AG | |
7 | All rights reserved. | |
8 | | |
9 | This file is confidential and a trade secret of Texas | |
10 | Instruments Berlin, AG | |
11 | The receipt of or possession of this file does not convey | |
12 | any rights to reproduce or disclose its contents or to | |
13 | manufacture, use, or sell anything it may describe, in | |
14 | whole, or in part, without the specific written consent of | |
15 | Texas Instruments Berlin, AG. | |
16 +----------------------------------------------------------------------------- | |
17 | Purpose : This module defines the functions for the List | |
18 | processing functions used in components RR/PL of the mobile station. | |
19 +----------------------------------------------------------------------------- | |
20 */ | |
21 | |
22 #ifndef CL_LIST_C | |
23 #define CL_LIST_C | |
24 | |
25 #define ENTITY_RR | |
26 #define ENTITY_PL | |
27 | |
28 /*==== INCLUDES ===================================================*/ | |
29 | |
30 #include <string.h> | |
31 #include <stdlib.h> | |
32 #include <stddef.h> | |
33 #include "typedefs.h" | |
34 #include "message.h" | |
35 #include "vsi.h" | |
36 #include "gsm.h" | |
37 #include "prim.h" | |
38 #include "cl_list.h" | |
39 | |
40 /*==== CONST ======================================================*/ | |
41 | |
42 /*==== VARIABLES ==================================================*/ | |
43 LOCAL const BYTE ByteBitMask[]= {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x1}; | |
44 | |
45 /*==== EXPORT =====================================================*/ | |
46 | |
47 /*==== PRIVATE FUNCTIONS ==========================================*/ | |
48 LOCAL UBYTE srv_is_not_in_list (USHORT * channels, | |
49 USHORT new_channel, | |
50 USHORT size); | |
51 /*==== PUBLIC FUNCTIONS ===========================================*/ | |
52 /* | |
53 * List processing Functions | |
54 * | |
55 * RR uses a lot of channel lists. They are organized internally as bitmaps. | |
56 * In the following a set of functions is defined for access to this lists: | |
57 * | |
58 * srv_set_channel | |
59 * srv_unset_channel | |
60 * srv_get_channel | |
61 * srv_create_list | |
62 * srv_clear_list | |
63 * srv_copy_list | |
64 * srv_compare_list | |
65 * srv_merge_list | |
66 * srv_is_empty_list | |
67 * srv_create_chan_mob_alloc | |
68 * | |
69 * The size of the internal channel lists depends on the supported frequency | |
70 * band: | |
71 * | |
72 * STD=1 (STD_900) GSM 900 | |
73 * STD=2 (STD_EGSM) E-GSM | |
74 * STD=3 (STD_1900) PCS 1900 | |
75 * STD=4 (STD_1800) DCS 1800 | |
76 * STD=5 (STD_DUAL) GSM 900 / DCS 1800 DUALBAND | |
77 * STD=6 (STD_DUAL_EGSM) GSM 900 / E-GSM / DCS 1800 DUALBAND | |
78 * STD=7 (STD_850) GSM 850 | |
79 * STD=8 (STD_DUAL_US) GSM 850 / PCS 1900 DUALBAND | |
80 * | |
81 * We use a compressed bit array to store the list of channels. | |
82 * Dependent on the configured or found frequency bands the bit array | |
83 * needs several numbers of bytes. For the representation of the individual | |
84 * bits in the array we need the function scr_channel_bit(), setBit(), | |
85 * resetBit() and getBit(). | |
86 * | |
87 */ | |
88 | |
89 /* | |
90 +--------------------------------------------------------------------+ | |
91 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
92 | STATE : code ROUTINE : setBit | | |
93 +--------------------------------------------------------------------+ | |
94 | |
95 PURPOSE : sets bit. | |
96 | |
97 */ | |
98 | |
99 LOCAL void setBit (UBYTE* bitstream, unsigned bitindex) | |
100 { | |
101 bitstream[bitindex >> 3] |= ByteBitMask[bitindex & 7]; | |
102 } | |
103 | |
104 | |
105 /* | |
106 +--------------------------------------------------------------------+ | |
107 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
108 | STATE : code ROUTINE : resetBit | | |
109 +--------------------------------------------------------------------+ | |
110 | |
111 PURPOSE : Resets bit. | |
112 | |
113 */ | |
114 | |
115 LOCAL void resetBit (UBYTE* bitstream, unsigned bitindex) | |
116 { | |
117 bitstream[bitindex >> 3] &= ~ByteBitMask[bitindex & 7]; | |
118 } | |
119 | |
120 /* | |
121 +--------------------------------------------------------------------+ | |
122 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
123 | STATE : code ROUTINE : getBit | | |
124 +--------------------------------------------------------------------+ | |
125 | |
126 PURPOSE : Gets bit. | |
127 | |
128 */ | |
129 | |
130 | |
131 LOCAL BYTE getBit (UBYTE* bitstream, unsigned bitindex) | |
132 { | |
133 unsigned ByteIdx = bitindex >> 3; | |
134 | |
135 if (bitstream[ByteIdx]) | |
136 return (bitstream[ByteIdx] & ByteBitMask[bitindex & 7]) ? 1 : 0; | |
137 else | |
138 return 0; | |
139 } | |
140 | |
141 /* | |
142 +--------------------------------------------------------------------+ | |
143 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
144 | STATE : code ROUTINE : scr_channel_bit | | |
145 +--------------------------------------------------------------------+ | |
146 | |
147 PURPOSE : calculate bit position in the bitstream for a given | |
148 channel and execute function dependent on mode. | |
149 | |
150 */ | |
151 | |
152 GLOBAL UBYTE scr_channel_bit(T_LIST * list, int channel, int mode) | |
153 { | |
154 int bitposition = -1; | |
155 UBYTE ret = 0; | |
156 | |
157 /* | |
158 * a more efficient way of range checking for ARM | |
159 * (according to application note 34, ARM DAI 0034A, January 1998) | |
160 * | |
161 * For the following code: | |
162 * if (channel >= low_channel AND channel <= high_channel) | |
163 * bitposition = ...; | |
164 * | |
165 * exist the faster way to implemented this: | |
166 * if ((unsigned)(channel - low_channel) <= (high_channel - low_channel) | |
167 * bitposition = ...; | |
168 * | |
169 * Future versions of the compiler will perform this optimization | |
170 * automatically. | |
171 * | |
172 * We use the follwing macro: | |
173 * #define INRANGE(min, x, max) ((unsigned)(x-min) <= (max-min)) | |
174 */ | |
175 if(channel EQ CHANNEL_0) | |
176 channel = CHANNEL_0_INTERNAL; | |
177 | |
178 bitposition = BITOFFSET_LIST - channel; | |
179 /*if (channel EQ CHANNEL_0) | |
180 bitposition = (USHORT)(BITOFFSET_DUAL_EGSM_B - CHANNEL_0_INTERNAL); | |
181 else if (INRANGE(LOW_CHANNEL_900,channel,HIGH_CHANNEL_900)) | |
182 bitposition = (USHORT)(BITOFFSET_DUAL_EGSM_A - channel); | |
183 else if (INRANGE(LOW_CHANNEL_EGSM,channel,HIGH_CHANNEL_EGSM)) | |
184 bitposition = (USHORT)(BITOFFSET_DUAL_EGSM_B - channel); | |
185 else if (INRANGE(LOW_CHANNEL_1800,channel,HIGH_CHANNEL_1800)) | |
186 bitposition = (USHORT)(BITOFFSET_DUAL_EGSM_C - channel); | |
187 if (INRANGE(LOW_CHANNEL_850,channel,HIGH_CHANNEL_850)) | |
188 bitposition = (USHORT)(BITOFFSET_DUAL_US_A - channel); | |
189 else if (INRANGE(LOW_CHANNEL_1900,channel,HIGH_CHANNEL_1900)) | |
190 bitposition = (USHORT)(BITOFFSET_DUAL_US_B - channel); | |
191 */ | |
192 if (bitposition NEQ -1) | |
193 { | |
194 switch (mode) | |
195 { | |
196 case SET_CHANNEL_BIT: | |
197 setBit (list->channels, bitposition); | |
198 break; | |
199 case RESET_CHANNEL_BIT: | |
200 resetBit (list->channels, bitposition); | |
201 break; | |
202 case GET_CHANNEL_BIT: | |
203 ret = getBit (list->channels, bitposition); | |
204 break; | |
205 case CHECK_CHANNEL: | |
206 ret = 1; | |
207 break; | |
208 } | |
209 } | |
210 return ret; | |
211 } | |
212 | |
213 /* | |
214 +--------------------------------------------------------------------+ | |
215 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
216 | STATE : code ROUTINE : srv_create_list | | |
217 +--------------------------------------------------------------------+ | |
218 | |
219 PURPOSE : Creates a frequency list in USHORT format from the | |
220 bit list. USHORT format means an array of USHORTs | |
221 followed by NOT_PRESENT_16BIT (0xFFFF), except for the | |
222 case when all elements of the array are used, i.e. the | |
223 array's space is fully occupied. | |
224 In this function the channels are just converted between | |
225 the formats, any semantic errors are not checked here, ie. | |
226 if the MS is 1800-only and the list contains a 900 channel | |
227 this will be converted even if this leads to an error. | |
228 This has to be handled by the caller. | |
229 | |
230 Parameters: | |
231 list - [in] is the input list. | |
232 channel_array - [out] converted list. | |
233 size - [in] defines the maximum number of channels | |
234 in the list. | |
235 zero_at_start - [in] specifies where the CHANNEL_0 should be | |
236 put: | |
237 TRUE - at the start of the list | |
238 FALSE - at the end of the list | |
239 start_index - [in] specifies a index into the channel_array. | |
240 new channels are added at the positions | |
241 following and including the index: | |
242 channel_array[start_index] to | |
243 channel_array[size-1] | |
244 | |
245 If the start_index is not equal zero it is | |
246 also checked if the new channel is already | |
247 in the channel_array list (from | |
248 channel_array[0] to | |
249 channel_array[start_index-1]) | |
250 | |
251 If the start_index is equal zero the | |
252 above check is not performed. | |
253 | |
254 Return Value: | |
255 number of elements added + start_index | |
256 | |
257 */ | |
258 | |
259 GLOBAL int srv_create_list (T_LIST * list, USHORT * channel_array, USHORT size, | |
260 UBYTE zero_at_start, USHORT start_index) | |
261 { | |
262 int BitOffset, Idx; | |
263 unsigned int ByteValue, BitMask, LeftMask; | |
264 int i = start_index; | |
265 UBYTE *pch; | |
266 USHORT *parray = &channel_array[start_index]; | |
267 | |
268 pch = &list->channels[T_LIST_MAX_SIZE-1]; | |
269 for(Idx = T_LIST_MAX_SIZE-1; Idx >= 0 AND i < size; Idx--, pch--) | |
270 { | |
271 /* | |
272 * check and add all channels | |
273 */ | |
274 if ((ByteValue = *pch) NEQ 0) | |
275 { | |
276 /* byte contains set bits */ | |
277 | |
278 /* check single bits */ | |
279 for (BitOffset=7, BitMask=0x01, LeftMask=0xfe; | |
280 BitOffset>=0; | |
281 BitOffset--, BitMask<<=1, LeftMask<<=1) | |
282 { | |
283 if (ByteValue & BitMask) | |
284 { | |
285 *parray = BITOFFSET_LIST - (BitOffset+(Idx<<3)); | |
286 if(!start_index OR | |
287 srv_is_not_in_list (channel_array, *parray, start_index)) | |
288 { | |
289 /* if the check is ok, ie: | |
290 * always add channel, or the channel has not yet existed | |
291 * in the list, then advance the pointer and add the | |
292 * next channel on next position | |
293 * if the check fails the pointer is not advanced and | |
294 * the channel will not be added and the next channel | |
295 * will overwrite the current channel. | |
296 */ | |
297 parray++; | |
298 | |
299 /* check if list is full */ | |
300 if (++i >= size) | |
301 break; | |
302 } | |
303 /* check if any bits are left */ | |
304 if ((ByteValue & LeftMask) EQ 0) | |
305 break; | |
306 } | |
307 } /* for all bits in byte */ | |
308 } /* if Byte NEQ 0 */ | |
309 } /* for all Bytes in List */ | |
310 | |
311 | |
312 /* | |
313 * If CHANNEL_0 is included in the list | |
314 * it has to be changed from CHANNEL_0_INTERNAL to CHANNEL_0 | |
315 * and then the zero_at_start flag is handled. | |
316 * | |
317 * If CHANNEL_0 is in the list it is always | |
318 * at the end of the list. | |
319 */ | |
320 if(i NEQ start_index AND | |
321 *(parray-1) EQ CHANNEL_0_INTERNAL) | |
322 { | |
323 *(parray-1) = CHANNEL_0; | |
324 | |
325 if(zero_at_start AND (i > 1)) | |
326 { | |
327 memmove(&channel_array[1], &channel_array[0], (int)sizeof(channel_array[0])*(i-1)); | |
328 channel_array[0] = CHANNEL_0; | |
329 } | |
330 } | |
331 | |
332 /* | |
333 * add the end identifier to the output list | |
334 */ | |
335 if (i<size) | |
336 { | |
337 *parray = NOT_PRESENT_16BIT; | |
338 } | |
339 | |
340 return i; | |
341 } | |
342 | |
343 /* | |
344 +--------------------------------------------------------------------+ | |
345 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
346 | STATE : code ROUTINE : srv_is_not_in_list | | |
347 +--------------------------------------------------------------------+ | |
348 | |
349 PURPOSE : Checks if the given channel number is a member of the given | |
350 list. | |
351 | |
352 Parameters: | |
353 channels - contains the existing output list. | |
354 new_channel - is the channel number which shall be checked. | |
355 size - indicates the length of the list. | |
356 | |
357 */ | |
358 | |
359 static UBYTE srv_is_not_in_list (USHORT * channels, | |
360 USHORT new_channel, | |
361 USHORT size) | |
362 { | |
363 USHORT i; | |
364 | |
365 /* | |
366 * for all members of the list | |
367 */ | |
368 for (i=0;i<size;i++) | |
369 { | |
370 /* | |
371 * The end of the list is reached | |
372 * that means the new channel is not inside. | |
373 */ | |
374 if (channels[i] EQ NOT_PRESENT_16BIT) | |
375 return TRUE; | |
376 | |
377 /* | |
378 * the channel is inside | |
379 */ | |
380 if (channels[i] EQ new_channel) | |
381 return FALSE; | |
382 } | |
383 | |
384 return TRUE; | |
385 } | |
386 | |
387 /* | |
388 +--------------------------------------------------------------------+ | |
389 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
390 | STATE : code ROUTINE : srv_clear_list | | |
391 +--------------------------------------------------------------------+ | |
392 | |
393 PURPOSE : Clears a list by clearing all bits. | |
394 | |
395 */ | |
396 | |
397 GLOBAL void srv_clear_list (T_LIST * list) | |
398 { | |
399 /* | |
400 * simple algorithm: clear the whole list. | |
401 */ | |
402 memset (list, 0, sizeof (T_LIST)); | |
403 } | |
404 | |
405 /* | |
406 +--------------------------------------------------------------------+ | |
407 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
408 | STATE : code ROUTINE : srv_copy_list | | |
409 +--------------------------------------------------------------------+ | |
410 | |
411 PURPOSE : Copies a list. | |
412 | |
413 */ | |
414 | |
415 GLOBAL void srv_copy_list (T_LIST * target_list, T_LIST * source_list, | |
416 UBYTE size) | |
417 { | |
418 memcpy (target_list, source_list, size); | |
419 } | |
420 | |
421 /* | |
422 +--------------------------------------------------------------------+ | |
423 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
424 | STATE : code ROUTINE : srv_compare_list | | |
425 +--------------------------------------------------------------------+ | |
426 | |
427 PURPOSE : Compares two lists. | |
428 | |
429 */ | |
430 | |
431 GLOBAL UBYTE srv_compare_list (T_LIST * list1, T_LIST * list2) | |
432 { | |
433 return (memcmp (list1, list2, sizeof (T_LIST)) EQ 0); | |
434 } | |
435 | |
436 /* | |
437 +--------------------------------------------------------------------+ | |
438 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
439 | STATE : code ROUTINE : srv_merge_list | | |
440 +--------------------------------------------------------------------+ | |
441 | |
442 PURPOSE : Merges two lists. Both lists are bitmaps. So the merge | |
443 is done by a bitwise OR. | |
444 | |
445 */ | |
446 | |
447 GLOBAL void srv_merge_list (T_LIST * target_list, T_LIST * list) | |
448 { | |
449 USHORT i; | |
450 | |
451 /* | |
452 * The maximum list size is T_LIST_MAX_SIZE Bytes for the dualband extended | |
453 * frequency standard. | |
454 */ | |
455 | |
456 for (i=0;i<T_LIST_MAX_SIZE;i++) | |
457 target_list->channels[i] |= list->channels[i]; | |
458 } | |
459 | |
460 /* | |
461 +--------------------------------------------------------------------+ | |
462 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
463 | STATE : code ROUTINE : srv_unmask_list | | |
464 +--------------------------------------------------------------------+ | |
465 | |
466 PURPOSE : This routine resets those bits in destination list that are set in | |
467 the source list. | |
468 Refer Cell Selection Improvements-LLD section:4.1.1.3.11 | |
469 */ | |
470 | |
471 GLOBAL void srv_unmask_list(T_LIST *target,T_LIST *source) | |
472 { | |
473 UBYTE count=0; | |
474 for (count=0;count<T_LIST_MAX_SIZE; count++) | |
475 { | |
476 target->channels[count] &= ~source->channels[count]; | |
477 } | |
478 } | |
479 | |
480 | |
481 /* | |
482 +--------------------------------------------------------------------+ | |
483 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
484 | STATE : code ROUTINE : srv_trace_freq_in_list | | |
485 +--------------------------------------------------------------------+ | |
486 | |
487 PURPOSE : This routine traces the frequencies in the list | |
488 CSI-LLD section:4.1.1.3.11 | |
489 */ | |
490 | |
491 GLOBAL void srv_trace_freq_in_list(T_LIST *list) | |
492 { | |
493 U16 i; | |
494 | |
495 for(i=CHANNEL_0;i<CHANNEL_0_INTERNAL;i++) | |
496 { | |
497 if(srv_get_channel (list, i)) | |
498 { | |
499 TRACE_EVENT_P1("arfcn=%u",i); | |
500 } | |
501 } | |
502 } | |
503 | |
504 /* | |
505 +--------------------------------------------------------------------+ | |
506 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
507 | STATE : code ROUTINE : srv_count_list | | |
508 +--------------------------------------------------------------------+ | |
509 | |
510 PURPOSE : This routine returns the count of the number of channels | |
511 set in the List | |
512 CSI-LLD section:4.1.1.3.11 | |
513 */ | |
514 | |
515 GLOBAL U16 srv_count_list(T_LIST *list) | |
516 { | |
517 U16 i; | |
518 U16 sum = 0; | |
519 | |
520 for(i=CHANNEL_0;i<CHANNEL_0_INTERNAL;i++) | |
521 { | |
522 if(srv_get_channel (list, i)) | |
523 { | |
524 sum++; | |
525 } | |
526 } | |
527 | |
528 return sum; | |
529 } | |
530 | |
531 /* | |
532 +--------------------------------------------------------------------+ | |
533 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
534 | STATE : code ROUTINE : srv_is_list_set | | |
535 +--------------------------------------------------------------------+ | |
536 | |
537 PURPOSE : This routine checks if any channel in the list is set | |
538 CSI-LLD section:4.1.1.3.11 | |
539 */ | |
540 | |
541 GLOBAL BOOL srv_is_list_set(T_LIST *list) | |
542 { | |
543 U8 i; | |
544 | |
545 for(i=0;i<T_LIST_MAX_SIZE;i++) | |
546 { | |
547 if(list->channels[i]) | |
548 { | |
549 return TRUE; | |
550 } | |
551 } | |
552 | |
553 return FALSE; | |
554 } | |
555 | |
556 /* | |
557 +--------------------------------------------------------------------+ | |
558 | PROJECT : GSM-PS (6147) MODULE : RR_SRV | | |
559 | STATE : code ROUTINE : srv_get_region_from_std | | |
560 +--------------------------------------------------------------------+ | |
561 | |
562 PURPOSE : This routine derived "region" from "std" | |
563 CSI-LLD section:4.1.1.3.11 | |
564 */ | |
565 GLOBAL U8 srv_get_region_from_std(U8 std) | |
566 { | |
567 U8 region = EUROPEAN_REGION; | |
568 | |
569 switch(std) | |
570 { | |
571 case STD_850: | |
572 case STD_1900: | |
573 case STD_DUAL_US: | |
574 region = AMERICAN_REGION; | |
575 break; | |
576 } | |
577 | |
578 return region; | |
579 } | |
580 | |
581 #endif /* !CL_LIST_C */ | |
582 |