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