FreeCalypso > hg > fc-magnetite
comparison src/aci2/alr/alr_nc.c @ 3:93999a60b835
src/aci2, src/condat2: import of g23m/condat source pieces from TCS211
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 26 Sep 2016 00:29:36 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:c41a534f33c6 | 3:93999a60b835 |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : GSM-PS | |
4 | Modul : ALR_NC | |
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 Modul defines the SDL process Idle_Neighbour_Cells. | |
18 +----------------------------------------------------------------------------- | |
19 */ | |
20 | |
21 #ifndef ALR_NC_C | |
22 #define ALR_NC_C | |
23 | |
24 #define ENTITY_PL | |
25 | |
26 /*==== INCLUDES ===================================================*/ | |
27 #include <string.h> | |
28 #include <stdlib.h> | |
29 #include <limits.h> | |
30 #include <ctype.h> | |
31 #include "typedefs.h" | |
32 #include "message.h" | |
33 #include "ccdapi.h" | |
34 #include "vsi.h" | |
35 #include "custom.h" | |
36 #include "gsm.h" | |
37 #include "prim.h" | |
38 #include "cnf_alr.h" | |
39 #include "mon_alr.h" | |
40 #include "pei.h" | |
41 #include "tok.h" | |
42 #include "pcm.h" | |
43 #ifdef GPRS | |
44 #include "alr_gprs.h" | |
45 #endif | |
46 | |
47 #if !defined(NTRACE) | |
48 #define TRACING | |
49 #endif /* !TRACING */ | |
50 | |
51 #include "alr.h" | |
52 #include "alr_em.h" | |
53 | |
54 #if !defined(NTRACE) && defined(TRACING) | |
55 LOCAL const char *nc_get_nc_state_str(UBYTE status); | |
56 LOCAL const char * const alr_nc_state_trc[18] = { | |
57 "INACT", | |
58 "IDLE", | |
59 "RD_BCCH", | |
60 "FB_SB_SYNC", | |
61 "FB_SB_FAIL", | |
62 "RD_FB_SB", | |
63 "RD_SB", | |
64 "IDLE_SYNC", | |
65 "EXCL", | |
66 "FB_SB_SYNC_RR", | |
67 "RD_SB_BCCH", | |
68 "RD_BCCH_P", | |
69 "RD_FB_SB_P", | |
70 "RD_SB_P", | |
71 "RD_SB_BCCH_P", | |
72 "RD_BCCH_RR", | |
73 "RD_BCCH_P_RR", | |
74 "???"}; | |
75 #endif /* !NTRACE && TRACING */ | |
76 LOCAL const UBYTE unc_values[] = | |
77 { | |
78 2, 4, 8, 12, 16, 22, 30, NOT_PRESENT_8BIT | |
79 }; | |
80 /*==== EXPORT =====================================================*/ | |
81 | |
82 /*==== PRIVAT =====================================================*/ | |
83 LOCAL void nc_update_ba_list (USHORT serving_cell, | |
84 T_MPH_NEIGHBOURCELL_REQ * ncell_list); | |
85 LOCAL UBYTE nc_remove_channel_from_ba_list (USHORT index); | |
86 LOCAL UBYTE nc_is_in_ncell_list (USHORT channel, | |
87 T_MPH_NEIGHBOURCELL_REQ * ncell_list); | |
88 LOCAL void nc_process_status (void); | |
89 LOCAL void nc_process_status_sync (void); | |
90 LOCAL void nc_process_status_last_bsic (void); | |
91 LOCAL void nc_process_status_bcch (void); | |
92 LOCAL BOOL nc_ncell_in_plmn_permitted (UBYTE bsic); | |
93 LOCAL void nc_find_cells (USHORT * c_found, | |
94 USHORT max, | |
95 UBYTE limitation, | |
96 UBYTE min_rxlev); | |
97 LOCAL void nc_store_rxlev (T_MPHC_RXLEV_PERIODIC_IND * report); | |
98 LOCAL void nc_rank_ncells (void); | |
99 LOCAL void nc_check_status (UBYTE start_list); | |
100 LOCAL void nc_build_rr_report_dedi (T_MPH_MEASUREMENT_IND * rr_report); | |
101 | |
102 LOCAL void nc_store_dedicated (T_MPHC_MEAS_REPORT * report); | |
103 LOCAL UBYTE nc_convert_quality (USHORT errors, | |
104 USHORT total); | |
105 LOCAL void nc_store_bcch (T_MPHC_DATA_IND * data_ind, | |
106 USHORT index, | |
107 UBYTE which); | |
108 LOCAL void nc_stop_bcch (USHORT index, | |
109 UBYTE new_status); | |
110 LOCAL void nc_stop_sync (USHORT index, | |
111 UBYTE new_status); | |
112 LOCAL void nc_clean_store_bcch (USHORT index); | |
113 LOCAL UBYTE nc_check_bsic (USHORT index, | |
114 UBYTE bsic); | |
115 #if 0 | |
116 #if !defined(NTRACE) && defined(TRACING) | |
117 LOCAL UBYTE nc_get_status (USHORT index); | |
118 #endif /* !NTRACE && TRACING */ | |
119 #endif /* 0|1 */ | |
120 LOCAL void nc_restart_bcch (USHORT index); | |
121 LOCAL void nc_set_fb_sb_sync_initial (USHORT index); | |
122 LOCAL void nc_set_fb_sb_failed (USHORT index, | |
123 UBYTE c_sync); | |
124 LOCAL UBYTE nc_sys_info_78_required (USHORT index); | |
125 LOCAL void nc_sync_failed_attempt (USHORT index); | |
126 LOCAL void nc_sync_failed_attempt_dedicated(USHORT index); | |
127 LOCAL void nc_build_rr_report (T_MPH_MEASUREMENT_IND* rr_report); | |
128 LOCAL void nc_release_bcch (void); | |
129 LOCAL void nc_find_list_cells (void); | |
130 LOCAL void nc_ncell_list_req (void); | |
131 LOCAL void nc_start_eotd_confirm (void); | |
132 LOCAL void nc_process_pos_req (T_MPH_NCELL_POS_REQ* pos_req); | |
133 LOCAL void nc_check_sync_ind_eotd (T_MPHC_NCELL_SYNC_IND* sync_ind, | |
134 USHORT arfcn); | |
135 LOCAL void nc_store_eotd (T_eotd_sc_res* p_res, | |
136 T_MPHC_NCELL_SYNC_IND* sync_ind, | |
137 USHORT arfcn); | |
138 LOCAL void nc_sync_ind_last_bsic_req (T_MPHC_NCELL_SYNC_IND* sync_ind, | |
139 USHORT index, | |
140 USHORT arfcn, | |
141 UBYTE bsic); | |
142 LOCAL void nc_sync_ind_ncell (T_MPHC_NCELL_SYNC_IND* sync_ind, | |
143 USHORT index, | |
144 USHORT arfcn, | |
145 UBYTE bsic); | |
146 LOCAL void nc_clear_last_bsic (void); | |
147 #if 0 | |
148 Symbol 'nc_stop_all_bcch(void)' 'nc_stop_all_sync(void)' and not referenced at the moment | |
149 LOCAL void nc_stop_all_bcch (void); | |
150 LOCAL void nc_stop_all_sync (void); | |
151 #endif /* 0|1 */ | |
152 LOCAL void nc_stop_all (void); | |
153 LOCAL void nc_stop_all_inactive (void); | |
154 LOCAL void nc_stop_if_active (USHORT i); | |
155 LOCAL void nc_ncell_list_req_pos (T_ncell_list* p_ncell_list, | |
156 T_ncell_eotd* asd_cell, | |
157 USHORT arfcn); | |
158 LOCAL void nc_get_timing_eotd (T_ncell_list* p_ncell_list, | |
159 T_ncell_eotd* asd_cell); | |
160 | |
161 LOCAL BOOL nc_is_sync (T_NC * p_ncell); | |
162 LOCAL void nc_build_sync_req (USHORT index); | |
163 LOCAL void nc_init_pos_ind (USHORT req_id); | |
164 LOCAL void nc_enable_conf (void); | |
165 LOCAL void nc_disable_conf (BOOL bFree); | |
166 LOCAL void nc_start_ncell_confirm (void); | |
167 LOCAL void nc_handle_new_strong_cells (void); | |
168 LOCAL void nc_check_new_strong_cell (USHORT index, UBYTE o_1of6, UBYTE rxlev); | |
169 #ifdef GPRS | |
170 LOCAL void nc_rxlev_sc_req (UBYTE rxlev); | |
171 LOCAL void nc_inform_grr_of_ncell (USHORT index, | |
172 UBYTE type); | |
173 LOCAL void remove_ncell_and_inform_grr (USHORT index); | |
174 LOCAL void nc_sync_failed_gprs (USHORT index); | |
175 LOCAL void nc_check_bsic_pbcch(T_MPH_NEIGHBOURCELL_REQ* ncell_list); | |
176 LOCAL void nc_process_status_sync_gprs(void); | |
177 #endif /* #ifdef GPRS */ | |
178 | |
179 #if defined(_SIMULATION_) | |
180 LOCAL void trace_nc(void); | |
181 #endif /* _SIMULATION_ */ | |
182 LOCAL void nc_start_ncsync (void); | |
183 | |
184 /*==== CONSTANTS ==================================================*/ | |
185 #define MAX_L1_SYNC_CNT 12 | |
186 #define MAX_L1_BCCH_CNT 6 | |
187 #define MAX_L1_SYNC_EOTD_CNT 14 | |
188 #define MAX_RR_NCELL_CNT 6 | |
189 | |
190 #define ONLY_BCC 7 | |
191 #define ONLY_BSIC 63 | |
192 | |
193 #define NC_CHECK_OK 0 | |
194 #define NC_CHECK_NCC_FAILED 1 | |
195 #define NC_CHECK_BSIC_CHANGED 2 | |
196 | |
197 #define CHECK_FOR_ACQUIRE_AND_BCCH_AND_FAIL 0 | |
198 #define CHECK_FOR_CONFIRM 1 | |
199 | |
200 #define DONT_FREE_POS_IND 0 | |
201 #define FREE_POS_IND 1 | |
202 | |
203 /* | |
204 * Counter to realize a time interval of 10sec in terms of Control Multiframe | |
205 * Idle state : 42 * 51 * 4.615ms = 9885ms | |
206 * Dedicated State : 42 * 104/2 * 4.615ms = 10079ms | |
207 */ | |
208 #define TEN_SECONDS_NCSYNC 42 | |
209 | |
210 #define TEN_SECONDS 1 | |
211 #define TWENTY_SECONDS 2 | |
212 #define THIRTY_SECONDS 3 | |
213 #define FIVE_MINUTES 30 | |
214 #define C_INVALID_SYNC (THIRTY_SECONDS+1) | |
215 /* +2 for rounding BCCH reading to confirmation boundary */ | |
216 #define C_INVALID_BCCH (FIVE_MINUTES+2+1) | |
217 | |
218 #ifdef GPRS | |
219 #define GRR_SB_FOUND (MPH_BSIC_UNKNOWN+1) | |
220 #define GRR_SB_NOT_FOUND NOT_PRESENT_8BIT | |
221 #define GRR_SB_UNKNOWN MPH_BSIC_UNKNOWN | |
222 #endif | |
223 | |
224 /*==== VARIABLES ==================================================*/ | |
225 | |
226 /*==== FUNCTIONS ==================================================*/ | |
227 #if defined (WIN32) && !defined (_SIMULATION_) | |
228 #define _SIMULATION_ | |
229 #endif | |
230 | |
231 #if defined (_SIMULATION_) | |
232 #define TRACING | |
233 #endif /* _SIMULATION_ */ | |
234 | |
235 /* | |
236 * some traces | |
237 */ | |
238 #if defined (TRACING) | |
239 #define ALR_TRACE_NC(a) ALR_TRACE(a) | |
240 #define ALR_TRACE_NC_CNT(a,b) TRACE_EVENT_P2 ("[%4u] c_sync %d", \ | |
241 ARFCN_TO_G23(a)&ARFCN_MASK, b) | |
242 #define ALR_TRACE_NC_BSIC_CNF(a) TRACE_EVENT_P1 ("[%4u] NC BSIC CNF passed", \ | |
243 ARFCN_TO_G23(a)&ARFCN_MASK) | |
244 #define ALR_TRACE_NC_SB_FAILED(a) TRACE_EVENT_P1 ("[%4u] NCELL SB IND failed", \ | |
245 ARFCN_TO_G23(a)&ARFCN_MASK) | |
246 #define ALR_TRACE_NC_BSIC_REQ(a) TRACE_EVENT_P4 ("[%4u] NC BSIC REQ %d %d %d", \ | |
247 a&ARFCN_MASK, GET_STATE (STATE_NC), \ | |
248 alr_data->nc_data.cell[LAST_BSIC_REQ].status, \ | |
249 alr_data->nc_data.c_bcch_req) | |
250 #define ALR_TRACE_NC_BCCH_OK(f,m) TRACE_EVENT_P2 ("[%4u] NCELL BCCH IND passed msg:%d", \ | |
251 f&ARFCN_MASK,m) | |
252 #define ALR_TRACE_NC_SB_IND_PASSED(f) TRACE_EVENT_P1 ("[%4u] NCELL SB IND passed", \ | |
253 f&ARFCN_MASK) | |
254 #define ALR_TRACE_NC_RESELECT(a) TRACE_EVENT_P1 ("[%4u] start reselect", a&ARFCN_MASK) | |
255 #define ALR_TRACE_NC_FN_TA(_i,f,t) TRACE_EVENT_P3 ("i %d, fn %d, ta %d ", _i, f, t) | |
256 #if 0 | |
257 #define GET_NC_STATE(i) nc_get_status(i) | |
258 #endif /* 0|1 */ | |
259 #if defined(_SIMULATION_) | |
260 #define ALR_TRACE_ALL_NC() trace_nc() | |
261 #else /* _SIMULATION_ */ | |
262 #define ALR_TRACE_ALL_NC() | |
263 #endif /* _SIMULATION_ */ | |
264 #else /* TRACING */ | |
265 #define ALR_TRACE_NC(a) | |
266 #define ALR_TRACE_NC_CNT(a,b) | |
267 #define ALR_TRACE_NC_BSIC_CNF(a) | |
268 #define ALR_TRACE_NC_SB_FAILED(a) | |
269 #define ALR_TRACE_NC_BSIC_REQ(a) | |
270 #define ALR_TRACE_NC_BCCH_OK(f,m) | |
271 #define ALR_TRACE_NC_SB_IND_PASSED(f) | |
272 #define ALR_TRACE_NC_RESELECT(a) | |
273 #define ALR_TRACE_NC_FN_TA(i,f,t) | |
274 #define GET_NC_STATE(i) alr_data->nc_data.cell[i].status | |
275 #define ALR_TRACE_ALL_NC() | |
276 #undef TRACE_EVENT | |
277 #undef TRACE_EVENT_P1 | |
278 #undef TRACE_EVENT_P2 | |
279 #undef TRACE_EVENT_P3 | |
280 #undef TRACE_EVENT_P4 | |
281 #undef TRACE_EVENT_P5 | |
282 #undef TRACE_EVENT_P6 | |
283 #undef TRACE_EVENT_P7 | |
284 #undef TRACE_EVENT_P8 | |
285 #undef TRACE_EVENT_P9 | |
286 #define TRACE_EVENT(s) | |
287 #define TRACE_EVENT_P1(s,a) | |
288 #define TRACE_EVENT_P2(s,a,b) | |
289 #define TRACE_EVENT_P3(s,a,b,c) | |
290 #define TRACE_EVENT_P4(s,a,b,c,d) | |
291 #define TRACE_EVENT_P5(s,a,b,c,d,e) | |
292 #define TRACE_EVENT_P6(s,a,b,c,d,e,f) | |
293 #define TRACE_EVENT_P7(s,a,b,c,d,e,f,g) | |
294 #define TRACE_EVENT_P8(s,a,b,c,d,e,f,g,h) | |
295 #define TRACE_EVENT_P9(s,a,b,c,d,e,f,g,h,i) | |
296 #endif /* TRACING */ | |
297 | |
298 /* | |
299 +--------------------------------------------------------------------+ | |
300 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
301 | STATE : code ROUTINE : nc_init | | |
302 +--------------------------------------------------------------------+ | |
303 | |
304 PURPOSE : Initialize Idle Neighbour Cell Process. | |
305 | |
306 */ | |
307 GLOBAL void nc_init (void) | |
308 { | |
309 nc_stop_all(); | |
310 alr_data->nc_data.c_ba_arfcn = 0; | |
311 alr_data->nc_data.ba_id = ALR_BA_LOW; | |
312 alr_data->nc_data.sc_included = FALSE; | |
313 alr_data->nc_data.cell[LAST_BSIC_REQ].status = IDLE; | |
314 alr_data->nc_data.cell[LAST_BSIC_REQ].ba_arfcn = NOT_PRESENT_16BIT; | |
315 alr_data->nc_data.c_reports = (UBYTE)-1; | |
316 alr_data->nc_data.cr_cell.ba_arfcn = NOT_PRESENT_16BIT; | |
317 alr_data->nc_data.tim_state = NC_TIM_STOPPED; | |
318 alr_data->nc_data.c_nc_timer = 0; | |
319 if (alr_data->nc_data.ppos_ind NEQ NULL) | |
320 { | |
321 PFREE(alr_data->nc_data.ppos_ind); | |
322 alr_data->nc_data.ppos_ind = NULL; | |
323 } | |
324 if (alr_data->nc_data.ppos_req NEQ NULL) | |
325 { | |
326 PFREE(alr_data->nc_data.ppos_req); | |
327 alr_data->nc_data.ppos_req = NULL; | |
328 } | |
329 | |
330 /* Initialize the counter for realizing 10sec timer value */ | |
331 alr_data->nc_data.c_ncsync_tim = 0; | |
332 alr_data->nc_data.ncsync_start_tim = 0; | |
333 | |
334 SET_STATE(STATE_NC_PROC, NC_ACQUIRE); | |
335 SET_STATE(STATE_NC, NC_NULL); | |
336 } | |
337 | |
338 #ifdef GPRS | |
339 /* | |
340 +----------------------------------------------------------------------+ | |
341 | PROJECT : GSM-PS (6103) MODULE : ALR_GPRS | | |
342 | STATE : code ROUTINE : nc_start_pbcch| | |
343 +----------------------------------------------------------------------+ | |
344 | |
345 PURPOSE :Checks whether pbcch is available and sets a relevant state. | |
346 | |
347 */ | |
348 | |
349 GLOBAL void nc_start_pbcch(void) | |
350 { | |
351 if(alr_data->gprs_data.ptm AND | |
352 alr_data->gprs_data.pbcch) | |
353 { | |
354 SET_STATE(STATE_NC, NC_PTM_PBCCH); | |
355 } | |
356 else if(alr_data->gprs_data.pbcch) | |
357 { | |
358 SET_STATE(STATE_NC, NC_PIM_PBCCH); | |
359 } | |
360 | |
361 nc_enable_conf(); | |
362 nc_process_status(); | |
363 } | |
364 | |
365 /* | |
366 +--------------------------------------------------------------------+ | |
367 | PROJECT : GSM-PS (6103) MODULE : ALR_GPRS | | |
368 | STATE : code ROUTINE : gprs_check_bsic_pbcch | | |
369 +--------------------------------------------------------------------+ | |
370 | |
371 PURPOSE : | |
372 | |
373 */ | |
374 LOCAL void nc_check_bsic_pbcch(T_MPH_NEIGHBOURCELL_REQ* ncell_list) | |
375 { | |
376 TRACE_EVENT("gprs_alr_check_bsic_pbcch"); | |
377 if(!alr_data->gprs_data.pbcch) return; | |
378 | |
379 if(ncell_list->sync_only EQ SYNC_LIST) | |
380 { | |
381 | |
382 USHORT n_rr; /* index of RR neighbor cell list */ | |
383 USHORT n_alr; /* index of ALR neighbor cell list */ | |
384 UBYTE last_alr; /* last index of ALR neighbor cell list */ | |
385 USHORT arfcn; | |
386 TRACE_EVENT("pbcch/check bsic"); | |
387 | |
388 /* | |
389 * remove all channels which are not longer member of the | |
390 * neighbour cell list. | |
391 */ | |
392 last_alr = alr_data->nc_data.c_ba_arfcn; /* current last index */ | |
393 for (n_alr = 0; n_alr < last_alr; n_alr++) | |
394 { | |
395 arfcn = alr_data->nc_data.cell[n_alr].ba_arfcn; | |
396 if (!nc_is_in_ncell_list (arfcn, ncell_list)) | |
397 /* AND | |
398 (arfcn NEQ alr_data->serving_cell))*/ | |
399 { | |
400 switch(alr_data->nc_data.cell[n_alr].status) | |
401 { | |
402 case READ_FB_SB: | |
403 case READ_FB_SB_PENDING: | |
404 case READ_SB_PENDING: | |
405 case READ_SB: | |
406 case READ_SB_BCCH: /* in case we come from BCCH */ | |
407 case INACTIVE: /* in case we returned from DEDIC */ | |
408 case IDLE: /* in case we returned from DEDIC */ | |
409 case EXCLUDED: /* in case we returned from DEDIC */ | |
410 TRACE_EVENT_P1("rem cell i%d",n_alr); | |
411 remove_ncell_and_inform_grr(n_alr); | |
412 last_alr = alr_data->nc_data.c_ba_arfcn; | |
413 n_alr--; | |
414 break; | |
415 case FB_SB_SYNC_RR_NOT_INFORMED: | |
416 case READ_BCCH_RR_NOT_INFORMED: | |
417 case READ_BCCH: | |
418 case FB_SB_SYNC: | |
419 case IDLE_SYNC: | |
420 case FB_SB_FAILED: | |
421 /*state change will be done with check_status*/ | |
422 TRACE_EVENT_P1("i%d reset 1o6", n_alr); | |
423 alr_data->nc_data.cell[n_alr].one_of_six = FALSE; | |
424 alr_data->nc_data.cell[n_alr].one_of_twelve = FALSE; | |
425 break; | |
426 default: | |
427 TRACE_EVENT_P3("i%d,arfcn:%d illegal status %d",n_alr, | |
428 alr_data->nc_data.cell[n_alr].ba_arfcn, | |
429 alr_data->nc_data.cell[n_alr].status); | |
430 break; | |
431 } | |
432 } | |
433 else | |
434 { /* ncell is in both lists */ | |
435 switch(alr_data->nc_data.cell[n_alr].status) | |
436 { | |
437 case READ_FB_SB: | |
438 // case READ_FB_SB_PENDING: | |
439 //case READ_SB_PENDING: | |
440 case READ_SB: | |
441 break; | |
442 case READ_SB_BCCH: /* in case we come from BCCH */ | |
443 nc_set_status(n_alr, READ_SB); | |
444 break; | |
445 case INACTIVE: /* in case we returned from DEDIC */ | |
446 case IDLE: /* in case we returned from DEDIC */ | |
447 case EXCLUDED: /* in case we returned from DEDIC */ | |
448 nc_set_status (n_alr, INACTIVE); | |
449 /* ALR does not receive measurements */ | |
450 /* set them to idle */ | |
451 nc_set_status (n_alr, IDLE); | |
452 /* and set it to one_of_six , the rest is done by check_status */ | |
453 nc_set_status(n_alr, READ_FB_SB); | |
454 break; | |
455 case FB_SB_SYNC_RR_NOT_INFORMED: | |
456 case READ_BCCH_RR_NOT_INFORMED: | |
457 case READ_BCCH: | |
458 nc_set_status(n_alr, FB_SB_SYNC); | |
459 break; | |
460 default: | |
461 break; | |
462 } | |
463 alr_data->nc_data.cell[n_alr].one_of_six = FALSE; | |
464 alr_data->nc_data.cell[n_alr].one_of_twelve = TRUE; | |
465 } | |
466 } | |
467 | |
468 /* | |
469 * add all new channels. | |
470 */ | |
471 for (n_rr = 0; | |
472 (n_rr < MAX_NEIGHBOURCELLS) AND (last_alr < BA_LIST_SIZE-1); | |
473 n_rr++) | |
474 { | |
475 arfcn = ncell_list->arfcn[n_rr]; | |
476 if (arfcn EQ NOT_PRESENT_16BIT) | |
477 break; /* no more entries in the RR ncell_list */ | |
478 | |
479 n_alr = nc_get_index (arfcn); | |
480 | |
481 if (((n_alr EQ NOT_PRESENT_16BIT) OR (n_alr EQ LAST_BSIC_REQ)) AND | |
482 (arfcn NEQ alr_data->serving_cell)) | |
483 { | |
484 T_NC* pcell = &alr_data->nc_data.cell[last_alr]; | |
485 | |
486 #if defined(TRACING) | |
487 TRACE_EVENT_P2 ("NC%u[%u] add", last_alr, arfcn); | |
488 #endif /* TRACING */ | |
489 pcell->ba_arfcn = arfcn; | |
490 nc_set_status (last_alr, INACTIVE); | |
491 /* ALR does not receive measurements */ | |
492 /* set them to idle */ | |
493 nc_set_status (last_alr, IDLE); | |
494 /* and set it to one_of_six , the rest is done by check_status */ | |
495 alr_data->nc_data.cell[last_alr].one_of_six = FALSE; | |
496 alr_data->nc_data.cell[last_alr].one_of_twelve = TRUE; | |
497 alr_data->nc_data.cell[last_alr].ba_status = IN_BA; | |
498 last_alr++; /* increment last index */ | |
499 } | |
500 } | |
501 alr_data->nc_data.c_ba_arfcn = last_alr; /* store new last index */ | |
502 ALR_TRACE_ALL_NC (); | |
503 | |
504 { | |
505 UBYTE six=0; | |
506 last_alr = alr_data->nc_data.c_ba_arfcn; /* current last index */ | |
507 for (n_alr = 0; n_alr < last_alr; n_alr++) | |
508 { | |
509 six += alr_data->nc_data.cell[n_alr].one_of_six; | |
510 } | |
511 /*XXX change this to handle 12 ncells */ | |
512 if(six > 6) | |
513 { | |
514 TRACE_ERROR("more then six candidates!"); | |
515 } | |
516 } | |
517 #if 0 /*only for easing debugging */ | |
518 /* | |
519 * Reorder the entries. The goal is that the propably strongest neigbour | |
520 * cells | |
521 * are measured in the first measurement period of a subsequent | |
522 * MPHC_RXLEV_PERIODIC_REQ/IND. The appropriate arfcn's are the first | |
523 * ones in | |
524 * ncell_list->arfcn | |
525 */ | |
526 { | |
527 T_NC temp, *prr, *palr; | |
528 | |
529 for (n_rr = 0; n_rr < 7; n_rr++) | |
530 { | |
531 if(ncell_list->arfcn[n_rr] NEQ NOT_PRESENT_16BIT) | |
532 n_alr = nc_get_index (ncell_list->arfcn[n_rr]); | |
533 else | |
534 break; | |
535 | |
536 if ( ((n_alr NEQ NOT_PRESENT_16BIT) OR (n_alr NEQ LAST_BSIC_REQ)) AND | |
537 n_rr NEQ n_alr) | |
538 { | |
539 palr = &(alr_data->nc_data.cell[n_alr]); | |
540 prr = &(alr_data->nc_data.cell[n_rr]); | |
541 memcpy(&temp, palr, sizeof(T_NC)); | |
542 memcpy(palr, prr, sizeof(T_NC)); | |
543 memcpy(prr, &temp, sizeof(T_NC)); | |
544 /*TRACE_EVENT_P4("reordered NC%u[%u] and NC%u[%u]", | |
545 n_rr, | |
546 ncell_list->arfcn[n_rr], | |
547 n_alr, ncell_list->arfcn[n_alr]);*/ | |
548 } | |
549 } | |
550 } | |
551 #endif | |
552 nc_check_status(CHECK_FOR_ACQUIRE_AND_BCCH_AND_FAIL); | |
553 | |
554 if(alr_data->nc_sync_with_grr) | |
555 { | |
556 TRACE_EVENT("sync_with_grr"); | |
557 last_alr = alr_data->nc_data.c_ba_arfcn; /* current last index */ | |
558 for (n_alr = 0; n_alr < last_alr; n_alr++) | |
559 { | |
560 switch(alr_data->nc_data.cell[n_alr].status) | |
561 { | |
562 case IDLE_SYNC: | |
563 case FB_SB_SYNC: | |
564 case READ_SB: | |
565 case READ_SB_PENDING: | |
566 case READ_FB_SB_PENDING: | |
567 TRACE_EVENT_P1("sync %d",alr_data->nc_data.cell[n_alr].ba_arfcn); | |
568 nc_inform_grr_of_ncell(n_alr, GRR_SB_FOUND); | |
569 break; | |
570 case FB_SB_FAILED: | |
571 case EXCLUDED: | |
572 case INACTIVE: | |
573 case IDLE: | |
574 TRACE_EVENT_P1("sync %d",alr_data->nc_data.cell[n_alr].ba_arfcn); | |
575 nc_inform_grr_of_ncell(n_alr, GRR_SB_NOT_FOUND); | |
576 break; | |
577 /* READ_FB_SB ->the cell will be synchronized next | |
578 and a result will be returnded anyway */ | |
579 default: | |
580 break; | |
581 } | |
582 } | |
583 alr_data->nc_sync_with_grr=FALSE; | |
584 } | |
585 | |
586 switch(GET_STATE(STATE_NC)) | |
587 { | |
588 case NC_PIM_PBCCH: | |
589 case NC_PTM_PBCCH: | |
590 nc_process_status(); | |
591 break; | |
592 default: | |
593 break; | |
594 } | |
595 } | |
596 else if(ncell_list->sync_only EQ RECONFIRM_SYNC_LIST) | |
597 { | |
598 nc_ncsync_tim_expiry(); | |
599 } | |
600 | |
601 } | |
602 | |
603 #endif | |
604 /* | |
605 +--------------------------------------------------------------------+ | |
606 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
607 | STATE : code ROUTINE : nc_stop | | |
608 +--------------------------------------------------------------------+ | |
609 | |
610 PURPOSE : stop the neighbourcell process. Is called by main process | |
611 if a recovery with power measurements is started. | |
612 | |
613 */ | |
614 | |
615 GLOBAL void nc_stop (void) | |
616 { | |
617 /* | |
618 * clean or neighbourcells of the BA and LAST_BSIC_REQ list if needed | |
619 */ | |
620 nc_stop_all_inactive(); | |
621 | |
622 /* | |
623 * initialize neighbourcell process and stops timer | |
624 */ | |
625 nc_init(); | |
626 } | |
627 | |
628 /* | |
629 +--------------------------------------------------------------------+ | |
630 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
631 | STATE : code ROUTINE : nc_stop_all_inactive | | |
632 +--------------------------------------------------------------------+ | |
633 | |
634 PURPOSE : This stops all activities to bring a channel to state NC_NULL. | |
635 | |
636 */ | |
637 | |
638 LOCAL void nc_stop_all_inactive (void) | |
639 { | |
640 UBYTE i, stopped_sync=0, stopped_bcch=0; | |
641 /* | |
642 * depending on the current status | |
643 */ | |
644 for (i = 0; i < alr_data->nc_data.c_ba_arfcn; i++) | |
645 { | |
646 switch (alr_data->nc_data.cell[i].status) | |
647 { | |
648 case READ_FB_SB_PENDING: | |
649 case READ_SB_PENDING: | |
650 case READ_SB_BCCH_PENDING: | |
651 /* | |
652 * stop the current running request for synchronisation in layer 1. | |
653 */ | |
654 nc_set_status (i, INACTIVE); | |
655 stopped_sync++; | |
656 break; | |
657 | |
658 case READ_BCCH_PENDING: | |
659 case READ_BCCH_PENDING_RR_NOT_INFORMED: | |
660 /* | |
661 * stop the current running request for BCCH reading in layer 1. | |
662 * If sys info 4 is already stored, but sys info 7 or 8 is requested | |
663 * clear also a stored BCCH message. | |
664 */ | |
665 nc_set_status (i, INACTIVE); | |
666 stopped_bcch++; | |
667 break; | |
668 default: | |
669 /* | |
670 * sys infos are stored, but RR is still not informed. | |
671 * Then clean the stored message | |
672 */ | |
673 nc_set_status (i, INACTIVE); | |
674 break; | |
675 } | |
676 } | |
677 switch (alr_data->nc_data.cell[LAST_BSIC_REQ].status) | |
678 { | |
679 case READ_FB_SB_PENDING: | |
680 nc_set_status (LAST_BSIC_REQ, IDLE); | |
681 alr_data->nc_data.cell[LAST_BSIC_REQ].ba_arfcn = NOT_PRESENT_16BIT; | |
682 stopped_sync++; | |
683 break; | |
684 case READ_BCCH_PENDING: | |
685 nc_set_status (LAST_BSIC_REQ, IDLE); | |
686 alr_data->nc_data.cell[LAST_BSIC_REQ].ba_arfcn = NOT_PRESENT_16BIT; | |
687 stopped_bcch++; | |
688 break; | |
689 } | |
690 | |
691 /*send to L1*/ | |
692 if (stopped_sync > 0) | |
693 { /* stop all synchronizations */ | |
694 PALLOC (stop_req, MPHC_STOP_NCELL_SYNC_REQ); | |
695 stop_req->radio_freq_array_size = MAX_L1_SYNC_CNT; | |
696 PSENDX(L1, stop_req); | |
697 } | |
698 if (stopped_bcch > 0) | |
699 { /* stop all bcch */ | |
700 PALLOC (stop_req, MPHC_STOP_NCELL_BCCH_REQ); | |
701 stop_req->radio_freq_array_size = MAX_L1_BCCH_CNT; | |
702 PSENDX(L1, stop_req); | |
703 } | |
704 } | |
705 | |
706 /* | |
707 +--------------------------------------------------------------------+ | |
708 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
709 | STATE : code ROUTINE : nc_stop_all | | |
710 +--------------------------------------------------------------------+ | |
711 | |
712 PURPOSE : This stops all activities to bring a channel | |
713 its corresping READ_ state. | |
714 | |
715 */ | |
716 | |
717 LOCAL void nc_stop_all (void) | |
718 { | |
719 UBYTE i, stopped_sync=0, stopped_bcch=0; | |
720 /* | |
721 * depending on the current status | |
722 */ | |
723 for (i = 0; i < alr_data->nc_data.c_ba_arfcn; i++) | |
724 { | |
725 switch (alr_data->nc_data.cell[i].status) | |
726 { | |
727 case READ_FB_SB_PENDING: | |
728 nc_set_status (i, READ_FB_SB); | |
729 stopped_sync++; | |
730 break; | |
731 case READ_SB_PENDING: | |
732 nc_set_status (i, READ_SB); | |
733 stopped_sync++; | |
734 break; | |
735 case READ_SB_BCCH_PENDING: | |
736 nc_set_status (i, READ_SB_BCCH); | |
737 stopped_sync++; | |
738 break; | |
739 case READ_BCCH_PENDING: | |
740 nc_set_status (i, READ_BCCH); | |
741 stopped_bcch++; | |
742 break; | |
743 case READ_BCCH_PENDING_RR_NOT_INFORMED: | |
744 nc_set_status (i, READ_BCCH_RR_NOT_INFORMED); | |
745 stopped_bcch++; | |
746 break; | |
747 case FB_SB_SYNC_RR_NOT_INFORMED: | |
748 nc_set_status (i, READ_BCCH_RR_NOT_INFORMED); | |
749 break; | |
750 } | |
751 } | |
752 switch (alr_data->nc_data.cell[LAST_BSIC_REQ].status) | |
753 { | |
754 case READ_FB_SB_PENDING: | |
755 nc_set_status (LAST_BSIC_REQ, READ_FB_SB); | |
756 stopped_sync++; | |
757 break; | |
758 case READ_BCCH_PENDING: | |
759 nc_set_status (LAST_BSIC_REQ, READ_BCCH); | |
760 stopped_bcch++; | |
761 break; | |
762 } | |
763 /*send to L1*/ | |
764 if ( stopped_sync > 0 OR | |
765 alr_data->nc_data.c_sync_req > 0 OR | |
766 (alr_data->nc_data.eotd_avail AND GET_STATE(STATE_NC_PROC) EQ NC_CONFIRM)) | |
767 { /* stop all synchronizations if waiting for any NC synchronization (or 2nd SC in EOTD case) */ | |
768 PALLOC (stop_req, MPHC_STOP_NCELL_SYNC_REQ); | |
769 stop_req->radio_freq_array_size = MAX_L1_SYNC_CNT; | |
770 PSENDX(L1, stop_req); | |
771 alr_data->nc_data.c_sync_req=0; | |
772 if (alr_data->nc_data.eotd_avail) | |
773 SET_STATE(STATE_NC_PROC, NC_ACQUIRE); | |
774 } | |
775 if(stopped_bcch > 0) | |
776 { /* stop all bcch */ | |
777 PALLOC (stop_req, MPHC_STOP_NCELL_BCCH_REQ); | |
778 stop_req->radio_freq_array_size = MAX_L1_BCCH_CNT; | |
779 PSENDX(L1, stop_req); | |
780 alr_data->nc_data.c_bcch_req=0; | |
781 } | |
782 } | |
783 | |
784 #if 0 | |
785 Symbol 'nc_stop_all_bcch(void)' not referenced at the moment | |
786 /* | |
787 +--------------------------------------------------------------------+ | |
788 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
789 | STATE : code ROUTINE : nc_stop_all_sync | | |
790 +--------------------------------------------------------------------+ | |
791 | |
792 PURPOSE : This stops all sync activities. | |
793 | |
794 */ | |
795 LOCAL void nc_stop_all_sync (void) | |
796 { | |
797 UBYTE i, stopped_sync=0; | |
798 /* | |
799 * depending on the current status | |
800 */ | |
801 for (i = 0; i < alr_data->nc_data.c_ba_arfcn; i++) | |
802 { | |
803 switch (alr_data->nc_data.cell[i].status) | |
804 { | |
805 case READ_FB_SB_PENDING: | |
806 nc_set_status (i, READ_FB_SB); | |
807 stopped_sync++; | |
808 break; | |
809 case READ_SB_PENDING: | |
810 nc_set_status (i, READ_SB); | |
811 stopped_sync++; | |
812 break; | |
813 case READ_SB_BCCH_PENDING: | |
814 nc_set_status (i, READ_SB_BCCH); | |
815 stopped_sync++; | |
816 break; | |
817 } | |
818 } | |
819 switch (alr_data->nc_data.cell[LAST_BSIC_REQ].status) | |
820 { | |
821 case READ_FB_SB_PENDING: | |
822 nc_set_status (LAST_BSIC_REQ, READ_FB_SB); | |
823 stopped_sync++; | |
824 break; | |
825 } | |
826 /*send to L1*/ | |
827 if (stopped_sync > 0) | |
828 { /* stop all synchronizations */ | |
829 PALLOC (stop_req, MPHC_STOP_NCELL_SYNC_REQ); | |
830 stop_req->radio_freq_array_size = MAX_L1_SYNC_CNT; | |
831 PSENDX(L1, stop_req); | |
832 alr_data->nc_data.c_sync_req=0; | |
833 } | |
834 } | |
835 #endif /* 0|1 */ | |
836 | |
837 #if 0 | |
838 Symbol 'nc_stop_all_bcch(void)' not referenced at the moment | |
839 /* | |
840 +--------------------------------------------------------------------+ | |
841 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
842 | STATE : code ROUTINE : nc_stop_all_bcch | | |
843 +--------------------------------------------------------------------+ | |
844 | |
845 PURPOSE : This stops all activities to bring a channel to state NC_NULL. | |
846 | |
847 */ | |
848 LOCAL void nc_stop_all_bcch (void) | |
849 { | |
850 UBYTE i, stopped_bcch=0; | |
851 /* | |
852 * depending on the current status | |
853 */ | |
854 for (i = 0; i < alr_data->nc_data.c_ba_arfcn; i++) | |
855 { | |
856 switch (alr_data->nc_data.cell[i].status) | |
857 { | |
858 case READ_BCCH_PENDING_RR_NOT_INFORMED: | |
859 nc_set_status (i, READ_BCCH_RR_NOT_INFORMED); | |
860 stopped_bcch++; | |
861 break; | |
862 case READ_BCCH_PENDING: | |
863 nc_set_status (i, READ_BCCH); | |
864 stopped_bcch++; | |
865 break; | |
866 } | |
867 } | |
868 switch (alr_data->nc_data.cell[LAST_BSIC_REQ].status) | |
869 { | |
870 case READ_BCCH_PENDING: | |
871 nc_set_status (LAST_BSIC_REQ, READ_BCCH); | |
872 stopped_bcch++; | |
873 break; | |
874 } | |
875 /*send to L1*/ | |
876 if (stopped_bcch > 0) | |
877 { /* stop all bcch */ | |
878 PALLOC (stop_req, MPHC_STOP_NCELL_BCCH_REQ); | |
879 stop_req->radio_freq_array_size = MAX_L1_BCCH_CNT; | |
880 PSENDX(L1, stop_req); | |
881 alr_data->nc_data.c_bcch_req=0; | |
882 } | |
883 } | |
884 #endif /* 0|1 */ | |
885 | |
886 LOCAL void nc_clear_last_bsic(void) | |
887 { | |
888 switch (alr_data->nc_data.cell[LAST_BSIC_REQ].status) | |
889 { | |
890 case READ_BCCH_PENDING: | |
891 nc_stop_bcch (LAST_BSIC_REQ, IDLE); | |
892 break; | |
893 case READ_FB_SB_PENDING: | |
894 nc_stop_sync (LAST_BSIC_REQ, IDLE); | |
895 break; | |
896 } | |
897 | |
898 nc_set_status(LAST_BSIC_REQ, IDLE); | |
899 alr_data->nc_data.cell[LAST_BSIC_REQ].ba_arfcn = NOT_PRESENT_16BIT; | |
900 | |
901 } | |
902 | |
903 LOCAL void nc_stop_if_active(USHORT i) | |
904 { | |
905 /* | |
906 * the requested channel number is member of the BA list. | |
907 * clear a request to layer 1 if needed. | |
908 */ | |
909 switch(alr_data->nc_data.cell[i].status) | |
910 { | |
911 case READ_SB_PENDING: | |
912 nc_stop_sync (i, READ_SB); | |
913 break; | |
914 case READ_SB_BCCH_PENDING: | |
915 nc_stop_sync (i, READ_SB_BCCH); | |
916 break; | |
917 case READ_FB_SB_PENDING: | |
918 nc_stop_sync (i, READ_FB_SB); | |
919 break; | |
920 case READ_BCCH_PENDING: | |
921 nc_stop_bcch (i, READ_BCCH); | |
922 break; | |
923 case READ_BCCH_PENDING_RR_NOT_INFORMED: | |
924 nc_stop_bcch (i, READ_BCCH_RR_NOT_INFORMED); | |
925 break; | |
926 default: | |
927 break; | |
928 } | |
929 } | |
930 /* | |
931 +--------------------------------------------------------------------+ | |
932 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
933 | STATE : code ROUTINE : nc_ncell_list | | |
934 +--------------------------------------------------------------------+ | |
935 | |
936 PURPOSE : Reception of a new neighbourcell list from RR. | |
937 | |
938 */ | |
939 | |
940 GLOBAL void nc_ncell_list (T_MPH_NEIGHBOURCELL_REQ * mph_neighbourcell_req) | |
941 { | |
942 UBYTE i, j; | |
943 switch (GET_STATE (STATE_NC)) | |
944 { | |
945 case NC_DEDICATED: | |
946 { | |
947 UBYTE c_ba_arfcn; | |
948 PALLOC (upd_dedi, MPHC_UPDATE_BA_LIST); | |
949 | |
950 /* | |
951 * mix new list with old list | |
952 */ | |
953 nc_update_ba_list (alr_data->serving_cell, | |
954 mph_neighbourcell_req); | |
955 | |
956 /* | |
957 * create new list for layer 1 | |
958 */ | |
959 c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
960 for (i = 0, j = 0; i < c_ba_arfcn; i++) | |
961 { | |
962 if (alr_data->nc_data.cell[i].ba_status EQ IN_BA) | |
963 upd_dedi->chan_list.radio_freq[j++] = | |
964 ARFCN_TO_L1(alr_data->nc_data.cell[i].ba_arfcn); | |
965 } | |
966 | |
967 /* | |
968 * send new list to layer 1 | |
969 */ | |
970 upd_dedi->num_of_chans = j; | |
971 | |
972 alr_data->nc_data.ba_id = ALR_ALLOCATE_NEW_BA ( alr_data->nc_data.ba_id ); | |
973 upd_dedi->ba_id = alr_data->nc_data.ba_id; | |
974 | |
975 upd_dedi->pwrc = alr_data->nc_data.pwrc; | |
976 upd_dedi->dtx_allowed = alr_data->nc_data.dtx; | |
977 | |
978 alr_data->nc_data.update = TRUE; | |
979 ma_nc_update_ba_list (upd_dedi); | |
980 | |
981 } | |
982 break; | |
983 case NC_CON_EST: /*for PBCCH just update the list, is checked in | |
984 nc_check_bsic_pbcch */ | |
985 #ifdef GPRS | |
986 case NC_PIM_PBCCH: | |
987 case NC_PTM_PBCCH: | |
988 nc_check_bsic_pbcch(mph_neighbourcell_req); | |
989 #endif | |
990 break; | |
991 default: | |
992 /* | |
993 * idle mode | |
994 */ | |
995 ALR_TRACE_NC ("ncell req in idle"); | |
996 | |
997 /* | |
998 * mix new list with old list | |
999 */ | |
1000 nc_update_ba_list (alr_data->serving_cell, mph_neighbourcell_req); | |
1001 | |
1002 /* | |
1003 * configure layer 1 and start monitoring on new list | |
1004 */ | |
1005 nc_start_monitoring(); | |
1006 break; | |
1007 } | |
1008 } | |
1009 | |
1010 | |
1011 /* | |
1012 +--------------------------------------------------------------------+ | |
1013 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
1014 | STATE : code ROUTINE : nc_start_monitoring | | |
1015 +--------------------------------------------------------------------+ | |
1016 | |
1017 PURPOSE : Configure layer 1 with a new list for neighbourcell | |
1018 measurements. | |
1019 | |
1020 */ | |
1021 | |
1022 static const UBYTE NO_OF_REPORTS [8] = | |
1023 { | |
1024 10, 7, 5, 4, 3, 3, 2, 2 | |
1025 }; | |
1026 | |
1027 static const UBYTE INIT_OF_C_REPORTS [8] = | |
1028 { | |
1029 5, 5, 2, 2, 1, 1, 0, 0 /* empirical for FTA 20.7, 20.19, for TC 084, 047 */ | |
1030 }; | |
1031 | |
1032 static BOOL first_period = FALSE, first_l1_meas = FALSE; | |
1033 | |
1034 GLOBAL void nc_start_monitoring (void) | |
1035 { | |
1036 USHORT index, prim_index; | |
1037 UBYTE report_idx = alr_data->bs_pa_mfrms; | |
1038 UBYTE c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
1039 PALLOC (update, MPHC_RXLEV_PERIODIC_REQ); | |
1040 | |
1041 ALR_TRACE_NC ("nc_start_mon"); | |
1042 | |
1043 first_period = first_l1_meas = TRUE; | |
1044 | |
1045 alr_data->nc_data.max_reports = NO_OF_REPORTS [report_idx]; | |
1046 alr_data->nc_data.fn_offset = (report_idx+2) * NO_OF_REPORTS[report_idx] * 51; | |
1047 | |
1048 if (alr_data->nc_data.c_reports EQ (UBYTE)-1) /* initial value */ | |
1049 alr_data->nc_data.c_reports = INIT_OF_C_REPORTS [report_idx]; | |
1050 else /* don´t touch c_reports except for max_reports is less */ | |
1051 if (alr_data->nc_data.c_reports >= alr_data->nc_data.max_reports) | |
1052 alr_data->nc_data.c_reports = alr_data->nc_data.max_reports - 1; | |
1053 index = nc_get_index(alr_data->serving_cell); | |
1054 if (index NEQ NOT_PRESENT_16BIT) | |
1055 alr_data->nc_data.cell[index].c_rxlev = NOT_PRESENT_8BIT; | |
1056 | |
1057 /* | |
1058 * for all neighbourcells: convert channel number | |
1059 * and fill the primitive to layer 1. | |
1060 */ | |
1061 for (index = 0, prim_index = 0; index < c_ba_arfcn; index++) | |
1062 { | |
1063 if (alr_data->nc_data.cell[index].ba_status EQ IN_BA) | |
1064 update->chan_list.radio_freq[prim_index++] = | |
1065 ARFCN_TO_L1(alr_data->nc_data.cell[index].ba_arfcn); | |
1066 } | |
1067 | |
1068 /* | |
1069 * set number of channels and band id | |
1070 */ | |
1071 update->num_of_chans = (UBYTE)prim_index; | |
1072 alr_data->nc_data.ba_id = ALR_ALLOCATE_NEW_BA ( alr_data->nc_data.ba_id ); | |
1073 update->ba_id = alr_data->nc_data.ba_id; | |
1074 update->next_radio_freq_measured = 0; | |
1075 | |
1076 #if defined(_SIMULATION_) | |
1077 { | |
1078 char buf[80], o; | |
1079 o = sprintf (buf, "RXLEV_PERIODIC: c=%d id=%02x:", update->num_of_chans, update->ba_id); | |
1080 for (index=0; index < update->num_of_chans; index++) | |
1081 { | |
1082 if (o > 80-6) | |
1083 { | |
1084 TRACE_EVENT (buf); | |
1085 o = 0; | |
1086 } | |
1087 o += sprintf (buf+o, "%u,", update->chan_list.radio_freq[index]); | |
1088 } | |
1089 buf[o-1]=0; | |
1090 TRACE_EVENT (buf); | |
1091 } | |
1092 #endif /* _SIMULATION_ */ | |
1093 | |
1094 SET_STATE (STATE_NC, NC_IDLE); | |
1095 /* | |
1096 TRACE_EVENT_P2("glob reps: %d max_report: %d", | |
1097 alr_data->nc_data.c_reports, alr_data->nc_data.max_reports); | |
1098 */ | |
1099 | |
1100 /* | |
1101 * configure layer 1. | |
1102 */ | |
1103 ma_nc_rxlev_periodic_req(update); | |
1104 | |
1105 nc_enable_conf(); | |
1106 } | |
1107 /* | |
1108 +--------------------------------------------------------------------+ | |
1109 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
1110 | STATE : code ROUTINE : nc_enable_conf | | |
1111 +--------------------------------------------------------------------+ | |
1112 | |
1113 PURPOSE : Maintains what happens after 10 seconds interval. | |
1114 restarts a pending ncell confirmation | |
1115 */ | |
1116 LOCAL void nc_enable_conf(void) | |
1117 { | |
1118 UBYTE tim_state = alr_data->nc_data.tim_state; | |
1119 UBYTE st = GET_STATE(STATE_NC); | |
1120 | |
1121 TRACE_EVENT("nc_enable_conf()"); | |
1122 alr_data->nc_data.tim_state = NC_CONF_ENABLED; | |
1123 SET_STATE(STATE_NC_PROC, NC_ACQUIRE); | |
1124 switch(tim_state) | |
1125 { | |
1126 case NC_TIM_STOPPED: | |
1127 if (alr_data->nc_data.ppos_req) | |
1128 nc_process_pos_req (alr_data->nc_data.ppos_req); | |
1129 /* Load the 10sec timer counter variable */ | |
1130 nc_start_ncsync(); | |
1131 break; | |
1132 case NC_CONF_PENDING: | |
1133 if (alr_data->nc_data.ppos_req) | |
1134 nc_process_pos_req (alr_data->nc_data.ppos_req); | |
1135 else | |
1136 nc_start_ncell_confirm(); | |
1137 break; | |
1138 case NC_CONF_DISABLED: | |
1139 if (alr_data->nc_data.ppos_req) | |
1140 nc_process_pos_req (alr_data->nc_data.ppos_req); | |
1141 else if (alr_data->nc_data.c_nc_timer EQ 0) | |
1142 nc_start_ncell_confirm(); /* a confirmation is to restart */ | |
1143 break; | |
1144 default: | |
1145 break; | |
1146 } | |
1147 | |
1148 | |
1149 /*XXX add PBCCH here also */ | |
1150 #ifdef GPRS | |
1151 if ((st EQ NC_DEDICATED OR st EQ NC_PIM_PBCCH OR st EQ NC_PTM_PBCCH) AND | |
1152 #else | |
1153 if ((st EQ NC_DEDICATED) AND | |
1154 #endif | |
1155 alr_data->nc_data.c_nc_timer > TEN_SECONDS) | |
1156 { | |
1157 alr_data->nc_data.c_nc_timer = TEN_SECONDS; | |
1158 } | |
1159 else if (alr_data->nc_data.c_nc_timer EQ 0) | |
1160 { | |
1161 if( st EQ NC_DEDICATED OR alr_data->nc_data.eotd_avail | |
1162 #ifdef GPRS | |
1163 OR st EQ NC_PIM_PBCCH OR st EQ NC_PTM_PBCCH | |
1164 #endif | |
1165 ) | |
1166 alr_data->nc_data.c_nc_timer = TEN_SECONDS; | |
1167 else | |
1168 alr_data->nc_data.c_nc_timer = THIRTY_SECONDS; | |
1169 } | |
1170 } | |
1171 | |
1172 /* | |
1173 +--------------------------------------------------------------------+ | |
1174 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
1175 | STATE : code ROUTINE : nc_disable_conf | | |
1176 +--------------------------------------------------------------------+ | |
1177 | |
1178 PURPOSE : Maintains what happens after TIM_NCSYNC expiry. | |
1179 prevents ncell confirmation | |
1180 */ | |
1181 LOCAL void nc_disable_conf(BOOL bFree) | |
1182 { | |
1183 TRACE_EVENT("nc_disable_conf()"); | |
1184 switch(alr_data->nc_data.tim_state) | |
1185 { | |
1186 case NC_TIM_STOPPED: | |
1187 case NC_CONF_PENDING: | |
1188 TRACE_ERROR("nc_disable_conf() in unexpected state"); | |
1189 break; | |
1190 default: | |
1191 break; | |
1192 } | |
1193 | |
1194 if(bFree AND (alr_data->nc_data.ppos_ind NEQ NULL)) | |
1195 { | |
1196 PFREE(alr_data->nc_data.ppos_ind); | |
1197 alr_data->nc_data.ppos_ind = NULL; | |
1198 } | |
1199 | |
1200 if(GET_STATE(STATE_NC_PROC) EQ NC_CONFIRM) | |
1201 { | |
1202 /* | |
1203 * restart confirmation if it was aborted | |
1204 * after the first expiry after the POS_REQ is done. | |
1205 */ | |
1206 alr_data->nc_data.c_nc_timer = 0; | |
1207 } | |
1208 | |
1209 SET_STATE(STATE_NC_PROC, NC_ACQUIRE); | |
1210 alr_data->nc_data.tim_state = NC_CONF_DISABLED; | |
1211 } | |
1212 | |
1213 LOCAL void nc_start_ncell_confirm(void) | |
1214 { | |
1215 BOOL acquire = FALSE; | |
1216 | |
1217 switch(GET_STATE(STATE_NC)) | |
1218 { | |
1219 case NC_DEDICATED: | |
1220 case NC_IDLE: | |
1221 #ifdef GPRS | |
1222 case NC_PIM_PBCCH: | |
1223 case NC_PTM_PBCCH: | |
1224 #endif | |
1225 if (alr_data->nc_data.eotd_avail AND | |
1226 alr_data->nc_data.c_nc_timer EQ 0) | |
1227 { | |
1228 alr_data->nc_data.c_nc_timer = TEN_SECONDS; | |
1229 | |
1230 nc_stop_all(); | |
1231 nc_check_status(CHECK_FOR_CONFIRM); | |
1232 nc_start_eotd_confirm(); | |
1233 } | |
1234 else if ((alr_data->nc_data.c_nc_timer EQ 0) OR | |
1235 (alr_data->nc_data.c_sync_intrupted EQ TRUE) ) | |
1236 { | |
1237 /* | |
1238 * confirm ncells every thirty seconds in idle | |
1239 * or every 10 seconds in dedicated | |
1240 */ | |
1241 if (GET_STATE(STATE_NC) EQ NC_DEDICATED | |
1242 #ifdef GPRS | |
1243 OR GET_STATE(STATE_NC) EQ NC_PIM_PBCCH | |
1244 OR GET_STATE(STATE_NC) EQ NC_PTM_PBCCH | |
1245 #endif | |
1246 ) | |
1247 alr_data->nc_data.c_nc_timer = TEN_SECONDS; | |
1248 else | |
1249 alr_data->nc_data.c_nc_timer = THIRTY_SECONDS; | |
1250 nc_stop_all(); | |
1251 nc_check_status(CHECK_FOR_CONFIRM); | |
1252 nc_ncell_list_req(); | |
1253 /* if a list_req was send we are in NC_CONFIRM | |
1254 if no list_req was send we are in NC_ACQUIRE | |
1255 This is needed for PBCCH, because there are | |
1256 no measurements in ALR to trigger the initial | |
1257 synchronizations, so we have to check this here | |
1258 if no list_req was send, when a list_req was send | |
1259 then we continue with initial sync after the last | |
1260 sync_ind | |
1261 */ | |
1262 if(GET_STATE(STATE_NC_PROC) EQ NC_ACQUIRE) | |
1263 acquire = TRUE; | |
1264 | |
1265 } | |
1266 else /* acquire ncells (initial or previous failed ones) or | |
1267 * read bcch | |
1268 */ | |
1269 { | |
1270 acquire = TRUE; | |
1271 } | |
1272 | |
1273 if(acquire EQ TRUE) | |
1274 { | |
1275 SET_STATE(STATE_NC_PROC, NC_ACQUIRE); | |
1276 nc_check_status(CHECK_FOR_ACQUIRE_AND_BCCH_AND_FAIL); | |
1277 nc_process_status(); | |
1278 } | |
1279 break; | |
1280 default: | |
1281 TRACE_ERROR("nc_ncsync_tim_expiry in wrong state"); | |
1282 break; | |
1283 } | |
1284 } | |
1285 | |
1286 /* | |
1287 +--------------------------------------------------------------------+ | |
1288 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
1289 | STATE : code ROUTINE : nc_start_ncsync | | |
1290 +--------------------------------------------------------------------+ | |
1291 PURPOSE : Assigns/resets c_ncsync_tim counter | |
1292 */ | |
1293 LOCAL void nc_start_ncsync (void) | |
1294 { | |
1295 alr_data->nc_data.c_ncsync_tim = TEN_SECONDS_NCSYNC; | |
1296 TRACE_EVENT("NCSYNC counter loaded with 10 seconds"); | |
1297 vsi_t_time(VSI_CALLER &alr_data->nc_data.ncsync_start_tim); | |
1298 } | |
1299 | |
1300 /* | |
1301 +--------------------------------------------------------------------+ | |
1302 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
1303 | STATE : code ROUTINE : nc_ncsync_tim_expiry | | |
1304 +--------------------------------------------------------------------+ | |
1305 PURPOSE : Called at the end of 10 seconds interval for NCELL synchronization | |
1306 | |
1307 */ | |
1308 GLOBAL void nc_ncsync_tim_expiry(void) | |
1309 { | |
1310 UBYTE i; | |
1311 UBYTE c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
1312 T_NC* pcell; | |
1313 | |
1314 #ifdef GPRS | |
1315 if(!alr_data->gprs_data.pbcch) | |
1316 #endif | |
1317 { | |
1318 T_TIME tval; | |
1319 vsi_t_time(VSI_CALLER &tval); | |
1320 if(tval<alr_data->nc_data.ncsync_start_tim) | |
1321 TRACE_EVENT_P2("NCSYNC expiry at %d milliseconds, BS_PA_MFRMS = %d", | |
1322 ULONG_MAX-alr_data->nc_data.ncsync_start_tim+tval, | |
1323 alr_data->bs_pa_mfrms+2); | |
1324 else | |
1325 TRACE_EVENT_P2("NCSYNC expiry at %d milliseconds, BS_PA_MFRMS = %d", | |
1326 tval-alr_data->nc_data.ncsync_start_tim, | |
1327 alr_data->bs_pa_mfrms+2); | |
1328 } | |
1329 | |
1330 | |
1331 | |
1332 if (alr_data->nc_data.tim_state NEQ NC_TIM_STOPPED) | |
1333 { | |
1334 #ifdef GPRS | |
1335 if(!alr_data->gprs_data.pbcch) | |
1336 #endif | |
1337 { | |
1338 nc_start_ncsync(); | |
1339 } | |
1340 | |
1341 if (alr_data->nc_data.c_nc_timer > 0) | |
1342 alr_data->nc_data.c_nc_timer--; | |
1343 TRACE_EVENT_P1("c_nc_timer %d", alr_data->nc_data.c_nc_timer); | |
1344 | |
1345 /* decrement counters */ | |
1346 for (i=0,pcell = &alr_data->nc_data.cell[0]; i < c_ba_arfcn; i++,pcell++) | |
1347 { | |
1348 if (pcell->c_sync > 0 AND pcell->c_sync < C_INVALID_SYNC) | |
1349 pcell->c_sync--; | |
1350 if (pcell->c_bcch > 0 AND pcell->c_bcch < C_INVALID_BCCH) | |
1351 pcell->c_bcch--; | |
1352 | |
1353 if(pcell->ba_arfcn NEQ alr_data->serving_cell) | |
1354 { | |
1355 switch(pcell->ba_status) | |
1356 { | |
1357 case NOT_IN_BA_SHORT: | |
1358 pcell->ba_status = NOT_IN_BA_LONG; | |
1359 #if defined(TRACING) | |
1360 TRACE_EVENT_P2 ("NC%u[%u] -> NOT_IN_BA_LONG", i, pcell->ba_arfcn); | |
1361 #endif /* TRACING */ | |
1362 break; | |
1363 case NOT_IN_BA_LONG: | |
1364 #if defined(TRACING) | |
1365 TRACE_EVENT_P2 ("NC%u[%u] remove", i, pcell->ba_arfcn); | |
1366 /* this trace must be performed before the removal to get right results */ | |
1367 #endif /* TRACING */ | |
1368 c_ba_arfcn = nc_remove_channel_from_ba_list (i); | |
1369 i--; | |
1370 pcell--; | |
1371 ALR_TRACE_ALL_NC (); | |
1372 break; | |
1373 case IN_BA: | |
1374 /* do nothing */ | |
1375 break; | |
1376 } | |
1377 } | |
1378 } | |
1379 } | |
1380 | |
1381 switch(alr_data->nc_data.tim_state) | |
1382 { | |
1383 case NC_CONF_ENABLED: | |
1384 nc_start_ncell_confirm(); | |
1385 break; | |
1386 case NC_CONF_DISABLED: | |
1387 alr_data->nc_data.tim_state = NC_CONF_PENDING; | |
1388 break; | |
1389 case NC_CONF_PENDING: | |
1390 TRACE_ERROR("TIM_NCSYNC expiry in unexpected state"); | |
1391 /* | |
1392 * this should never happen, but in case ALR is waiting | |
1393 * more than 20 seconds for the last MPHC_NCELL_SYNC_IND of the | |
1394 * confirmation procedure and the reason isn't a position request, | |
1395 * then the confirmation procedure is restarted | |
1396 */ | |
1397 if (GET_STATE(STATE_NC_PROC) EQ NC_CONFIRM AND | |
1398 alr_data->nc_data.ppos_req EQ NULL) | |
1399 { | |
1400 alr_data->nc_data.c_nc_timer = 0; | |
1401 nc_start_ncell_confirm(); | |
1402 } | |
1403 break; | |
1404 } | |
1405 } | |
1406 /* | |
1407 +--------------------------------------------------------------------+ | |
1408 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
1409 | STATE : code ROUTINE : nc_init_pos_ind | | |
1410 +--------------------------------------------------------------------+ | |
1411 | |
1412 PURPOSE : initial setting of a MPH_NCELL_POS_IND | |
1413 | |
1414 */ | |
1415 | |
1416 LOCAL void nc_init_pos_ind (USHORT req_id) | |
1417 { | |
1418 memset(&(alr_data->nc_data.ppos_ind->eotd_sc_res), 0, sizeof (T_eotd_sc_res )); | |
1419 memset(&(alr_data->nc_data.ppos_ind->eotd_sc_res1), 0, sizeof (T_eotd_sc_res1)); | |
1420 alr_data->nc_data.ppos_ind->c_eotd_nc_res = 0; | |
1421 alr_data->nc_data.ppos_ind->req_id = req_id; | |
1422 alr_data->nc_data.ppos_ind->eotd_res = 0; | |
1423 } | |
1424 /* | |
1425 +--------------------------------------------------------------------+ | |
1426 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
1427 | STATE : code ROUTINE : nc_is_sync | | |
1428 +--------------------------------------------------------------------+ | |
1429 | |
1430 PURPOSE : checks whether a ncell is synchronized and timing values | |
1431 are valid | |
1432 | |
1433 */ | |
1434 LOCAL BOOL nc_is_sync (T_NC * p_ncell) | |
1435 { | |
1436 switch (p_ncell->status) | |
1437 { | |
1438 case FB_SB_SYNC: | |
1439 case READ_SB: | |
1440 case READ_SB_BCCH: | |
1441 case READ_BCCH: | |
1442 case READ_BCCH_RR_NOT_INFORMED: | |
1443 case IDLE_SYNC: | |
1444 return TRUE; | |
1445 default: | |
1446 return FALSE; | |
1447 } | |
1448 } | |
1449 /* | |
1450 +--------------------------------------------------------------------+ | |
1451 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
1452 | STATE : code ROUTINE : nc_ncell_pos_req | | |
1453 +--------------------------------------------------------------------+ | |
1454 | |
1455 PURPOSE : reception of a ncell_pos_req | |
1456 | |
1457 */ | |
1458 | |
1459 void nc_ncell_pos_req (T_MPH_NCELL_POS_REQ* pos_req) | |
1460 { | |
1461 /* if there is an earlier position request disgard it*/ | |
1462 if (alr_data->nc_data.ppos_req NEQ NULL) | |
1463 PFREE(alr_data->nc_data.ppos_req); | |
1464 /* store the request until the end of the respective position indication */ | |
1465 alr_data->nc_data.ppos_req = pos_req; | |
1466 | |
1467 /* | |
1468 * process the request immediately if confirmation is enabled or | |
1469 * another measurement is in progress | |
1470 * (otherwise start processing when confirmation becomes enabled | |
1471 */ | |
1472 if ( (alr_data->nc_data.tim_state EQ NC_CONF_ENABLED) OR | |
1473 (alr_data->nc_data.tim_state EQ NC_CONF_DISABLED AND | |
1474 GET_STATE(STATE_NC_PROC) EQ NC_CONFIRM) ) | |
1475 nc_process_pos_req(pos_req); | |
1476 } | |
1477 /* | |
1478 +--------------------------------------------------------------------+ | |
1479 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
1480 | STATE : code ROUTINE : nc_process_pos_req | | |
1481 +--------------------------------------------------------------------+ | |
1482 | |
1483 PURPOSE : processes a ncell_pos_req | |
1484 | |
1485 */ | |
1486 | |
1487 LOCAL void nc_process_pos_req (T_MPH_NCELL_POS_REQ* pos_req) | |
1488 { | |
1489 UBYTE fail=1; | |
1490 | |
1491 if (alr_data->nc_data.ppos_ind EQ NULL) | |
1492 { | |
1493 PALLOC (pos_ind, MPH_NCELL_POS_IND); | |
1494 alr_data->nc_data.ppos_ind = pos_ind; | |
1495 } | |
1496 | |
1497 nc_init_pos_ind(pos_req->req_id); | |
1498 | |
1499 #if 0 /* allow position requests also in NC_IDLE mode to be able to answer a test SMS */ | |
1500 switch(GET_STATE(STATE_NC)) | |
1501 { | |
1502 case NC_DEDICATED: | |
1503 #endif /* 0|1 */ | |
1504 if(alr_data->nc_data.eotd_avail) | |
1505 { | |
1506 T_NC* p_ncell; | |
1507 T_ncell_eotd* p_ncell_pos = &pos_req->ncell_eotd[0]; | |
1508 T_NC* list_of_asd_1o12 [12]; | |
1509 T_ncell_eotd* list_of_asd_ba [15]; | |
1510 T_ncell_eotd* list_of_asd [15]; | |
1511 T_NC** p_asd_1o12 = &list_of_asd_1o12[0]; | |
1512 T_ncell_eotd** p_asd_ba = &list_of_asd_ba[0]; | |
1513 T_ncell_eotd** p_asd = &list_of_asd[0]; | |
1514 UBYTE c_ba = alr_data->nc_data.c_ba_arfcn; | |
1515 UBYTE i,j; | |
1516 UBYTE c_list; | |
1517 UBYTE found; | |
1518 | |
1519 fail=0; | |
1520 | |
1521 nc_stop_all(); | |
1522 | |
1523 /* | |
1524 * generate and send an appropriate MPHC_NCELL_LIST_SYNC_REQ | |
1525 * 1/ take all ncells which are in ASD list and the twelve | |
1526 * strongest synchronized of the BA list (using timing values | |
1527 * from former synchronisation) | |
1528 * 2/ then all ncells which are in ASD list and in the BA list | |
1529 * (using timings from the ASD list) | |
1530 * 3/ then rest of ASD cells (using timings from the ASD list) | |
1531 * 4/ then rest of BA list cells which are synchronized (using | |
1532 * timing values from former synchronisation) | |
1533 */ | |
1534 { | |
1535 PALLOC (ncell_list_req, MPHC_NCELL_LIST_SYNC_REQ); | |
1536 ncell_list_req->eotd = TRUE; | |
1537 | |
1538 /* for all ncells in ASD list */ | |
1539 for(j=0; j < MAX_NCELL_EOTD_L1 AND j < pos_req->c_ncell_eotd; | |
1540 j++, p_ncell_pos++) | |
1541 { | |
1542 if (p_ncell_pos->arfcn EQ alr_data->serving_cell) | |
1543 { | |
1544 continue; | |
1545 } | |
1546 /* look if it is in BA list */ | |
1547 found=FALSE; | |
1548 for (i = 0, p_ncell = &alr_data->nc_data.cell[0]; i < c_ba; i++, p_ncell++) | |
1549 { | |
1550 if(p_ncell_pos->arfcn EQ p_ncell->ba_arfcn) | |
1551 { | |
1552 /* | |
1553 * if it is in both list then check | |
1554 * if it is synchronized or not | |
1555 * and use the correct list | |
1556 */ | |
1557 if(nc_is_sync(p_ncell)) | |
1558 { /* case 1/ */ | |
1559 *(p_asd_1o12++) = p_ncell; | |
1560 found=TRUE; | |
1561 } | |
1562 else | |
1563 { /* case 2/ */ | |
1564 *(p_asd_ba++) = p_ncell_pos; | |
1565 found=TRUE; | |
1566 } /* is sync */ | |
1567 break; | |
1568 } /*arfcn*/ | |
1569 } /*ba list*/ | |
1570 | |
1571 /* if nothing was found, then it is case 3/ */ | |
1572 if(!found) | |
1573 *(p_asd++) = p_ncell_pos; | |
1574 | |
1575 } /* asd list */ | |
1576 | |
1577 c_list=0; | |
1578 for(i=0; c_list < MAX_L1_SYNC_CNT AND i < p_asd_1o12-list_of_asd_1o12;i++) | |
1579 { | |
1580 nc_ncell_list_req_pos(&ncell_list_req->ncell_list[c_list++], | |
1581 NULL, | |
1582 list_of_asd_1o12[i]->ba_arfcn); | |
1583 } /*asd_1o12 */ | |
1584 for(i=0 ;c_list < MAX_L1_SYNC_CNT AND i < p_asd_ba-list_of_asd_ba;i++) | |
1585 { | |
1586 nc_ncell_list_req_pos(&ncell_list_req->ncell_list[c_list++], | |
1587 list_of_asd_ba[i], | |
1588 list_of_asd_ba[i]->arfcn); | |
1589 | |
1590 } | |
1591 for(i=0 ;c_list < MAX_L1_SYNC_CNT AND i < p_asd-list_of_asd;i++) | |
1592 { | |
1593 nc_ncell_list_req_pos(&ncell_list_req->ncell_list[c_list++], | |
1594 list_of_asd[i], | |
1595 list_of_asd[i]->arfcn); | |
1596 } | |
1597 /* | |
1598 * fill the ncell list req with the remaining synchronized | |
1599 * neigbour cells of the BA list (case 4/ ) | |
1600 */ | |
1601 for (i=0, p_ncell = &alr_data->nc_data.cell[0]; | |
1602 c_list < MAX_L1_SYNC_CNT AND i < c_ba; | |
1603 i++, p_ncell++) | |
1604 { | |
1605 if (p_ncell->ba_arfcn EQ alr_data->serving_cell) | |
1606 { | |
1607 continue; | |
1608 } | |
1609 if (nc_is_sync(p_ncell)) | |
1610 { | |
1611 USHORT l1_arfcn = ARFCN_TO_L1(p_ncell->ba_arfcn); | |
1612 found=FALSE; | |
1613 for (j=0; j < c_list;j++) | |
1614 { | |
1615 if (ncell_list_req->ncell_list[j].radio_freq EQ l1_arfcn) | |
1616 { | |
1617 found = TRUE; | |
1618 break; | |
1619 } | |
1620 } /* MPHC_NCELL_LIST_SYNC_REQ */ | |
1621 if (!found) | |
1622 nc_ncell_list_req_pos(&ncell_list_req->ncell_list[c_list++], | |
1623 NULL, | |
1624 p_ncell->ba_arfcn); | |
1625 } /* is sync */ | |
1626 } /* BA list */ | |
1627 | |
1628 if (c_list > 0) | |
1629 { | |
1630 ncell_list_req->list_size = c_list; | |
1631 alr_data->nc_data.c_sync_req = c_list; | |
1632 if (c_list < MAX_NCELL_EOTD_L1) | |
1633 memset(&(ncell_list_req->ncell_list[c_list]), | |
1634 0, | |
1635 (MAX_NCELL_EOTD_L1 - c_list) * sizeof(T_ncell_list)); | |
1636 | |
1637 alr_data->nc_data.c_sync_req += 2; /* for the 2 scell ind's */ | |
1638 nc_disable_conf(DONT_FREE_POS_IND); | |
1639 SET_STATE(STATE_NC_PROC, NC_CONFIRM); | |
1640 ma_nc_list_sync_req (ncell_list_req); | |
1641 TRACE_EVENT_P1("MPHC_NCELL_LIST_SYNC_REQ eotd=TRUE c_sync_req=%u", alr_data->nc_data.c_sync_req); | |
1642 } | |
1643 else | |
1644 fail = TRUE; | |
1645 }/* PALLOC list_req */ | |
1646 } /* eotd_avail */ | |
1647 /* else fail=1*/ | |
1648 #if 0 | |
1649 break; | |
1650 default: | |
1651 /*fail=1*/ | |
1652 break; | |
1653 } /*switch NC_STATE*/ | |
1654 #endif /* 0|1 */ | |
1655 | |
1656 if(fail) | |
1657 { /* TODO complete ?? */ | |
1658 alr_data->nc_data.ppos_ind->eotd_res = EOTD_REF; | |
1659 PSENDX(RR, alr_data->nc_data.ppos_ind); | |
1660 alr_data->nc_data.ppos_ind = NULL; | |
1661 PFREE(pos_req); | |
1662 alr_data->nc_data.ppos_req = NULL; | |
1663 } | |
1664 } | |
1665 | |
1666 /* | |
1667 +--------------------------------------------------------------------+ | |
1668 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
1669 | STATE : code ROUTINE : nc_ncell_list_req_pos | | |
1670 +--------------------------------------------------------------------+ | |
1671 | |
1672 PURPOSE : Handles cell lists. | |
1673 | |
1674 */ | |
1675 | |
1676 LOCAL void nc_ncell_list_req_pos(T_ncell_list* p_ncell_list, | |
1677 T_ncell_eotd* asd_cell, | |
1678 USHORT arfcn) | |
1679 { | |
1680 USHORT index = nc_get_index(arfcn); | |
1681 | |
1682 p_ncell_list->radio_freq = ARFCN_TO_L1(arfcn); | |
1683 | |
1684 if(asd_cell) | |
1685 { | |
1686 if(index NEQ NOT_PRESENT_16BIT AND index NEQ LAST_BSIC_REQ AND | |
1687 alr_data->nc_data.cell[index].status EQ IDLE_SYNC) | |
1688 { | |
1689 p_ncell_list->fn_offset = alr_data->nc_data.cell[index].frame_offset; | |
1690 p_ncell_list->time_alignment = alr_data->nc_data.cell[index].time_align; | |
1691 p_ncell_list->timing_validity = TV_VALID_TIMING_INFO; | |
1692 /*TODO what about reception of ncell_sync_ind for this cell | |
1693 are timing info and counter updated ?*/ | |
1694 } | |
1695 else | |
1696 { | |
1697 nc_get_timing_eotd(p_ncell_list, asd_cell); | |
1698 p_ncell_list->timing_validity = TV_VALID_TIMING_INFO; /* TV_APPROX_TIMING_INFO;*/ | |
1699 } | |
1700 } /*asd_cell*/ | |
1701 else | |
1702 { | |
1703 if(index NEQ NOT_PRESENT_16BIT AND index NEQ LAST_BSIC_REQ) | |
1704 { | |
1705 /* cell is in BA list and 1o12, so use the data we have */ | |
1706 switch(alr_data->nc_data.cell[index].status) | |
1707 { | |
1708 case READ_SB_BCCH: | |
1709 case READ_BCCH: | |
1710 nc_set_status(index,READ_SB_BCCH_PENDING); | |
1711 break; | |
1712 case READ_SB: | |
1713 case FB_SB_SYNC: | |
1714 nc_set_status(index,READ_SB_PENDING); | |
1715 break; | |
1716 case READ_FB_SB: | |
1717 case READ_BCCH_RR_NOT_INFORMED: | |
1718 case FB_SB_SYNC_RR_NOT_INFORMED: | |
1719 /*TODO what about reception of ncell_sync_ind for this cell | |
1720 are timing info and counter updated ?*/ | |
1721 break; | |
1722 } /*status*/ | |
1723 p_ncell_list->fn_offset = alr_data->nc_data.cell[index].frame_offset; | |
1724 p_ncell_list->time_alignment = alr_data->nc_data.cell[index].time_align; | |
1725 p_ncell_list->timing_validity = TV_VALID_TIMING_INFO; | |
1726 } | |
1727 else | |
1728 { | |
1729 TRACE_ERROR("nc_ncell_list_req_pos: asd_cell==0 but cell not in BA"); | |
1730 } | |
1731 }/*asd_cell*/ | |
1732 } | |
1733 | |
1734 LOCAL void nc_get_timing_eotd(T_ncell_list* p_ncell_list, | |
1735 T_ncell_eotd* asd_cell) | |
1736 { | |
1737 USHORT td, adjust = 0, offs; | |
1738 /* | |
1739 * The values mfrm_offset, rough_rtd and exp_otd are differences | |
1740 * between the BTS in question and the reference BTS. | |
1741 * L1 expects the differences between serving BTS and BTS in question: | |
1742 * | |
1743 * +----+----+----+----+----+....+----+----+----+----+----+ serving BTS | |
1744 * 0 51 | |
1745 * | | |
1746 * 0 Net | L1 1250 (5000) | |
1747 * +---->V<----+ | |
1748 * \ / | |
1749 * \ / | |
1750 * +----+----+----+----+----+....+----+----+----+----+----+ BTS in question | |
1751 * 0 51 | |
1752 * +-----Net----->| |<---------L1----------------------+ | |
1753 * | |
1754 * time differences are indicated in bits by the net, but expected | |
1755 * in quarterbits by L1 | |
1756 */ | |
1757 | |
1758 offs = asd_cell->mfrm_offset; | |
1759 | |
1760 if (asd_cell->otd_type EQ BOTH_OTD) | |
1761 { | |
1762 int diff = asd_cell->rough_rtd - asd_cell->exp_otd; | |
1763 if (diff >= 850) | |
1764 adjust = 1; | |
1765 else if (diff <= -850) | |
1766 adjust = -1; | |
1767 /* | |
1768 * GSM 04.31 section A.2.2.3 version 8.7.0 says that adjust shall be | |
1769 * equal 0 for -400 <= diff <= 400 and states an error for | |
1770 * -850 < diff < -450 and for 450 < diff < 850, but doesn't | |
1771 * describe the behaviour in this cases. | |
1772 * All this valid and invalid cases are implemented here by | |
1773 * adjust = 0 | |
1774 */ | |
1775 } | |
1776 | |
1777 if (asd_cell->otd_type EQ ROUGH_OTD) | |
1778 td = asd_cell->rough_rtd; | |
1779 else | |
1780 { /* | |
1781 * uncertainty indicates how many bits the search window | |
1782 * for measurement should be opended earlier than the expected | |
1783 * value. Because of the subsequent subtraction we have to ADD | |
1784 * the uncertainty value. | |
1785 * no special handling for uncertainty value 7 (uncertainty > 30 bits) | |
1786 * is implemented yet | |
1787 */ | |
1788 td = asd_cell->exp_otd + unc_values[asd_cell->uncertainty]; | |
1789 if (td >= 1250) | |
1790 offs++; | |
1791 } | |
1792 td %= 1250; | |
1793 | |
1794 if (td) | |
1795 { | |
1796 p_ncell_list->time_alignment = 5000 - 4 * td; | |
1797 offs++; | |
1798 } | |
1799 else | |
1800 p_ncell_list->time_alignment = 0; | |
1801 | |
1802 offs = (offs + adjust) % 51; | |
1803 | |
1804 if (offs) | |
1805 p_ncell_list->fn_offset = 51 - offs; | |
1806 else | |
1807 p_ncell_list->fn_offset = 0; | |
1808 } | |
1809 /* | |
1810 +--------------------------------------------------------------------+ | |
1811 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
1812 | STATE : code ROUTINE : nc_start_eotd_confirm | | |
1813 +--------------------------------------------------------------------+ | |
1814 | |
1815 PURPOSE : generates an MPHC_NCELL_LIST_SYNC_REQ from the BA list. | |
1816 */ | |
1817 LOCAL void nc_start_eotd_confirm(void) | |
1818 { | |
1819 /* | |
1820 * this check is needed for the resume | |
1821 * in the GPRS case because we need | |
1822 * to keep the states over a | |
1823 * start transition | |
1824 */ | |
1825 if(alr_data->nc_data.ppos_ind EQ NULL) | |
1826 { | |
1827 PALLOC (pos_ind, MPH_NCELL_POS_IND); | |
1828 alr_data->nc_data.ppos_ind = pos_ind; | |
1829 } | |
1830 nc_init_pos_ind (NOT_PRESENT_16BIT); | |
1831 | |
1832 /* generate and send an appropriate MPHC_NCELL_LIST_SYNC_REQ */ | |
1833 nc_ncell_list_req(); | |
1834 } | |
1835 | |
1836 /* | |
1837 +--------------------------------------------------------------------+ | |
1838 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
1839 | STATE : code ROUTINE : nc_ncell_list_req | | |
1840 +--------------------------------------------------------------------+ | |
1841 | |
1842 PURPOSE : generates an MPHC_NCELL_LIST_SYNC_REQ based on the 12 | |
1843 strongest neighbour cells of the BA | |
1844 | |
1845 */ | |
1846 LOCAL void nc_ncell_list_req (void) | |
1847 { | |
1848 UBYTE c_found = 0, found, i, validity; | |
1849 USHORT c_ba = alr_data->nc_data.c_ba_arfcn; | |
1850 T_NC* pcell; | |
1851 T_ncell_list *pnc; | |
1852 PALLOC (ncell_list_req, MPHC_NCELL_LIST_SYNC_REQ); | |
1853 | |
1854 if (alr_data->nc_data.c_sync_req NEQ 0) | |
1855 TRACE_EVENT_P1("nc_ncell_list_req with c_sync_req=%u before", alr_data->nc_data.c_sync_req); | |
1856 | |
1857 ncell_list_req->eotd = alr_data->nc_data.eotd_avail; | |
1858 | |
1859 nc_stop_all(); | |
1860 for (i = 0, pcell = &alr_data->nc_data.cell[0]; i < c_ba; i++, pcell++) | |
1861 { | |
1862 if (alr_data->nc_data.eotd_avail AND pcell->ba_arfcn EQ alr_data->serving_cell) | |
1863 { | |
1864 continue; | |
1865 } | |
1866 if (pcell->one_of_twelve) | |
1867 { | |
1868 switch (pcell->status) | |
1869 { | |
1870 case READ_SB: | |
1871 nc_set_status(nc_get_index(pcell->ba_arfcn), READ_SB_PENDING); | |
1872 found = TRUE; | |
1873 validity = TV_VALID_TIMING_INFO; | |
1874 break; | |
1875 case READ_SB_BCCH: | |
1876 nc_set_status(nc_get_index(pcell->ba_arfcn), READ_SB_BCCH_PENDING); | |
1877 found = TRUE; | |
1878 validity = TV_VALID_TIMING_INFO; | |
1879 break; | |
1880 /* TODO(opt): if !eotd_avail maybe optimize later | |
1881 case READ_FB_SB: | |
1882 break*/ | |
1883 /* | |
1884 case READ_BCCH_RR_NOT_INFORMED: | |
1885 case READ_BCCH_PENDING_RR_NOT_INFORMED: | |
1886 case READ_BCCH: | |
1887 case READ_BCCH_PENDING: | |
1888 found = TRUE; | |
1889 validity = TV_VALID_TIMING_INFO; | |
1890 break;*/ | |
1891 default: | |
1892 found = FALSE; | |
1893 validity = TV_INVALID_TIMING_INFO; | |
1894 break; | |
1895 } | |
1896 | |
1897 if (found) | |
1898 { | |
1899 pnc = &(ncell_list_req->ncell_list[c_found++]); | |
1900 pnc->radio_freq = ARFCN_TO_L1(pcell->ba_arfcn); | |
1901 if (validity EQ TV_VALID_TIMING_INFO) | |
1902 { | |
1903 pnc->fn_offset = pcell->frame_offset; | |
1904 pnc->time_alignment = pcell->time_align; | |
1905 } | |
1906 else | |
1907 { | |
1908 pnc->fn_offset = 0; | |
1909 pnc->time_alignment = 0; | |
1910 } | |
1911 pnc->timing_validity = validity; | |
1912 } | |
1913 } | |
1914 } | |
1915 | |
1916 /* | |
1917 * in case there are no synchronized neighbour cells | |
1918 * send an empty MPHC_NCELL_LIST_SYNC_REQ to L1 | |
1919 * (to serve the cursor task later with a position indication | |
1920 * containing measurements of the serving cell only) | |
1921 */ | |
1922 if(c_found OR alr_data->nc_data.eotd_avail) | |
1923 { | |
1924 ncell_list_req->list_size = c_found; | |
1925 alr_data->nc_data.c_sync_req = c_found; | |
1926 if (c_found < MAX_NCELL_EOTD_L1) | |
1927 memset(&(ncell_list_req->ncell_list[c_found]), | |
1928 0, | |
1929 (MAX_NCELL_EOTD_L1 - c_found) * sizeof(T_ncell_list)); | |
1930 | |
1931 if(alr_data->nc_data.eotd_avail) | |
1932 /* add the 2 scell sync_ind */ | |
1933 alr_data->nc_data.c_sync_req += 2; | |
1934 | |
1935 nc_disable_conf(DONT_FREE_POS_IND); | |
1936 SET_STATE(STATE_NC_PROC, NC_CONFIRM); | |
1937 ma_nc_list_sync_req (ncell_list_req); | |
1938 TRACE_EVENT_P3("MPHC_NCELL_LIST_SYNC_REQ eotd=%d c_sync_req=%u SC=%u", | |
1939 alr_data->nc_data.eotd_avail, | |
1940 alr_data->nc_data.c_sync_req, | |
1941 alr_data->serving_cell); | |
1942 } | |
1943 else | |
1944 { | |
1945 PFREE(ncell_list_req); | |
1946 SET_STATE(STATE_NC_PROC, NC_ACQUIRE); | |
1947 nc_enable_conf(); | |
1948 } | |
1949 } | |
1950 | |
1951 /* | |
1952 +--------------------------------------------------------------------+ | |
1953 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
1954 | STATE : code ROUTINE : nc_store_eotd | | |
1955 +--------------------------------------------------------------------+ | |
1956 | |
1957 PURPOSE : copies the measurement results into the MPH_NCELL_POS_IND | |
1958 | |
1959 */ | |
1960 LOCAL void nc_store_eotd (T_eotd_sc_res * p_res, | |
1961 T_MPHC_NCELL_SYNC_IND * sync_ind, | |
1962 USHORT arfcn) | |
1963 { | |
1964 p_res->sb_flag = sync_ind->sb_flag; | |
1965 p_res->bsic = sync_ind->bsic; | |
1966 p_res->arfcn = arfcn; | |
1967 memcpy(&(p_res->eotd_crosscor), | |
1968 &(sync_ind->a_eotd_crosscor), | |
1969 sizeof(sync_ind->a_eotd_crosscor)); | |
1970 p_res->d_eotd_nrj = sync_ind->d_eotd_nrj; | |
1971 p_res->time_tag = sync_ind->time_tag; | |
1972 } | |
1973 | |
1974 /* | |
1975 +--------------------------------------------------------------------+ | |
1976 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
1977 | STATE : code ROUTINE : nc_stop_ext_meas_ind | | |
1978 +--------------------------------------------------------------------+ | |
1979 | |
1980 PURPOSE : Notify RR about the end of the end of the Extended | |
1981 Measurement procedure. | |
1982 | |
1983 */ | |
1984 GLOBAL void nc_stop_ext_meas_ind (void) | |
1985 { | |
1986 PALLOC ( mph_sync_ind, MPH_SYNC_IND ); | |
1987 mph_sync_ind->cs = CS_STOP_PLMN_SEARCH; | |
1988 mph_sync_ind->arfcn = NOT_PRESENT_16BIT; | |
1989 PSENDX ( RR, mph_sync_ind ); | |
1990 | |
1991 if( alr_data->cs_data.p_power_cnf NEQ NULL ) | |
1992 { | |
1993 PFREE(alr_data->cs_data.p_power_cnf) | |
1994 alr_data->cs_data.p_power_cnf = NULL; | |
1995 } | |
1996 if( IS_EXT_MEAS_RUNNING )/*alr_data->cs_data.mph_ext_meas_req NEQ NULL */ | |
1997 { | |
1998 PFREE ( alr_data->cs_data.mph_ext_meas_req ); | |
1999 alr_data->cs_data.mph_ext_meas_req = NULL; | |
2000 } | |
2001 } | |
2002 | |
2003 /* | |
2004 +--------------------------------------------------------------------+ | |
2005 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
2006 | STATE : code ROUTINE : nc_stop_rr_activity | | |
2007 +--------------------------------------------------------------------+ | |
2008 | |
2009 PURPOSE : Stop BCCH reading or PLMN seach originated by RR. | |
2010 | |
2011 */ | |
2012 GLOBAL void nc_stop_rr_activity (UBYTE stop) | |
2013 { | |
2014 /* | |
2015 * RR signals stop BCCH reading or stop PLMN search | |
2016 */ | |
2017 if( (IS_EXT_MEAS_RUNNING) AND | |
2018 (alr_data->nc_data.cell[LAST_BSIC_REQ].status EQ READ_FB_SB_PENDING) ) | |
2019 { | |
2020 /* | |
2021 * Wait for MPHC_NCELL_SYNC_IND or MPHC_STOP_NCELL_SYNC_CON | |
2022 */ | |
2023 alr_data->cs_data.ext_meas_state_pend = CS_ACTIVE_SYNC; | |
2024 } | |
2025 nc_clear_last_bsic(); | |
2026 | |
2027 /* | |
2028 * RR signals end of PLMN search | |
2029 */ | |
2030 if (stop) | |
2031 { | |
2032 alr_data->plmn_search_running = FALSE; | |
2033 nc_enable_conf(); | |
2034 } | |
2035 | |
2036 if ( IS_EXT_MEAS_RUNNING AND (alr_data->cs_data.ext_meas_state_pend EQ CS_NULL) ) | |
2037 { | |
2038 nc_stop_ext_meas_ind(); | |
2039 } | |
2040 } | |
2041 | |
2042 /* | |
2043 +--------------------------------------------------------------------+ | |
2044 | PROJECT : GSM-PS (8403) MODULE : ALR_NC | | |
2045 | STATE : code ROUTINE : nc_bsic_req | | |
2046 +--------------------------------------------------------------------+ | |
2047 | |
2048 PURPOSE : Request of RR to search for frequency correction | |
2049 burst and synchron burst. | |
2050 | |
2051 */ | |
2052 | |
2053 GLOBAL void nc_bsic_req (T_MPH_BSIC_REQ *mph_bsic_req) | |
2054 { | |
2055 USHORT i; | |
2056 | |
2057 mph_bsic_req->arfcn &= ARFCN_MASK; | |
2058 ALR_TRACE_NC_BSIC_REQ (mph_bsic_req->arfcn); | |
2059 | |
2060 ALR_EM_NEIGHBOURCELL_BSIC_REQUEST; | |
2061 | |
2062 nc_clear_last_bsic(); | |
2063 | |
2064 /* | |
2065 * look if the requested channel number is also in the normal | |
2066 * BA list to stop it. | |
2067 */ | |
2068 i = nc_get_index( mph_bsic_req->arfcn ); | |
2069 | |
2070 switch(i) | |
2071 { | |
2072 case NOT_PRESENT_16BIT: | |
2073 case LAST_BSIC_REQ: | |
2074 break; | |
2075 default: | |
2076 nc_stop_if_active(i); | |
2077 TRACE_ERROR("bsic_req for arfcn which is in BA list"); | |
2078 break; | |
2079 } | |
2080 | |
2081 | |
2082 /* | |
2083 * fill in parameters for BSIC request | |
2084 */ | |
2085 nc_set_status (LAST_BSIC_REQ, READ_FB_SB); | |
2086 alr_data->nc_data.cell[LAST_BSIC_REQ].ba_arfcn = mph_bsic_req->arfcn; | |
2087 | |
2088 /* | |
2089 * forward synchronisation request to layer 1, if not full | |
2090 */ | |
2091 if (alr_data->nc_data.c_sync_req < MAX_L1_SYNC_CNT) | |
2092 { | |
2093 /* | |
2094 * reset if we are in NC_CON_EST | |
2095 */ | |
2096 | |
2097 if(GET_STATE(STATE_NC) EQ NC_CON_EST | |
2098 #ifdef GPRS | |
2099 AND !alr_data->gprs_data.pbcch | |
2100 #endif | |
2101 ) | |
2102 { | |
2103 SET_STATE(STATE_NC, NC_IDLE); | |
2104 } | |
2105 #ifdef GPRS | |
2106 else if(GET_STATE(STATE_NC) EQ NC_CON_EST AND | |
2107 alr_data->gprs_data.pbcch) /* AND */ | |
2108 /* add later alr_data->gprs_data.pim) */ | |
2109 { | |
2110 SET_STATE(STATE_NC, NC_PIM_PBCCH); | |
2111 } | |
2112 #endif | |
2113 | |
2114 nc_process_status (); | |
2115 } | |
2116 | |
2117 } | |
2118 | |
2119 | |
2120 /* | |
2121 +--------------------------------------------------------------------+ | |
2122 | PROJECT : GSM-PS (6103) MODULE : alr_nc | | |
2123 | STATE : code ROUTINE : nc_bcch_ind | | |
2124 +--------------------------------------------------------------------+ | |
2125 | |
2126 PURPOSE : Reception of a system information message for a neighbourcell. | |
2127 | |
2128 */ | |
2129 | |
2130 GLOBAL void nc_bcch_ind (T_MPHC_NCELL_BCCH_IND *data_ind) | |
2131 { | |
2132 USHORT index; | |
2133 UBYTE msg_t = data_ind->l2_frame.content[SI_CONTENTS_MSG_T]; | |
2134 | |
2135 if (alr_data->nc_data.cell[LAST_BSIC_REQ].status EQ READ_BCCH_PENDING AND | |
2136 alr_data->nc_data.cell[LAST_BSIC_REQ].ba_arfcn EQ ARFCN_TO_G23(data_ind->radio_freq)) | |
2137 { | |
2138 /* | |
2139 * Cell selection or PLMN available search triggered by RR. | |
2140 */ | |
2141 if (data_ind->error_flag NEQ VALID_BLOCK) | |
2142 { | |
2143 /* | |
2144 * Reception of an invalid block | |
2145 */ | |
2146 ALR_TRACE_NC ("invalid PLMN BCCH"); | |
2147 | |
2148 /* | |
2149 * indicate BCCH read error to RR, too many errors are controlled by RR | |
2150 */ | |
2151 ma_error_ind (CS_BCCH_READ_ERROR, ARFCN_TO_G23(data_ind->radio_freq)); | |
2152 } | |
2153 else | |
2154 { | |
2155 UBYTE mt = data_ind->l2_frame.content[2]; | |
2156 | |
2157 ALR_TRACE_NC ("valid PLMN BCCH"); | |
2158 | |
2159 /* | |
2160 * forward message to RR | |
2161 */ | |
2162 ma_send_unitdata ((T_MPHC_DATA_IND *)data_ind); | |
2163 | |
2164 switch (mt) | |
2165 { | |
2166 case D_SYS_INFO_3: | |
2167 case D_SYS_INFO_4: | |
2168 alr_data->nc_data.cell[LAST_BSIC_REQ].blocks_required = 0; | |
2169 break; | |
2170 | |
2171 default: | |
2172 /* | |
2173 * Reception of any other message. Shall not happen after | |
2174 * GSM 5.02 chapter 6.3.1.3 Mapping of BCCH data, but | |
2175 * is possible for future extensions. | |
2176 * Read this tc again plus all which are not read until now. | |
2177 */ | |
2178 break; | |
2179 } | |
2180 } | |
2181 | |
2182 /* | |
2183 * all frames received, then decrement pending BCCH request | |
2184 */ | |
2185 if (alr_data->nc_data.cell[LAST_BSIC_REQ].blocks_required EQ 0) | |
2186 { | |
2187 | |
2188 nc_set_status (LAST_BSIC_REQ, IDLE); | |
2189 alr_data->nc_data.cell[LAST_BSIC_REQ].ba_arfcn = NOT_PRESENT_16BIT; | |
2190 | |
2191 /* | |
2192 * L3 may avoid sending a stop message to terminate a NCELL_BCCH process | |
2193 * if there no more pending request in L1 | |
2194 */ | |
2195 if (alr_data->nc_data.c_bcch_req > 0) | |
2196 { | |
2197 /* | |
2198 * stop any ongoing request in layer 1 | |
2199 */ | |
2200 ma_nc_stop_ncell_bcch_req(ARFCN_TO_G23(data_ind->radio_freq)); | |
2201 | |
2202 /* | |
2203 * decrement the number of pending requests in layer 1. | |
2204 */ | |
2205 alr_data->nc_data.c_bcch_req--; | |
2206 } | |
2207 } | |
2208 else | |
2209 { | |
2210 /* | |
2211 * stop pending request and start again. | |
2212 */ | |
2213 nc_restart_bcch (LAST_BSIC_REQ); | |
2214 } | |
2215 return ; | |
2216 } | |
2217 | |
2218 /* | |
2219 * Normal Ncell Handling, get position in neighbourcell list | |
2220 */ | |
2221 index = nc_get_index (ARFCN_TO_G23(data_ind->radio_freq)); | |
2222 | |
2223 if (index NEQ NOT_PRESENT_16BIT AND | |
2224 index NEQ LAST_BSIC_REQ AND | |
2225 (alr_data->nc_data.cell[index].status EQ READ_BCCH_PENDING OR | |
2226 alr_data->nc_data.cell[index].status EQ READ_BCCH_PENDING_RR_NOT_INFORMED)) | |
2227 { | |
2228 /* | |
2229 * normal member of the neighbourcell list and an answer is expected. | |
2230 */ | |
2231 if (data_ind->error_flag EQ VALID_BLOCK) | |
2232 { | |
2233 switch (msg_t) | |
2234 { | |
2235 case D_SYS_INFO_3: | |
2236 /* | |
2237 * Sys Info 3 contains the needed information in any case | |
2238 */ | |
2239 #if defined(TRACING) | |
2240 TRACE_EVENT_P3("NC%u[%d] BCCH ok %s", | |
2241 index, | |
2242 alr_data->nc_data.cell[index].ba_arfcn EQ NOT_PRESENT_16BIT ? | |
2243 -1 : alr_data->nc_data.cell[index].ba_arfcn&ARFCN_MASK, "si3"); | |
2244 #endif /* TRACING */ | |
2245 if (alr_data->nc_data.cell[index].status EQ READ_BCCH_PENDING_RR_NOT_INFORMED) | |
2246 { | |
2247 /* | |
2248 * store data if RR is not informed yet about | |
2249 * synchronisation | |
2250 */ | |
2251 nc_store_bcch((T_MPHC_DATA_IND *) data_ind, index,0); | |
2252 nc_set_status (index, FB_SB_SYNC_RR_NOT_INFORMED); | |
2253 } | |
2254 else | |
2255 { | |
2256 /* | |
2257 * forward information to RR | |
2258 */ | |
2259 ma_send_unitdata ((T_MPHC_DATA_IND *)data_ind); | |
2260 nc_set_fb_sb_sync_initial (index); | |
2261 | |
2262 } | |
2263 break; | |
2264 | |
2265 case D_SYS_INFO_4: | |
2266 if ((data_ind->l2_frame.content[SI_CONTENTS_CS2] & ONLY_ACS) EQ 0) | |
2267 { | |
2268 #if defined(TRACING) | |
2269 TRACE_EVENT_P3("NC%u[%d] BCCH ok %s", | |
2270 index, | |
2271 alr_data->nc_data.cell[index].ba_arfcn EQ NOT_PRESENT_16BIT ? | |
2272 -1 : alr_data->nc_data.cell[index].ba_arfcn&ARFCN_MASK, "si4"); | |
2273 #endif /* TRACING */ | |
2274 /* | |
2275 * additional cell selection info from sys info 7 or 8 is not necessary | |
2276 */ | |
2277 if (alr_data->nc_data.cell[index].status EQ READ_BCCH_PENDING_RR_NOT_INFORMED) | |
2278 { | |
2279 /* | |
2280 * store data if RR is not informed yet about synchronisation | |
2281 */ | |
2282 nc_store_bcch((T_MPHC_DATA_IND *) data_ind, index,0); | |
2283 nc_set_status (index, FB_SB_SYNC_RR_NOT_INFORMED); | |
2284 } | |
2285 else | |
2286 { | |
2287 /* | |
2288 * forward information to RR | |
2289 */ | |
2290 ma_send_unitdata ((T_MPHC_DATA_IND *)data_ind); | |
2291 nc_set_fb_sb_sync_initial (index); | |
2292 | |
2293 } | |
2294 } | |
2295 else | |
2296 { | |
2297 #if defined(TRACING) | |
2298 TRACE_EVENT_P3("NC%u[%d] BCCH ok %s", | |
2299 index, | |
2300 alr_data->nc_data.cell[index].ba_arfcn EQ NOT_PRESENT_16BIT ? | |
2301 -1 : alr_data->nc_data.cell[index].ba_arfcn&ARFCN_MASK, "si4_n78"); | |
2302 #endif /* TRACING */ | |
2303 /* | |
2304 * additional information from system info 7 or 8 | |
2305 * is needed for cell reselection purposes | |
2306 */ | |
2307 if(alr_data->nc_data.cell[index].status EQ READ_BCCH_PENDING_RR_NOT_INFORMED) | |
2308 { | |
2309 /* | |
2310 * store data if RR is not informed yet about synchronisation | |
2311 */ | |
2312 nc_store_bcch((T_MPHC_DATA_IND *) data_ind, index,0); | |
2313 } | |
2314 else | |
2315 { | |
2316 /* | |
2317 * forward information to RR | |
2318 */ | |
2319 ma_send_unitdata ((T_MPHC_DATA_IND *)data_ind); | |
2320 } | |
2321 | |
2322 /* | |
2323 * system info 3, 7 or 8 required | |
2324 * -> tc = 2,6 for normal BCCH or 3,7 for extended BCCH | |
2325 */ | |
2326 alr_data->nc_data.cell[index].blocks_required = NCELL_BCCH_SI_3_7_8; | |
2327 } | |
2328 break; | |
2329 | |
2330 case D_SYS_INFO_7: | |
2331 case D_SYS_INFO_8: | |
2332 if (nc_sys_info_78_required (index)) | |
2333 { | |
2334 #if defined(TRACING) | |
2335 TRACE_EVENT_P3("NC%u[%d] BCCH ok %s", | |
2336 index, | |
2337 alr_data->nc_data.cell[index].ba_arfcn EQ NOT_PRESENT_16BIT ? | |
2338 -1 : alr_data->nc_data.cell[index].ba_arfcn&ARFCN_MASK, "si78"); | |
2339 #endif /* TRACING */ | |
2340 if(alr_data->nc_data.cell[index].status EQ READ_BCCH_PENDING_RR_NOT_INFORMED) | |
2341 { | |
2342 /* | |
2343 * store data if RR is not informed yet about synchronisation | |
2344 */ | |
2345 nc_store_bcch((T_MPHC_DATA_IND *) data_ind, index,1); | |
2346 nc_set_status (index, FB_SB_SYNC_RR_NOT_INFORMED); | |
2347 } | |
2348 else | |
2349 { | |
2350 /* | |
2351 * forward information to RR | |
2352 */ | |
2353 ma_send_unitdata ((T_MPHC_DATA_IND *)data_ind); | |
2354 nc_set_fb_sb_sync_initial (index); | |
2355 | |
2356 } | |
2357 } | |
2358 else | |
2359 /* | |
2360 * increment error counter and request tc again. | |
2361 */ | |
2362 alr_data->nc_data.cell[index].c_error++; | |
2363 | |
2364 break; | |
2365 | |
2366 default: | |
2367 /* | |
2368 * increment error counter and request tc again. | |
2369 */ | |
2370 alr_data->nc_data.cell[index].c_error++; | |
2371 break; | |
2372 } | |
2373 } | |
2374 else | |
2375 { | |
2376 /* | |
2377 * BCCH reading failed | |
2378 * | |
2379 * error counter is incremented and tc shall be read again. | |
2380 */ | |
2381 alr_data->nc_data.cell[index].c_error++; | |
2382 } | |
2383 | |
2384 /* | |
2385 * restart next attempt | |
2386 */ | |
2387 if (alr_data->nc_data.cell[index].blocks_required EQ 0) | |
2388 { | |
2389 if (alr_data->nc_data.c_bcch_req > 0) | |
2390 { | |
2391 /* | |
2392 * decrement number of pending BCCH requests in layer 1. | |
2393 */ | |
2394 alr_data->nc_data.c_bcch_req--; | |
2395 | |
2396 /* | |
2397 * Stop the pending reading, if not all tc-s read | |
2398 */ | |
2399 ma_nc_stop_ncell_bcch_req (alr_data->nc_data.cell[index].ba_arfcn); | |
2400 } | |
2401 alr_data->nc_data.cell[index].c_attempt = 0; | |
2402 | |
2403 /* | |
2404 * start next request to layer 1 if necessary | |
2405 */ | |
2406 nc_process_status (); | |
2407 } | |
2408 else | |
2409 { | |
2410 if (alr_data->nc_data.cell[index].c_error >= 4) | |
2411 { | |
2412 /* | |
2413 * set status to failed or excluded depending on the failed | |
2414 * attempt counter and/or restart for this channel. | |
2415 */ | |
2416 nc_sync_failed_attempt (index); | |
2417 | |
2418 /* | |
2419 * L3 may avoid sending a stop message to terminate a NCELL_BCCH process | |
2420 * if there no more pending request in L1 | |
2421 */ | |
2422 if (alr_data->nc_data.c_bcch_req > 0) | |
2423 { | |
2424 /* | |
2425 * decrement number of pending BCCH requests in layer 1. | |
2426 */ | |
2427 alr_data->nc_data.c_bcch_req--; | |
2428 | |
2429 /* | |
2430 * Stop the pending reading, if not all tc-s read | |
2431 */ | |
2432 ma_nc_stop_ncell_bcch_req (alr_data->nc_data.cell[index].ba_arfcn); | |
2433 } | |
2434 | |
2435 /* | |
2436 * start next request to layer 1 if necessary | |
2437 */ | |
2438 nc_process_status (); | |
2439 } | |
2440 else | |
2441 { | |
2442 /* | |
2443 * restart the BCCH reading for this TC again. | |
2444 */ | |
2445 nc_restart_bcch (index); | |
2446 } | |
2447 } | |
2448 } | |
2449 } | |
2450 | |
2451 /* | |
2452 +--------------------------------------------------------------------+ | |
2453 | PROJECT : GSM-PS (6103) MODULE : alr_nc | | |
2454 | STATE : code ROUTINE : nc_restart_bcch | | |
2455 +--------------------------------------------------------------------+ | |
2456 | |
2457 PURPOSE : Stop old request and start new request to layer 1. | |
2458 | |
2459 */ | |
2460 | |
2461 LOCAL void nc_restart_bcch (USHORT index) | |
2462 { | |
2463 PALLOC (ncell_bcch, MPHC_NCELL_BCCH_REQ); | |
2464 | |
2465 if (alr_data->nc_data.c_bcch_req > 0) | |
2466 { | |
2467 /* | |
2468 * if necessary stop previous request to avoid on the fly change | |
2469 */ | |
2470 ma_nc_stop_ncell_bcch_req(alr_data->nc_data.cell[index].ba_arfcn); | |
2471 } | |
2472 | |
2473 ncell_bcch->radio_freq = ARFCN_TO_L1(alr_data->nc_data.cell[index].ba_arfcn); | |
2474 ncell_bcch->fn_offset = alr_data->nc_data.cell[index].frame_offset; | |
2475 ncell_bcch->time_alignment = alr_data->nc_data.cell[index].time_align; | |
2476 ncell_bcch->tsc = (UBYTE)(alr_data->nc_data.cell[index].bsic & ONLY_BCC); | |
2477 ncell_bcch->bcch_blocks_required = alr_data->nc_data.cell[index].blocks_required; | |
2478 #ifdef GPRS | |
2479 /*if the mobile is in PTM the GPRS_PRIORITY must be set to TOP*/ | |
2480 if(ma_is_ptm()) | |
2481 { | |
2482 ncell_bcch->gprs_prio = GPRS_PRIO_TOP; | |
2483 } | |
2484 else | |
2485 #endif | |
2486 ncell_bcch->gprs_prio = GPRS_PRIO_NORM; | |
2487 | |
2488 /* | |
2489 * and start next request | |
2490 */ | |
2491 ma_nc_bcch_req (ncell_bcch); | |
2492 } | |
2493 /* | |
2494 +--------------------------------------------------------------------+ | |
2495 | PROJECT : GSM-PS (6103) MODULE : alr_nc | | |
2496 | STATE : code ROUTINE : nc_store_sync_ind | | |
2497 +--------------------------------------------------------------------+ | |
2498 | |
2499 PURPOSE : stores the data of an MPHC_NCELL_SYNC_IND end enters | |
2500 a new state of ncell. | |
2501 | |
2502 */ | |
2503 | |
2504 LOCAL void nc_store_sync_ind (USHORT index, | |
2505 T_MPHC_NCELL_SYNC_IND *sync_ind, | |
2506 UBYTE new_status) | |
2507 { | |
2508 T_NC* pcell = &alr_data->nc_data.cell[index]; | |
2509 pcell->bsic = (UBYTE)(sync_ind->bsic & ONLY_BSIC); | |
2510 pcell->frame_offset = sync_ind->fn_offset; | |
2511 pcell->time_align = sync_ind->time_alignment; | |
2512 pcell->tim_valid = TV_VALID_TIMING_INFO; | |
2513 nc_set_status (index, new_status); | |
2514 } | |
2515 | |
2516 /* | |
2517 +--------------------------------------------------------------------+ | |
2518 | PROJECT : GSM-PS (6103) MODULE : alr_nc | | |
2519 | STATE : code ROUTINE : nc_sync_ind | | |
2520 +--------------------------------------------------------------------+ | |
2521 | |
2522 PURPOSE : Confirmation for a synchronisation request to layer 1. | |
2523 | |
2524 */ | |
2525 | |
2526 GLOBAL void nc_sync_ind (T_MPHC_NCELL_SYNC_IND *sync_ind) | |
2527 { | |
2528 USHORT index; | |
2529 UBYTE bsic = (UBYTE)(sync_ind->bsic & ONLY_BSIC); | |
2530 USHORT arfcn = ARFCN_TO_G23(sync_ind->radio_freq)&ARFCN_MASK; | |
2531 index = nc_get_index (arfcn); | |
2532 | |
2533 switch (GET_STATE (STATE_NC)) | |
2534 { | |
2535 case NC_IDLE: | |
2536 case NC_DEDICATED: | |
2537 #ifdef GPRS | |
2538 case NC_PIM_PBCCH: | |
2539 case NC_PTM_PBCCH: /*XXX*/ | |
2540 #endif | |
2541 TRACE_EVENT_P5("nc_sync_ind[%d] sb_flag=%d fn_offset=%ld time_alignment=%ld bsic=%d", | |
2542 arfcn, sync_ind->sb_flag, sync_ind->fn_offset, | |
2543 sync_ind->time_alignment, sync_ind->bsic); | |
2544 if (alr_data->nc_data.c_sync_req > 0) | |
2545 alr_data->nc_data.c_sync_req--; | |
2546 | |
2547 if (alr_data->nc_data.cell[LAST_BSIC_REQ].status EQ READ_FB_SB_PENDING AND | |
2548 alr_data->nc_data.cell[LAST_BSIC_REQ].ba_arfcn EQ arfcn AND | |
2549 #ifdef GPRS | |
2550 (GET_STATE(STATE_NC) EQ NC_IDLE OR GET_STATE(STATE_NC) EQ NC_PIM_PBCCH) | |
2551 ) | |
2552 #else | |
2553 GET_STATE(STATE_NC) EQ NC_IDLE | |
2554 ) | |
2555 #endif | |
2556 { | |
2557 nc_sync_ind_last_bsic_req(sync_ind,index,arfcn,bsic); | |
2558 } | |
2559 else | |
2560 { | |
2561 if (index NEQ NOT_PRESENT_16BIT AND | |
2562 index NEQ LAST_BSIC_REQ) | |
2563 { | |
2564 nc_sync_ind_ncell(sync_ind,index,arfcn,bsic); | |
2565 } /* valid index check */ | |
2566 else if (alr_data->nc_data.eotd_avail AND | |
2567 alr_data->nc_data.ppos_ind NEQ NULL) | |
2568 nc_check_sync_ind_eotd(sync_ind, arfcn); | |
2569 /* LAST_BSIC_REQ check */ | |
2570 else if ( (index EQ NOT_PRESENT_16BIT) AND (IS_EXT_MEAS_RUNNING) AND | |
2571 (GET_STATE(STATE_NC) EQ NC_IDLE)) | |
2572 { | |
2573 if ( alr_data->cs_data.ext_meas_state_pend NEQ CS_NULL ) | |
2574 { | |
2575 nc_stop_ext_meas_ind(); | |
2576 alr_data->cs_data.ext_meas_state_pend = CS_NULL; | |
2577 return; | |
2578 } | |
2579 } | |
2580 } | |
2581 | |
2582 if( alr_data->nc_data.c_sync_intrupted EQ TRUE AND alr_data->nc_data.c_sync_req EQ 0) | |
2583 { | |
2584 nc_enable_conf(); | |
2585 alr_data->nc_data.c_sync_intrupted = FALSE; | |
2586 } | |
2587 | |
2588 if(GET_STATE(STATE_NC_PROC) EQ NC_ACQUIRE) | |
2589 { | |
2590 nc_process_status(); | |
2591 } | |
2592 | |
2593 break; | |
2594 default: | |
2595 break; | |
2596 } /* STATE_NC */ | |
2597 } | |
2598 | |
2599 /* | |
2600 +--------------------------------------------------------------------+ | |
2601 | PROJECT : GSM-PS (6103) MODULE : alr_nc | | |
2602 | STATE : code ROUTINE : nc_sync_ind_last_bsic_req | | |
2603 +--------------------------------------------------------------------+ | |
2604 | |
2605 PURPOSE : Confirmation of the LAST_BSIC_REQ synchronisation request | |
2606 | |
2607 */ | |
2608 | |
2609 LOCAL void nc_sync_ind_last_bsic_req(T_MPHC_NCELL_SYNC_IND* sync_ind, | |
2610 USHORT index, | |
2611 USHORT arfcn, | |
2612 UBYTE bsic) | |
2613 { | |
2614 | |
2615 /* | |
2616 * decoding of FB / SB of hplmn cell is in progress | |
2617 * send confirmation to RR. | |
2618 */ | |
2619 PALLOC (mph_bsic_cnf, MPH_BSIC_CNF); | |
2620 | |
2621 mph_bsic_cnf->arfcn = arfcn; | |
2622 mph_bsic_cnf->bsic = bsic; | |
2623 | |
2624 if (sync_ind->sb_flag EQ SB_FOUND) | |
2625 { | |
2626 ALR_TRACE_NC_BSIC_CNF(sync_ind->radio_freq); | |
2627 | |
2628 /* | |
2629 * FCB and SCB found, set result code | |
2630 */ | |
2631 mph_bsic_cnf->cs = CS_NO_ERROR; | |
2632 | |
2633 if ( IS_EXT_MEAS_RUNNING ) | |
2634 { | |
2635 nc_set_status (LAST_BSIC_REQ, IDLE); | |
2636 alr_data->nc_data.cell[LAST_BSIC_REQ].ba_arfcn = NOT_PRESENT_16BIT; | |
2637 | |
2638 if ( alr_data->cs_data.ext_meas_state_pend NEQ CS_NULL ) | |
2639 { | |
2640 PFREE ( mph_bsic_cnf ); | |
2641 nc_stop_ext_meas_ind(); | |
2642 } | |
2643 else | |
2644 { | |
2645 ma_bsic_cnf (mph_bsic_cnf); | |
2646 } | |
2647 return; | |
2648 } | |
2649 | |
2650 ALR_EM_NEIGHBOURCELL_BCCH(EM_AVAIL); | |
2651 | |
2652 /* save data for next cell reselection */ | |
2653 { | |
2654 T_NC *pcr_cell = &alr_data->nc_data.cr_cell; | |
2655 pcr_cell->ba_arfcn = arfcn; | |
2656 pcr_cell->bsic = bsic; | |
2657 pcr_cell->frame_offset = sync_ind->fn_offset; | |
2658 pcr_cell->time_align = sync_ind->time_alignment; | |
2659 } | |
2660 | |
2661 ma_bsic_cnf (mph_bsic_cnf); | |
2662 | |
2663 nc_store_sync_ind (LAST_BSIC_REQ, sync_ind, READ_BCCH); | |
2664 #ifdef GPRS | |
2665 /* don't do the next checks for PBCCH just return | |
2666 * maybe later TODO(opt) | |
2667 */ | |
2668 if (GET_STATE (STATE_NC) EQ NC_PIM_PBCCH OR | |
2669 GET_STATE (STATE_NC) EQ NC_PTM_PBCCH) | |
2670 { | |
2671 return; | |
2672 } | |
2673 #endif | |
2674 | |
2675 index = nc_get_index (arfcn); | |
2676 | |
2677 if(index NEQ LAST_BSIC_REQ AND | |
2678 index NEQ NOT_PRESENT_16BIT) | |
2679 { | |
2680 /* | |
2681 * check BSIC of the incoming BCCH message | |
2682 */ | |
2683 switch (nc_check_bsic (index, bsic)) | |
2684 { | |
2685 case NC_CHECK_OK: | |
2686 /* | |
2687 * channel has passed NCC permitted check. | |
2688 */ | |
2689 switch (alr_data->nc_data.cell[index].status) | |
2690 { | |
2691 | |
2692 case IDLE: | |
2693 /* This patch helps during parallel search in Limited service. | |
2694 * Cell synchronised in the last BSIC_REQ fromm RR during parallel | |
2695 * search is also a part of BA list. In such a case, we store the | |
2696 * synchrinisation information, so that its can be used later by | |
2697 * nc_start_reselect. | |
2698 */ | |
2699 if(alr_data->nc_data.cell[index].one_of_twelve) | |
2700 nc_store_sync_ind (index, sync_ind, READ_BCCH_RR_NOT_INFORMED); | |
2701 else | |
2702 nc_store_sync_ind (index, sync_ind, IDLE_SYNC); | |
2703 break; | |
2704 | |
2705 case READ_FB_SB: | |
2706 /* | |
2707 * the channel shall start synchronisation of FB/SB | |
2708 * so reading of BCCH shall be started. | |
2709 */ | |
2710 if(alr_data->nc_data.cell[index].one_of_six AND | |
2711 GET_STATE(STATE_NC) NEQ NC_DEDICATED) | |
2712 nc_store_sync_ind (index, sync_ind, READ_BCCH_RR_NOT_INFORMED); | |
2713 else if(alr_data->nc_data.cell[index].one_of_twelve) | |
2714 nc_store_sync_ind (index, sync_ind, FB_SB_SYNC); | |
2715 break; | |
2716 | |
2717 case READ_SB: | |
2718 /* | |
2719 * the channel shall start synchronisation of SB | |
2720 * so this is done. | |
2721 */ | |
2722 if(alr_data->nc_data.cell[index].one_of_twelve) | |
2723 nc_store_sync_ind (index, sync_ind, FB_SB_SYNC); | |
2724 break; | |
2725 | |
2726 case FB_SB_FAILED: | |
2727 /* | |
2728 * A channel synchronisation has failed in the past. | |
2729 * Now it is synchronized again. Start BCCH reading | |
2730 * and send this information to RR after indicating | |
2731 * the synchronisation with next measurement report. | |
2732 */ | |
2733 if(alr_data->nc_data.cell[index].one_of_six AND | |
2734 GET_STATE(STATE_NC) NEQ NC_DEDICATED) | |
2735 nc_store_sync_ind (index, sync_ind, READ_BCCH_RR_NOT_INFORMED); | |
2736 else if(alr_data->nc_data.cell[index].one_of_twelve) | |
2737 nc_store_sync_ind (index, sync_ind, FB_SB_SYNC); | |
2738 break; | |
2739 | |
2740 | |
2741 case READ_SB_BCCH: | |
2742 /* | |
2743 * the channel shall start synchronisation of SB | |
2744 * followed by BCCH reading. SB synchronisation | |
2745 * is done. | |
2746 */ | |
2747 if(alr_data->nc_data.cell[index].one_of_six) | |
2748 nc_store_sync_ind (index, sync_ind, READ_BCCH); | |
2749 break; | |
2750 | |
2751 case READ_FB_SB_PENDING: | |
2752 case READ_SB_PENDING: | |
2753 case READ_SB_BCCH_PENDING: | |
2754 case READ_BCCH_PENDING: | |
2755 case READ_BCCH_PENDING_RR_NOT_INFORMED: | |
2756 /* | |
2757 * REMARK: this shall not happen, because this | |
2758 * attempt shall be killed if RR requests | |
2759 * procedure for the channel. | |
2760 */ | |
2761 ALR_TRACE_NC ("Abnormal situation sync ind"); | |
2762 break; | |
2763 | |
2764 default: | |
2765 break; | |
2766 } | |
2767 break; | |
2768 | |
2769 case NC_CHECK_BSIC_CHANGED: | |
2770 /* | |
2771 * BSIC of the channel has changed. | |
2772 */ | |
2773 switch (alr_data->nc_data.cell[index].status) | |
2774 { | |
2775 case READ_SB: | |
2776 /* | |
2777 * the channel shall start synchronisation of SB | |
2778 * so this is done, but a changed BSIC is stored. | |
2779 * Read BCCH of the channel and forward to RR. | |
2780 */ | |
2781 if(alr_data->nc_data.cell[index].one_of_six AND | |
2782 GET_STATE(STATE_NC) NEQ NC_DEDICATED) | |
2783 nc_store_sync_ind (index, sync_ind, READ_BCCH_RR_NOT_INFORMED); | |
2784 else if(alr_data->nc_data.cell[index].one_of_twelve) | |
2785 nc_store_sync_ind (index, sync_ind, FB_SB_SYNC); | |
2786 break; | |
2787 | |
2788 case FB_SB_FAILED: | |
2789 /* | |
2790 * A channel synchronisation has failed in the past. | |
2791 * Now it is synchronized again. Start BCCH reading | |
2792 * and send this information to RR after indicating | |
2793 * the synchronisation with next measurement report. | |
2794 */ | |
2795 if(alr_data->nc_data.cell[index].one_of_six AND | |
2796 GET_STATE(STATE_NC) NEQ NC_DEDICATED) | |
2797 nc_store_sync_ind (index, sync_ind, READ_BCCH_RR_NOT_INFORMED); | |
2798 else if(alr_data->nc_data.cell[index].one_of_twelve) | |
2799 nc_store_sync_ind (index, sync_ind, FB_SB_SYNC); | |
2800 break; | |
2801 | |
2802 case READ_SB_BCCH: | |
2803 /* | |
2804 * the channel shall start synchronisation of SB | |
2805 * followed by BCCH reading. SB synchronisation | |
2806 * is done. Read BCCH of the channel and forward to RR. | |
2807 */ | |
2808 if(alr_data->nc_data.cell[index].one_of_six) | |
2809 nc_store_sync_ind (index, sync_ind, READ_BCCH_RR_NOT_INFORMED); | |
2810 break; | |
2811 | |
2812 case READ_FB_SB: | |
2813 case READ_FB_SB_PENDING: | |
2814 case READ_SB_PENDING: | |
2815 case READ_SB_BCCH_PENDING: | |
2816 case READ_BCCH_PENDING: | |
2817 case READ_BCCH_PENDING_RR_NOT_INFORMED: | |
2818 /* | |
2819 * REMARK: this shall not happen, because this | |
2820 * attempt shall be killed if RR requests | |
2821 * procedure for the channel. | |
2822 */ | |
2823 ALR_TRACE_NC ("Abnormal situation sync ind (changed BSIC)"); | |
2824 break; | |
2825 | |
2826 default: | |
2827 break; | |
2828 } | |
2829 break; | |
2830 | |
2831 case NC_CHECK_NCC_FAILED: | |
2832 /* | |
2833 * ncc permitted check failed | |
2834 */ | |
2835 nc_set_status (index, EXCLUDED); | |
2836 break; | |
2837 | |
2838 default: | |
2839 break; | |
2840 } | |
2841 } | |
2842 | |
2843 ALR_EM_NEIGHBOURCELL_BSIC_CONFIRM(EM_AVAIL); | |
2844 | |
2845 } | |
2846 else | |
2847 { | |
2848 /* | |
2849 * FCB and SCB not found, set result code, | |
2850 * mark cell[LAST_BSIC_REQ] and cr_cell as invalid | |
2851 * and send negative answer to RR | |
2852 */ | |
2853 mph_bsic_cnf->cs = CS_NO_BCCH_AVAIL; | |
2854 nc_set_status (LAST_BSIC_REQ, IDLE); | |
2855 alr_data->nc_data.cell[LAST_BSIC_REQ].ba_arfcn = NOT_PRESENT_16BIT; | |
2856 alr_data->nc_data.cr_cell.ba_arfcn = NOT_PRESENT_16BIT; | |
2857 | |
2858 ma_bsic_cnf (mph_bsic_cnf); | |
2859 | |
2860 ALR_EM_NEIGHBOURCELL_BSIC_CONFIRM(EM_NOT_AVAIL); | |
2861 | |
2862 } | |
2863 } | |
2864 | |
2865 /* | |
2866 +--------------------------------------------------------------------+ | |
2867 | PROJECT : GSM-PS (6103) MODULE : alr_nc | | |
2868 | STATE : code ROUTINE : nc_sync_ind_ncell | | |
2869 +--------------------------------------------------------------------+ | |
2870 | |
2871 PURPOSE : Confirmation of a ncell synchronisation request | |
2872 | |
2873 */ | |
2874 | |
2875 LOCAL void nc_sync_ind_ncell(T_MPHC_NCELL_SYNC_IND* sync_ind, | |
2876 USHORT index, | |
2877 USHORT arfcn, | |
2878 UBYTE bsic) | |
2879 { | |
2880 #ifdef GPRS | |
2881 BOOL bsic_chg = FALSE; | |
2882 #endif | |
2883 | |
2884 if (GET_STATE(STATE_NC_PROC) EQ NC_CONFIRM) | |
2885 { | |
2886 /* eotd confirmation is active */ | |
2887 if(alr_data->nc_data.eotd_avail) | |
2888 nc_check_sync_ind_eotd(sync_ind, arfcn); | |
2889 | |
2890 TRACE_EVENT_P2("sync_ind[%u] c_sync_req=%u", arfcn, alr_data->nc_data.c_sync_req); | |
2891 /* | |
2892 * check if the end of the CONFIRM procedure (LIST_REQ) is | |
2893 * reached | |
2894 * this is done here because it is independent from EOTD | |
2895 */ | |
2896 if(alr_data->nc_data.c_sync_req EQ 0) | |
2897 { | |
2898 nc_enable_conf(); | |
2899 } | |
2900 /* | |
2901 * skip the rest of this function for scell | |
2902 * because the status for the scell is always FB_SB_SYNC | |
2903 */ | |
2904 if(alr_data->nc_data.eotd_avail AND | |
2905 arfcn EQ alr_data->serving_cell) | |
2906 return; | |
2907 } | |
2908 | |
2909 if (sync_ind->sb_flag EQ SB_FOUND) | |
2910 { | |
2911 /* | |
2912 * Synchronization successful for a normal member of the BA list. | |
2913 */ | |
2914 ALR_TRACE_NC_SB_IND_PASSED(arfcn); | |
2915 | |
2916 ALR_EM_NEIGHBOURCELL_SB(EM_AVAIL); | |
2917 | |
2918 switch (GET_STATE (STATE_NC)) | |
2919 { | |
2920 case NC_IDLE: | |
2921 case NC_DEDICATED: | |
2922 /* | |
2923 * check neighbourcell | |
2924 */ | |
2925 switch (nc_check_bsic (index, bsic)) | |
2926 { | |
2927 case NC_CHECK_OK: | |
2928 /* | |
2929 * channel has passed NCC permitted check. | |
2930 */ | |
2931 switch (alr_data->nc_data.cell[index].status) | |
2932 { | |
2933 case READ_FB_SB_PENDING: | |
2934 /* | |
2935 * initial synchronization to FB and SB | |
2936 * if the cell is a 1o6 we read the BCCH | |
2937 * otherwise we just set it to synchronized | |
2938 */ | |
2939 | |
2940 if(alr_data->nc_data.cell[index].one_of_six AND | |
2941 GET_STATE(STATE_NC) NEQ NC_DEDICATED) | |
2942 { | |
2943 nc_store_sync_ind (index, sync_ind, READ_BCCH_RR_NOT_INFORMED); | |
2944 } | |
2945 else if(alr_data->nc_data.cell[index].one_of_twelve) | |
2946 nc_store_sync_ind (index, sync_ind, FB_SB_SYNC); | |
2947 else | |
2948 { | |
2949 TRACE_EVENT_P1("sync ind for not 1o12 cell %d", arfcn); | |
2950 } | |
2951 break; | |
2952 | |
2953 case READ_SB_PENDING: | |
2954 /* | |
2955 * confirmation of SB | |
2956 */ | |
2957 alr_data->nc_data.cell[index].c_attempt = 0; | |
2958 if(alr_data->nc_data.cell[index].one_of_twelve) | |
2959 nc_store_sync_ind (index, sync_ind, FB_SB_SYNC); | |
2960 else | |
2961 nc_store_sync_ind (index, sync_ind, IDLE_SYNC); | |
2962 break; | |
2963 | |
2964 case READ_SB_BCCH_PENDING: | |
2965 /* | |
2966 * confirmation of SB before reading | |
2967 * neighbour cell BCCH all five minutes. | |
2968 */ | |
2969 if(alr_data->nc_data.cell[index].one_of_six AND | |
2970 GET_STATE(STATE_NC) EQ NC_IDLE) | |
2971 { | |
2972 nc_store_sync_ind (index, sync_ind, READ_BCCH); | |
2973 } | |
2974 else | |
2975 { | |
2976 alr_data->nc_data.cell[index].c_attempt = 0; | |
2977 if(alr_data->nc_data.cell[index].one_of_twelve) | |
2978 nc_store_sync_ind (index, sync_ind, FB_SB_SYNC); | |
2979 else | |
2980 nc_store_sync_ind (index, sync_ind, IDLE_SYNC); | |
2981 } | |
2982 break; | |
2983 case READ_BCCH_RR_NOT_INFORMED: /*TODO(opt)*/ | |
2984 case READ_BCCH_PENDING_RR_NOT_INFORMED:/*TODO(opt)*/ | |
2985 case READ_BCCH:/*TODO(opt)*/ | |
2986 case READ_BCCH_PENDING:/*TODO(opt)*/ | |
2987 TRACE_ERROR("sync_ind for ncell in READ_BCCH*"); | |
2988 if(alr_data->nc_data.cell[index].one_of_six AND | |
2989 GET_STATE(STATE_NC) EQ NC_IDLE) | |
2990 { | |
2991 nc_store_sync_ind (index, sync_ind, FB_SB_SYNC); | |
2992 } | |
2993 break; | |
2994 default: | |
2995 break; | |
2996 } /*switch(status)*/ | |
2997 break; | |
2998 case NC_CHECK_BSIC_CHANGED: | |
2999 /* | |
3000 * channel has passed NCC permitted check, | |
3001 * but a changed BSIC has been detected. | |
3002 */ | |
3003 switch (alr_data->nc_data.cell[index].status) | |
3004 { | |
3005 case READ_SB_PENDING: | |
3006 case READ_SB_BCCH_PENDING: | |
3007 /* | |
3008 * confirmation of SB indicates new BSIC | |
3009 */ | |
3010 if(alr_data->nc_data.cell[index].one_of_six AND | |
3011 GET_STATE(STATE_NC) NEQ NC_DEDICATED) | |
3012 { | |
3013 nc_store_sync_ind (index, sync_ind, READ_BCCH_RR_NOT_INFORMED); | |
3014 } | |
3015 else if(alr_data->nc_data.cell[index].one_of_twelve) | |
3016 { | |
3017 alr_data->nc_data.cell[index].c_attempt = 0; | |
3018 nc_store_sync_ind (index, sync_ind, FB_SB_SYNC); | |
3019 } | |
3020 else | |
3021 { | |
3022 TRACE_EVENT_P1("sync ind for not 1o12 cell %d", arfcn); | |
3023 nc_store_sync_ind (index, sync_ind, IDLE_SYNC); | |
3024 } | |
3025 break; | |
3026 | |
3027 default: | |
3028 break; | |
3029 } /*switch(status)*/ | |
3030 break; | |
3031 | |
3032 case NC_CHECK_NCC_FAILED: | |
3033 /* | |
3034 * ncc permitted check failed. Attempt again. | |
3035 * BSIC of a cell may always change. So do not | |
3036 * exclude this cell in IDLE mode meaurements | |
3037 */ | |
3038 if(GET_STATE(STATE_NC) EQ NC_IDLE) | |
3039 { | |
3040 alr_data->nc_data.cell[index].c_attempt = 0; | |
3041 nc_set_fb_sb_failed (index, TEN_SECONDS); | |
3042 } | |
3043 else if(GET_STATE(STATE_NC) EQ NC_DEDICATED) | |
3044 { | |
3045 alr_data->nc_data.cell[index].c_attempt = 0; | |
3046 nc_set_fb_sb_failed (index, THIRTY_SECONDS); | |
3047 } | |
3048 else | |
3049 { | |
3050 nc_set_status (index, EXCLUDED); | |
3051 } | |
3052 break; | |
3053 } | |
3054 break; | |
3055 #ifdef GPRS | |
3056 case NC_PIM_PBCCH: | |
3057 case NC_PTM_PBCCH: /*XXX*/ | |
3058 TRACE_EVENT("sync_ind PBCCH"); | |
3059 switch (alr_data->nc_data.cell[index].status) | |
3060 { | |
3061 case READ_FB_SB_PENDING: | |
3062 nc_store_sync_ind (index, sync_ind, FB_SB_SYNC); | |
3063 nc_inform_grr_of_ncell(index, GRR_SB_FOUND); | |
3064 break; | |
3065 case READ_SB_PENDING: | |
3066 if(bsic NEQ alr_data->nc_data.cell[index].bsic) | |
3067 bsic_chg = TRUE; | |
3068 else | |
3069 bsic_chg = FALSE; | |
3070 | |
3071 if(alr_data->nc_data.cell[index].one_of_twelve) | |
3072 nc_store_sync_ind (index, sync_ind, FB_SB_SYNC); | |
3073 else | |
3074 nc_store_sync_ind (index, sync_ind, IDLE_SYNC); | |
3075 | |
3076 if(bsic_chg) | |
3077 nc_inform_grr_of_ncell(index, GRR_SB_FOUND); | |
3078 break; | |
3079 default: | |
3080 break; | |
3081 } | |
3082 break; | |
3083 default: | |
3084 break; | |
3085 #endif | |
3086 } /* NC_STATE */ | |
3087 } | |
3088 else /* sb_flag EQ FALSE */ | |
3089 { | |
3090 /* | |
3091 * Synchronization failed | |
3092 */ | |
3093 ALR_TRACE_NC_SB_FAILED (sync_ind->radio_freq); | |
3094 if (alr_data->nc_data.cell[index].ba_status EQ IN_BA) | |
3095 { | |
3096 switch (alr_data->nc_data.cell[index].status) | |
3097 { | |
3098 case READ_FB_SB_PENDING: | |
3099 case READ_SB_PENDING: | |
3100 case READ_SB_BCCH_PENDING: | |
3101 | |
3102 ALR_EM_NEIGHBOURCELL_SB(EM_NOT_AVAIL); | |
3103 | |
3104 if(GET_STATE(STATE_NC) EQ NC_IDLE) | |
3105 nc_sync_failed_attempt(index); | |
3106 else if(GET_STATE(STATE_NC) EQ NC_DEDICATED) | |
3107 nc_sync_failed_attempt_dedicated(index); | |
3108 #ifdef GPRS /*XXX*/ | |
3109 else | |
3110 nc_sync_failed_gprs(index); | |
3111 #endif | |
3112 break; | |
3113 default: | |
3114 break; | |
3115 } | |
3116 } | |
3117 else | |
3118 { /* | |
3119 * the cell currently or perhaps for a longer time doesn't | |
3120 * belong to the BA list, no more attempts to synchronize now | |
3121 */ | |
3122 switch (alr_data->nc_data.cell[index].status) | |
3123 { | |
3124 case READ_FB_SB_PENDING: | |
3125 nc_set_status (index, IDLE); | |
3126 break; | |
3127 case READ_SB_PENDING: | |
3128 alr_data->nc_data.cell[index].c_attempt++; | |
3129 alr_data->nc_data.cell[index].tim_valid = TV_APPROX_TIMING_INFO; | |
3130 nc_set_status (index, READ_SB); | |
3131 break; | |
3132 case READ_SB_BCCH_PENDING: | |
3133 alr_data->nc_data.cell[index].c_attempt++; | |
3134 alr_data->nc_data.cell[index].tim_valid = TV_APPROX_TIMING_INFO; | |
3135 nc_set_status (index, READ_SB_BCCH); | |
3136 break; | |
3137 default: | |
3138 break; | |
3139 } | |
3140 } | |
3141 } /* error_flag check */ | |
3142 } | |
3143 | |
3144 /* | |
3145 +--------------------------------------------------------------------+ | |
3146 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3147 | STATE : code ROUTINE : nc_check_sync_ind_eotd | | |
3148 +--------------------------------------------------------------------+ | |
3149 | |
3150 PURPOSE : copies the measurement results to the MPH_NCELL_POS_IND | |
3151 while EOTD is active | |
3152 | |
3153 */ | |
3154 LOCAL void nc_check_sync_ind_eotd (T_MPHC_NCELL_SYNC_IND* sync_ind, USHORT arfcn) | |
3155 { | |
3156 T_MPH_NCELL_POS_IND* ppos_ind; | |
3157 | |
3158 if ((ppos_ind = alr_data->nc_data.ppos_ind) EQ NULL) | |
3159 { | |
3160 TRACE_ERROR("nc_check_sync_ind_eotd() while alr_data->nc_data.ppos_ind==0"); | |
3161 return; | |
3162 } | |
3163 | |
3164 if (arfcn EQ alr_data->serving_cell) | |
3165 { | |
3166 if (ppos_ind->eotd_res EQ 0) /*0 doesn't mean EOTD_SUCC here | |
3167 - it indicates that no SC results are present*/ | |
3168 { | |
3169 nc_store_eotd(&(ppos_ind->eotd_sc_res), sync_ind, arfcn); | |
3170 ppos_ind->fn = sync_ind->fn_in_sb; | |
3171 ppos_ind->eotd_res++; | |
3172 } | |
3173 else /*first EOTD results for SC are already present | |
3174 - now continue with second SC results*/ | |
3175 { | |
3176 nc_store_eotd((T_eotd_sc_res*)(&(ppos_ind->eotd_sc_res1)), sync_ind, | |
3177 arfcn); | |
3178 ppos_ind->eotd_res = EOTD_SUCC; | |
3179 ppos_ind->ta = GET_STATE(STATE_NC) EQ NC_DEDICATED ? | |
3180 alr_data->nc_data.tav : NOT_PRESENT_8BIT; | |
3181 PSENDX (RR, ppos_ind); | |
3182 alr_data->nc_data.ppos_ind = NULL; | |
3183 | |
3184 if (alr_data->nc_data.ppos_req NEQ NULL) | |
3185 { | |
3186 PFREE(alr_data->nc_data.ppos_req); | |
3187 alr_data->nc_data.ppos_req = NULL; | |
3188 } | |
3189 } | |
3190 } | |
3191 else | |
3192 { | |
3193 if (ppos_ind->c_eotd_nc_res < MAX_NCELL_EOTD_RES) | |
3194 { | |
3195 nc_store_eotd((T_eotd_sc_res*)( | |
3196 &(ppos_ind->eotd_nc_res[ppos_ind->c_eotd_nc_res])) , sync_ind, arfcn); | |
3197 (ppos_ind->c_eotd_nc_res)++; | |
3198 } | |
3199 else | |
3200 TRACE_ERROR("more than MAX_NCELL_EOTD_RES ncell sync indications"); | |
3201 } | |
3202 } | |
3203 | |
3204 /* | |
3205 +--------------------------------------------------------------------+ | |
3206 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3207 | STATE : code ROUTINE : nc_sync_failed_attempt | | |
3208 +--------------------------------------------------------------------+ | |
3209 | |
3210 PURPOSE : A synchronisation attempt has failed during idle mode. | |
3211 | |
3212 */ | |
3213 LOCAL void nc_sync_failed_attempt (USHORT index) | |
3214 { | |
3215 switch (alr_data->nc_data.cell[index].c_attempt) | |
3216 { | |
3217 case 0: | |
3218 case 1: | |
3219 case 2: | |
3220 case 3: | |
3221 /* | |
3222 * for attempts 1 to 4 try it again | |
3223 * after ten seconds | |
3224 */ | |
3225 nc_set_fb_sb_failed (index, TEN_SECONDS); | |
3226 | |
3227 break; | |
3228 default: | |
3229 /* | |
3230 * if there are more attempts, exclude | |
3231 * the cell from further attempts | |
3232 * Store last fieldstrength value | |
3233 */ | |
3234 nc_set_status (index, EXCLUDED); | |
3235 break; | |
3236 } | |
3237 } | |
3238 | |
3239 /* | |
3240 +--------------------------------------------------------------------+ | |
3241 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3242 | STATE : code ROUTINE : nc_sync_failed_attempt_dedicated | | |
3243 +--------------------------------------------------------------------+ | |
3244 | |
3245 PURPOSE : A synchronisation attempt has failed during dedicated mode. | |
3246 | |
3247 */ | |
3248 LOCAL void nc_sync_failed_attempt_dedicated (USHORT index) | |
3249 { | |
3250 /* | |
3251 * Store last fieldstrength value | |
3252 */ | |
3253 switch (alr_data->nc_data.cell[index].c_attempt) | |
3254 { | |
3255 case 0: | |
3256 case 1: | |
3257 case 2: | |
3258 /* | |
3259 * for attempts 1 to 3 try it again immediately | |
3260 */ | |
3261 alr_data->nc_data.cell[index].c_attempt++; | |
3262 if (alr_data->nc_data.cell[index].status EQ READ_FB_SB_PENDING) | |
3263 alr_data->nc_data.cell[index].tim_valid = TV_INVALID_TIMING_INFO; | |
3264 else | |
3265 alr_data->nc_data.cell[index].tim_valid = TV_APPROX_TIMING_INFO; | |
3266 nc_set_status (index, READ_FB_SB); | |
3267 break; | |
3268 default: | |
3269 /* | |
3270 * if there are more attempts, exclude | |
3271 * the cell from further attempts | |
3272 */ | |
3273 nc_set_status (index, EXCLUDED); | |
3274 break; | |
3275 } | |
3276 } | |
3277 | |
3278 /* | |
3279 +--------------------------------------------------------------------+ | |
3280 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3281 | STATE : code ROUTINE : nc_start_dedicated | | |
3282 +--------------------------------------------------------------------+ | |
3283 | |
3284 PURPOSE : Process signal nc_start_dedicated from SDL process | |
3285 Main_Control. | |
3286 | |
3287 */ | |
3288 | |
3289 GLOBAL void nc_start_dedicated (UBYTE pwrc, UBYTE dtx) | |
3290 { | |
3291 USHORT i; | |
3292 | |
3293 switch(GET_STATE(STATE_NC)) | |
3294 { | |
3295 case NC_CON_EST: | |
3296 for (i = 0; i < alr_data->nc_data.c_ba_arfcn; i++) | |
3297 { | |
3298 switch (alr_data->nc_data.cell[i].status) | |
3299 { | |
3300 case READ_BCCH_RR_NOT_INFORMED: | |
3301 case FB_SB_SYNC_RR_NOT_INFORMED: | |
3302 case READ_BCCH: | |
3303 /* | |
3304 * BCCH reading is not needed during dedicated mode, | |
3305 * but SB synchronisation is already done. | |
3306 * clear a stored BCCH if needed. | |
3307 */ | |
3308 nc_set_status (i, FB_SB_SYNC); | |
3309 break; | |
3310 | |
3311 case READ_SB_BCCH: | |
3312 nc_set_status (i, READ_SB); | |
3313 break; | |
3314 | |
3315 case READ_FB_SB_PENDING: | |
3316 case READ_SB_PENDING: | |
3317 case READ_SB_BCCH_PENDING: | |
3318 case READ_BCCH_PENDING_RR_NOT_INFORMED: | |
3319 case READ_BCCH_PENDING: | |
3320 TRACE_ERROR("Abnormal situation nc_start_dedi"); | |
3321 nc_set_status (i, IDLE); | |
3322 break; | |
3323 case FB_SB_FAILED: | |
3324 nc_set_status (i, IDLE); | |
3325 break; | |
3326 case IDLE_SYNC: | |
3327 if (alr_data->nc_data.cell[i].c_sync > 0) | |
3328 alr_data->nc_data.cell[i].c_sync = TEN_SECONDS; | |
3329 break; | |
3330 default: | |
3331 break; | |
3332 } | |
3333 } | |
3334 | |
3335 nc_clear_last_bsic(); | |
3336 | |
3337 alr_data->nc_data.pwrc = pwrc; | |
3338 alr_data->nc_data.dtx = dtx; | |
3339 | |
3340 SET_STATE (STATE_NC, NC_DEDICATED); | |
3341 nc_enable_conf(); | |
3342 break; | |
3343 default: | |
3344 TRACE_ERROR("nc_start_dedicated in wrong state"); | |
3345 break; | |
3346 } | |
3347 | |
3348 } | |
3349 | |
3350 /* | |
3351 +--------------------------------------------------------------------+ | |
3352 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3353 | STATE : code ROUTINE : nc_suspend | | |
3354 +--------------------------------------------------------------------+ | |
3355 | |
3356 PURPOSE : This stops all active processes like FB/SB and BCCH reading | |
3357 if | |
3358 - the mobile start connection establishment | |
3359 - RR requests power measurements parallel to idle mode | |
3360 - leave dedicated mode. | |
3361 | |
3362 */ | |
3363 | |
3364 GLOBAL void nc_suspend (void) | |
3365 { | |
3366 ALR_TRACE_NC( "nc_suspend"); | |
3367 | |
3368 switch (GET_STATE(STATE_NC)) | |
3369 { | |
3370 case NC_IDLE: | |
3371 case NC_DEDICATED: | |
3372 nc_clear_last_bsic(); | |
3373 nc_stop_all(); | |
3374 nc_disable_conf(FREE_POS_IND); | |
3375 | |
3376 SET_STATE(STATE_NC, NC_CON_EST); | |
3377 break; | |
3378 case NC_CON_EST: | |
3379 break; | |
3380 #ifdef GPRS | |
3381 case NC_PIM_PBCCH: | |
3382 if(alr_data->nc_data.cell[LAST_BSIC_REQ].status NEQ IDLE) | |
3383 nc_clear_last_bsic(); | |
3384 /*lint -fallthrough*/ | |
3385 case NC_PTM_PBCCH: | |
3386 nc_stop_all(); | |
3387 nc_disable_conf(FREE_POS_IND); | |
3388 SET_STATE(STATE_NC, NC_CON_EST); | |
3389 break; | |
3390 #endif | |
3391 default: | |
3392 break; | |
3393 } | |
3394 } | |
3395 | |
3396 GLOBAL void nc_suspend_handover (void) | |
3397 { | |
3398 ALR_TRACE_NC( "nc_suspend_handover"); | |
3399 | |
3400 switch (GET_STATE(STATE_NC)) | |
3401 { | |
3402 case NC_DEDICATED: | |
3403 nc_stop_all(); | |
3404 nc_disable_conf(FREE_POS_IND); | |
3405 break; | |
3406 } | |
3407 } | |
3408 /* | |
3409 +--------------------------------------------------------------------+ | |
3410 | PROJECT : GSM-PS (6103) MODULE : alr_nc | | |
3411 | STATE : code ROUTINE : nc_resume | | |
3412 +--------------------------------------------------------------------+ | |
3413 | |
3414 PURPOSE : Only needed for alr_gprs.c | |
3415 | |
3416 */ | |
3417 | |
3418 GLOBAL void nc_resume (void) | |
3419 { | |
3420 SET_STATE (STATE_NC, NC_IDLE); | |
3421 nc_enable_conf(); | |
3422 } | |
3423 | |
3424 /* | |
3425 +--------------------------------------------------------------------+ | |
3426 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3427 | STATE : code ROUTINE : nc_update_dedicated | | |
3428 +--------------------------------------------------------------------+ | |
3429 | |
3430 PURPOSE : Process signal nc_update_dedicated from SDL process | |
3431 Dedi_Control. | |
3432 | |
3433 */ | |
3434 | |
3435 GLOBAL void nc_update_dedicated (UBYTE dtx, UBYTE pwrc) | |
3436 { | |
3437 UBYTE i, j; | |
3438 UBYTE c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
3439 | |
3440 switch(GET_STATE (STATE_NC)) | |
3441 { | |
3442 case NC_DEDICATED: | |
3443 { | |
3444 PALLOC (upd_dedi, MPHC_UPDATE_BA_LIST); | |
3445 | |
3446 /* | |
3447 * updated values of pwrc or dtx can be configure | |
3448 * only by sending a new neighbourcell list to layer 1 | |
3449 */ | |
3450 alr_data->nc_data.pwrc = pwrc; | |
3451 alr_data->nc_data.dtx = dtx; | |
3452 | |
3453 for (i = 0, j = 0; i < c_ba_arfcn; i++) | |
3454 { | |
3455 if (alr_data->nc_data.cell[i].ba_status EQ IN_BA) | |
3456 upd_dedi->chan_list.radio_freq[j++] = | |
3457 ARFCN_TO_L1(alr_data->nc_data.cell[i].ba_arfcn); | |
3458 } | |
3459 | |
3460 upd_dedi->num_of_chans = j; | |
3461 alr_data->nc_data.ba_id = ALR_ALLOCATE_NEW_BA ( alr_data->nc_data.ba_id ); | |
3462 upd_dedi->ba_id = alr_data->nc_data.ba_id; | |
3463 upd_dedi->pwrc = alr_data->nc_data.pwrc; | |
3464 upd_dedi->dtx_allowed = alr_data->nc_data.dtx; | |
3465 | |
3466 alr_data->nc_data.update = TRUE; | |
3467 ma_nc_update_ba_list (upd_dedi); | |
3468 } | |
3469 break; | |
3470 default: | |
3471 TRACE_ERROR("nc_update_dedicated in wrong state"); | |
3472 break; | |
3473 } | |
3474 } | |
3475 | |
3476 GLOBAL void nc_resume_dedicated(void) | |
3477 { | |
3478 nc_enable_conf(); | |
3479 } | |
3480 /* | |
3481 +--------------------------------------------------------------------+ | |
3482 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3483 | STATE : code ROUTINE : nc_get_fn_time | | |
3484 +--------------------------------------------------------------------+ | |
3485 | |
3486 PURPOSE : Export Procedure to request frame offset and time | |
3487 alignment of neighbour cells. | |
3488 | |
3489 Returns FALSE if timing information not found. | |
3490 | |
3491 */ | |
3492 | |
3493 GLOBAL BOOL nc_get_fn_time (USHORT channel, | |
3494 ULONG *fn, | |
3495 ULONG *time) | |
3496 { | |
3497 USHORT index; | |
3498 if( channel EQ alr_data->serving_cell) | |
3499 { | |
3500 *fn = 0; | |
3501 *time = 0; | |
3502 return TRUE; | |
3503 } | |
3504 | |
3505 /* Check if we have read SYNC on this channel */ | |
3506 index = nc_get_index (channel); | |
3507 if (index NEQ NOT_PRESENT_16BIT) | |
3508 { | |
3509 *fn = alr_data->nc_data.cell[index].frame_offset; | |
3510 *time = alr_data->nc_data.cell[index].time_align; | |
3511 | |
3512 if( (*fn EQ NOT_PRESENT_32BIT) OR (*time EQ NOT_PRESENT_32BIT)) | |
3513 { | |
3514 return FALSE; | |
3515 } | |
3516 else | |
3517 { | |
3518 return TRUE; | |
3519 } | |
3520 } | |
3521 else | |
3522 { | |
3523 *fn = NOT_PRESENT_32BIT; | |
3524 *time = NOT_PRESENT_32BIT; | |
3525 return FALSE; | |
3526 } | |
3527 } | |
3528 | |
3529 | |
3530 /* | |
3531 +--------------------------------------------------------------------+ | |
3532 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3533 | STATE : code ROUTINE : nc_start_reselect | | |
3534 +--------------------------------------------------------------------+ | |
3535 | |
3536 PURPOSE : Process signal nc_start_reselect from SDL process | |
3537 Main_Control. | |
3538 | |
3539 */ | |
3540 | |
3541 GLOBAL void nc_start_reselect (USHORT arfcn) | |
3542 { | |
3543 USHORT index; | |
3544 T_NC *pcell; | |
3545 | |
3546 ALR_TRACE_NC_RESELECT(arfcn); | |
3547 | |
3548 index = nc_get_index (arfcn); | |
3549 if (index EQ NOT_PRESENT_16BIT) | |
3550 { | |
3551 if (arfcn NEQ alr_data->nc_data.cr_cell.ba_arfcn) | |
3552 { | |
3553 ma_error_ind (CS_BCCH_READ_ERROR, arfcn); | |
3554 return; | |
3555 } | |
3556 else | |
3557 { | |
3558 pcell = &alr_data->nc_data.cr_cell; | |
3559 } | |
3560 } | |
3561 else | |
3562 { | |
3563 pcell = &alr_data->nc_data.cell[index]; | |
3564 | |
3565 /* Cannot to reselect to a cell for which the synchronization information | |
3566 * is not available | |
3567 */ | |
3568 if (pcell->bsic EQ NOT_PRESENT_8BIT) | |
3569 { | |
3570 ma_error_ind (CS_NC_SYNC_FAILED, arfcn); | |
3571 return; | |
3572 } | |
3573 } | |
3574 | |
3575 | |
3576 { | |
3577 PALLOC(reselect, MPHC_NEW_SCELL_REQ); | |
3578 | |
3579 reselect->radio_freq = ARFCN_TO_L1(arfcn); | |
3580 reselect->fn_offset = (ULONG)pcell->frame_offset; | |
3581 reselect->time_alignment = (ULONG)pcell->time_align; | |
3582 reselect->tsc = pcell->bsic; | |
3583 alr_data->nc_data.channel = arfcn; | |
3584 | |
3585 ALR_TRACE_NC_FN_TA(index, reselect->fn_offset, reselect->time_alignment); | |
3586 | |
3587 ALR_EM_CONFIGURE_CELL_RESELECTION; | |
3588 | |
3589 ma_new_scell_req(reselect); | |
3590 } | |
3591 } | |
3592 | |
3593 /* | |
3594 +--------------------------------------------------------------------+ | |
3595 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3596 | STATE : code ROUTINE : nc_report | | |
3597 +--------------------------------------------------------------------+ | |
3598 | |
3599 PURPOSE : Process signal nc_report from SDL process | |
3600 Main_Control. | |
3601 | |
3602 */ | |
3603 | |
3604 GLOBAL void nc_report (T_MPHC_RXLEV_PERIODIC_IND *rxlev_periodic_ind) | |
3605 { | |
3606 ALR_TRACE_NC("nc_report"); | |
3607 | |
3608 | |
3609 switch(GET_STATE(STATE_NC)) | |
3610 { | |
3611 case NC_IDLE: | |
3612 case NC_CON_EST: | |
3613 nc_store_rxlev (rxlev_periodic_ind); | |
3614 | |
3615 #ifdef GPRS | |
3616 nc_rxlev_sc_req (rxlev_periodic_ind->s_rxlev); | |
3617 #endif | |
3618 nc_check_activity(); | |
3619 break; | |
3620 default: | |
3621 TRACE_ERROR("nc_report in invalid state"); | |
3622 break; | |
3623 } | |
3624 } | |
3625 | |
3626 /* | |
3627 +--------------------------------------------------------------------+ | |
3628 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3629 | STATE : code ROUTINE : nc_report_dedicated | | |
3630 +--------------------------------------------------------------------+ | |
3631 | |
3632 PURPOSE : Process signal nc_report_dedicated from SDL process | |
3633 Main_Control. | |
3634 | |
3635 */ | |
3636 | |
3637 GLOBAL void nc_report_dedicated (T_MPHC_MEAS_REPORT *meas_report) | |
3638 { | |
3639 switch(GET_STATE(STATE_NC)) | |
3640 { | |
3641 case NC_DEDICATED: | |
3642 nc_store_dedicated (meas_report); | |
3643 nc_check_activity (); | |
3644 break; | |
3645 default: | |
3646 TRACE_ERROR("nc_report_dedicated in wrong state"); | |
3647 break; | |
3648 } | |
3649 } | |
3650 | |
3651 /* | |
3652 +--------------------------------------------------------------------+ | |
3653 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3654 | STATE : code ROUTINE : nc_update_list | | |
3655 +--------------------------------------------------------------------+ | |
3656 | |
3657 PURPOSE : Procedure to update frame offset and time alignment after | |
3658 cell change. All values are relative to the actual serving | |
3659 cell. | |
3660 | |
3661 */ | |
3662 | |
3663 #define TDMA_FRAMES_PER_HYPERFRAME 2715648 | |
3664 | |
3665 GLOBAL void nc_update_list (USHORT channel) | |
3666 { | |
3667 USHORT index; | |
3668 USHORT i; | |
3669 | |
3670 switch(GET_STATE(STATE_NC)) | |
3671 { | |
3672 case NC_CON_EST: | |
3673 case NC_DEDICATED: | |
3674 case NC_IDLE: | |
3675 index = nc_get_index (channel); | |
3676 if (index NEQ NOT_PRESENT_16BIT) | |
3677 { | |
3678 for (i = 0; i < alr_data->nc_data.c_ba_arfcn; i++) | |
3679 { | |
3680 if (i NEQ index) | |
3681 { | |
3682 ULONG new_frame_offset; | |
3683 ULONG new_time_align; | |
3684 | |
3685 new_frame_offset = (alr_data->nc_data.cell[i].frame_offset - | |
3686 alr_data->nc_data.cell[index].frame_offset + | |
3687 TDMA_FRAMES_PER_HYPERFRAME) % | |
3688 TDMA_FRAMES_PER_HYPERFRAME; | |
3689 if (alr_data->nc_data.cell[i].time_align >= alr_data->nc_data.cell[index].time_align) | |
3690 { | |
3691 new_time_align = alr_data->nc_data.cell[i].time_align - | |
3692 alr_data->nc_data.cell[index].time_align; | |
3693 } | |
3694 else | |
3695 { | |
3696 new_time_align = 5000 + alr_data->nc_data.cell[i].time_align - | |
3697 alr_data->nc_data.cell[index].time_align; | |
3698 new_frame_offset = (new_frame_offset + 1) % | |
3699 TDMA_FRAMES_PER_HYPERFRAME; | |
3700 } /* time_align */ | |
3701 alr_data->nc_data.cell[i].frame_offset = new_frame_offset; | |
3702 alr_data->nc_data.cell[i].time_align = new_time_align; | |
3703 } /* i NEQ index */ | |
3704 } /* for(all ncells) */ | |
3705 | |
3706 ALR_TRACE_NC("set chan to 0"); | |
3707 | |
3708 alr_data->nc_data.cell[index].frame_offset = 0; | |
3709 alr_data->nc_data.cell[index].time_align = 0; | |
3710 } /* NOT_PRESENT */ | |
3711 break; | |
3712 default: | |
3713 TRACE_ERROR("nc_update_list in invalid state"); | |
3714 break; | |
3715 } | |
3716 } | |
3717 | |
3718 /* | |
3719 +--------------------------------------------------------------------+ | |
3720 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3721 | STATE : code ROUTINE : nc_add_offset | | |
3722 +--------------------------------------------------------------------+ | |
3723 | |
3724 PURPOSE : If the mobile comes back from dedicated mode all synchronized | |
3725 neighbourcells make a status transition to READ_BCCH_RR_NOT_INFORMED. | |
3726 This triggers reading of the neighbourcell BCCH. | |
3727 | |
3728 */ | |
3729 | |
3730 GLOBAL void nc_add_offset (void) | |
3731 { | |
3732 USHORT i; | |
3733 USHORT c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
3734 | |
3735 for (i = 0; i < c_ba_arfcn; i++) | |
3736 { | |
3737 if (alr_data->nc_data.cell[i].ba_arfcn NEQ alr_data->serving_cell) | |
3738 { | |
3739 /*XXX c_sync should be the same in idle and dedic also for pbcchc | |
3740 so no action here */ | |
3741 switch (alr_data->nc_data.cell[i].status) | |
3742 { | |
3743 case FB_SB_SYNC: | |
3744 case READ_SB: | |
3745 nc_set_status (i, READ_BCCH_RR_NOT_INFORMED); | |
3746 break; | |
3747 default: | |
3748 break; | |
3749 | |
3750 } | |
3751 } | |
3752 else | |
3753 nc_set_status (i, FB_SB_SYNC); | |
3754 } | |
3755 } | |
3756 | |
3757 /* | |
3758 +--------------------------------------------------------------------+ | |
3759 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3760 | STATE : code ROUTINE : nc_fill_report_sc_dedi | | |
3761 +--------------------------------------------------------------------+ | |
3762 | |
3763 PURPOSE : Fills the serving cell values for a measurement report. | |
3764 | |
3765 */ | |
3766 | |
3767 GLOBAL void nc_fill_report_sc_dedi (T_MPH_MEASUREMENT_IND *rr_report, | |
3768 UBYTE ncells) | |
3769 { | |
3770 rr_report->valid = TRUE; | |
3771 rr_report->ncells.no_of_ncells = ncells; | |
3772 rr_report->arfcn = alr_data->serving_cell; | |
3773 rr_report->fn_offset = 103; /* average of SDCCH/FACCH */ | |
3774 rr_report->dtx = alr_data->nc_data.act_dtx; | |
3775 rr_report->rx_lev_full = (UBYTE)alr_data->nc_data.rxlev_full; | |
3776 if (rr_report->rx_lev_full > 63) | |
3777 rr_report->rx_lev_full = 63; | |
3778 rr_report->rx_lev_sub = (UBYTE)alr_data->nc_data.rxlev_sub; | |
3779 if (rr_report->rx_lev_sub > 63) | |
3780 rr_report->rx_lev_sub = 63; | |
3781 rr_report->rx_qual_full = alr_data->nc_data.rxqual_full; | |
3782 rr_report->rx_qual_sub = alr_data->nc_data.rxqual_sub; | |
3783 rr_report->otd = alr_data->nc_data.tav; | |
3784 | |
3785 if(ncells EQ 0) | |
3786 { | |
3787 /* | |
3788 * rxlev of SC BCCH channel is not avail | |
3789 * use approx value (rxlev_sub) | |
3790 */ | |
3791 rr_report->bcch_rxlev_of_sc = rr_report->rx_lev_sub; | |
3792 } | |
3793 else | |
3794 { | |
3795 USHORT index = nc_get_index(alr_data->serving_cell); | |
3796 if(index EQ NOT_PRESENT_16BIT) | |
3797 { | |
3798 TRACE_EVENT("Error SC not present in BA list"); | |
3799 rr_report->bcch_rxlev_of_sc = rr_report->rx_lev_sub; | |
3800 } | |
3801 else | |
3802 { | |
3803 if((UBYTE) alr_data->nc_data.cell[index].rxlev_average > 63) | |
3804 rr_report->bcch_rxlev_of_sc = 63; | |
3805 else | |
3806 rr_report->bcch_rxlev_of_sc = (UBYTE)alr_data->nc_data.cell[index].rxlev_average; | |
3807 } | |
3808 } | |
3809 } | |
3810 | |
3811 /* | |
3812 +--------------------------------------------------------------------+ | |
3813 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3814 | STATE : code ROUTINE : inform GRR | | |
3815 +--------------------------------------------------------------------+ | |
3816 | |
3817 PURPOSE : inform GRR | |
3818 | |
3819 */ | |
3820 | |
3821 #ifdef GPRS | |
3822 LOCAL void nc_inform_grr_of_ncell (USHORT index, UBYTE type) | |
3823 { | |
3824 PALLOC(rr_rep, MPH_MEASUREMENT_IND); | |
3825 rr_rep->ncells.no_of_ncells = 1; | |
3826 rr_rep->ncells.arfcn[0] = alr_data->nc_data.cell[index].ba_arfcn; | |
3827 if(type EQ GRR_SB_FOUND) | |
3828 rr_rep->ncells.bsic[0] = alr_data->nc_data.cell[index].bsic; | |
3829 else | |
3830 rr_rep->ncells.bsic[0] = type; | |
3831 rr_rep->gprs_sync = SYNC_RESULTS; | |
3832 PSENDX(RR,rr_rep); | |
3833 } | |
3834 | |
3835 LOCAL void remove_ncell_and_inform_grr (USHORT index) | |
3836 { | |
3837 nc_inform_grr_of_ncell (index, GRR_SB_UNKNOWN); | |
3838 nc_remove_channel_from_ba_list(index); | |
3839 } | |
3840 #endif | |
3841 | |
3842 | |
3843 /* | |
3844 +--------------------------------------------------------------------+ | |
3845 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3846 | STATE : code ROUTINE : nc_build_rr_report | | |
3847 +--------------------------------------------------------------------+ | |
3848 | |
3849 PURPOSE : Fills a measurement report to RR with neighbour cell | |
3850 information. | |
3851 | |
3852 */ | |
3853 | |
3854 LOCAL void nc_build_rr_report (T_MPH_MEASUREMENT_IND *rr_report) | |
3855 { | |
3856 UBYTE c_report; | |
3857 UBYTE c_ba_list; | |
3858 T_NC * pcell = alr_data->nc_data.cell; | |
3859 | |
3860 c_report = 0; | |
3861 rr_report->valid = TRUE; | |
3862 | |
3863 for (c_ba_list = 0; c_ba_list < alr_data->nc_data.c_ba_arfcn AND | |
3864 c_report < MAX_RR_NCELL_CNT; c_ba_list++, pcell++) | |
3865 { | |
3866 if(pcell->one_of_six AND pcell->ba_status EQ IN_BA) | |
3867 { | |
3868 switch (pcell->status) | |
3869 { | |
3870 case FB_SB_SYNC_RR_NOT_INFORMED: | |
3871 /* | |
3872 * the cell is synchronized but RR has no prior | |
3873 * knowledge of the cell, but we may have already | |
3874 * read data from the ncell BCCH. This check is performed | |
3875 * after sending the measurement report | |
3876 */ | |
3877 case FB_SB_SYNC: | |
3878 case READ_BCCH: | |
3879 case READ_SB: | |
3880 case READ_SB_BCCH: | |
3881 /* | |
3882 * we may be currently reading this SB/FB or BCCH of the cell | |
3883 * pass up this cell also | |
3884 * if READ_FB_SB_PENDING this may be the first time that the | |
3885 * cell is read so check if the bsic of this cell has been | |
3886 * read already | |
3887 */ | |
3888 case READ_SB_PENDING: | |
3889 case READ_SB_BCCH_PENDING: | |
3890 case READ_BCCH_PENDING: | |
3891 case READ_FB_SB_PENDING: | |
3892 if (pcell->ba_arfcn NEQ alr_data->serving_cell AND | |
3893 pcell->bsic NEQ NOT_PRESENT_8BIT) | |
3894 { | |
3895 rr_report->ncells.arfcn[c_report] = pcell->ba_arfcn; | |
3896 rr_report->ncells.rx_lev[c_report] = (UBYTE)pcell->rxlev_average; | |
3897 #if defined(_SIMULATION_) | |
3898 TRACE_EVENT_P3 ("rx_lev%u[%u]=%d", | |
3899 c_report, rr_report->ncells.arfcn[c_report], | |
3900 rr_report->ncells.rx_lev[c_report]); | |
3901 #endif /* _SIMULATION_ */ | |
3902 rr_report->ncells.bsic[c_report] = pcell->bsic; | |
3903 rr_report->ncells.time_alignmt[c_report] = pcell->time_align; | |
3904 rr_report->ncells.frame_offset[c_report++] = pcell->frame_offset; | |
3905 } | |
3906 break; | |
3907 case READ_BCCH_RR_NOT_INFORMED: | |
3908 case READ_BCCH_PENDING_RR_NOT_INFORMED: | |
3909 case READ_FB_SB: | |
3910 /* do nothing */ | |
3911 default: | |
3912 break; | |
3913 } | |
3914 }/* not one_of_six*/ | |
3915 } | |
3916 rr_report->ncells.no_of_ncells = c_report; | |
3917 } | |
3918 | |
3919 | |
3920 | |
3921 /* | |
3922 +--------------------------------------------------------------------+ | |
3923 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
3924 | STATE : code ROUTINE : nc_build_nwctrl_rr_report | | |
3925 +--------------------------------------------------------------------+ | |
3926 | |
3927 PURPOSE : Fills a measurement report to RR with neighbour cell | |
3928 information. | |
3929 | |
3930 */ | |
3931 | |
3932 | |
3933 #ifdef GPRS | |
3934 GLOBAL void nc_build_nwctrl_rr_report (T_MPH_MEAS_REP_CNF *rr_report) | |
3935 { | |
3936 UBYTE c_report; | |
3937 UBYTE c_ba_list; | |
3938 USHORT index; | |
3939 T_NC * pcell; | |
3940 | |
3941 /* | |
3942 * Store the rxlev average for the serving cell | |
3943 */ | |
3944 index = nc_get_index(alr_data->serving_cell); | |
3945 if ( index NEQ NOT_PRESENT_16BIT ) | |
3946 { | |
3947 pcell = &alr_data->nc_data.cell[index]; | |
3948 rr_report->meas_rep[0].arfcn = alr_data->serving_cell; | |
3949 rr_report->meas_rep[0].bsic = pcell->bsic; | |
3950 | |
3951 if(pcell->c_nc_rxlev) | |
3952 { | |
3953 rr_report->meas_rep[0].rx_lev = pcell->nc_rxlev/pcell->c_nc_rxlev; | |
3954 } | |
3955 #if defined(_SIMULATION_) | |
3956 TRACE_EVENT_P3 ("nw_sc__rxlev[%u]=acc : %d, count:%d",rr_report->meas_rep[0].arfcn,pcell->nc_rxlev,pcell->c_nc_rxlev); | |
3957 #endif /* _SIMULATION_ */ | |
3958 } | |
3959 | |
3960 c_report = 0; | |
3961 pcell = alr_data->nc_data.cell; | |
3962 | |
3963 for (c_ba_list = 0; c_ba_list < alr_data->nc_data.c_ba_arfcn AND | |
3964 c_report < MAX_RR_NCELL_CNT; c_ba_list++, pcell++) | |
3965 { | |
3966 if(pcell->one_of_six AND pcell->ba_status EQ IN_BA) | |
3967 { | |
3968 switch (pcell->status) | |
3969 { | |
3970 case FB_SB_SYNC_RR_NOT_INFORMED: | |
3971 /* | |
3972 * the cell is synchronized but RR has no prior | |
3973 * knowledge of the cell, but we may have already | |
3974 * read data from the ncell BCCH. This check is performed | |
3975 * after sending the measurement report | |
3976 */ | |
3977 case FB_SB_SYNC: | |
3978 case READ_BCCH: | |
3979 case READ_SB: | |
3980 case READ_SB_BCCH: | |
3981 /* | |
3982 * we may be currently reading this SB/FB or BCCH of the cell | |
3983 * pass up this cell also | |
3984 * if READ_FB_SB_PENDING this may be the first time that the | |
3985 * cell is read so check if the bsic of this cell has been | |
3986 * read already | |
3987 */ | |
3988 case READ_SB_PENDING: | |
3989 case READ_SB_BCCH_PENDING: | |
3990 case READ_BCCH_PENDING: | |
3991 case READ_FB_SB_PENDING: | |
3992 if (pcell->ba_arfcn NEQ alr_data->serving_cell AND | |
3993 pcell->bsic NEQ NOT_PRESENT_8BIT) | |
3994 { | |
3995 rr_report->meas_rep[c_report+1].arfcn = pcell->ba_arfcn; | |
3996 rr_report->meas_rep[c_report+1].bsic = pcell->bsic; | |
3997 if(pcell->c_nc_rxlev) | |
3998 { | |
3999 rr_report->meas_rep[c_report+1].rx_lev = pcell->nc_rxlev/pcell->c_nc_rxlev; | |
4000 } | |
4001 | |
4002 #if defined(_SIMULATION_) | |
4003 TRACE_EVENT_P3 ("nwctrl_rxlev%u[%u]=%d",c_report+1, rr_report->meas_rep[c_report+1].arfcn,rr_report->meas_rep[c_report+1].rx_lev); | |
4004 #endif /* _SIMULATION_ */ | |
4005 c_report++; | |
4006 } | |
4007 break; | |
4008 case READ_BCCH_RR_NOT_INFORMED: | |
4009 case READ_BCCH_PENDING_RR_NOT_INFORMED: | |
4010 case READ_FB_SB: | |
4011 /* do nothing */ | |
4012 default: | |
4013 break; | |
4014 } | |
4015 }/* not one_of_six*/ | |
4016 } | |
4017 | |
4018 if( (c_report + 1 ) < RR_ALR_MEAS_REPORT_SIZE ) | |
4019 { | |
4020 rr_report->meas_rep[c_report+1].arfcn = NOT_PRESENT_16BIT ; | |
4021 rr_report->meas_rep[c_report+1].rx_lev = NOT_PRESENT_8BIT ; | |
4022 rr_report->meas_rep[c_report+1].bsic = NOT_PRESENT_8BIT ; | |
4023 } | |
4024 } | |
4025 #endif /* ifdef GPRS */ | |
4026 | |
4027 /* | |
4028 +--------------------------------------------------------------------+ | |
4029 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
4030 | STATE : code ROUTINE : nc_store_tav | | |
4031 +--------------------------------------------------------------------+ | |
4032 | |
4033 PURPOSE : Stores timing advance receveived with dedicated mode SI's | |
4034 */ | |
4035 GLOBAL void nc_store_tav(USHORT tav) | |
4036 { | |
4037 alr_data->nc_data.tav = tav; | |
4038 } | |
4039 | |
4040 | |
4041 /* | |
4042 *======================================================================== | |
4043 * Helper Functions | |
4044 *======================================================================== | |
4045 */ | |
4046 | |
4047 | |
4048 /* | |
4049 +--------------------------------------------------------------------+ | |
4050 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
4051 | STATE : code ROUTINE : nc_check_status | | |
4052 +--------------------------------------------------------------------+ | |
4053 | |
4054 PURPOSE : Checks the status of the neighbour cells. | |
4055 */ | |
4056 | |
4057 LOCAL void nc_check_status (UBYTE start_list) | |
4058 { | |
4059 USHORT i; | |
4060 USHORT c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
4061 T_NC * pcell = alr_data->nc_data.cell; | |
4062 | |
4063 for (i = 0; i < c_ba_arfcn; i++, pcell++) | |
4064 { | |
4065 if (pcell->ba_arfcn NEQ alr_data->serving_cell) | |
4066 { | |
4067 switch (GET_STATE(STATE_NC)) | |
4068 { | |
4069 case NC_DEDICATED: | |
4070 switch (pcell->status) | |
4071 { | |
4072 case INACTIVE: | |
4073 break; | |
4074 case IDLE: | |
4075 if (pcell->one_of_twelve) | |
4076 nc_set_status (i, READ_FB_SB); | |
4077 if (start_list EQ CHECK_FOR_CONFIRM) | |
4078 { | |
4079 if (pcell->tim_valid EQ TV_VALID_TIMING_INFO) | |
4080 pcell->tim_valid = TV_APPROX_TIMING_INFO; | |
4081 else if (pcell->tim_valid EQ TV_APPROX_TIMING_INFO) | |
4082 pcell->tim_valid = TV_INVALID_TIMING_INFO; | |
4083 } | |
4084 break; | |
4085 case READ_FB_SB: | |
4086 if (pcell->one_of_twelve EQ FALSE) | |
4087 { | |
4088 nc_set_status (i, IDLE); | |
4089 if (start_list EQ CHECK_FOR_CONFIRM AND pcell->tim_valid EQ TV_APPROX_TIMING_INFO) | |
4090 pcell->tim_valid = TV_INVALID_TIMING_INFO; | |
4091 } | |
4092 break; | |
4093 case FB_SB_SYNC: | |
4094 if (pcell->one_of_twelve EQ FALSE) | |
4095 { | |
4096 nc_set_status (i, IDLE_SYNC); | |
4097 } | |
4098 else | |
4099 { | |
4100 if ( (start_list) AND (alr_data->nc_data.c_sync_intrupted EQ FALSE)) | |
4101 nc_set_status (i, READ_SB); | |
4102 } | |
4103 break; | |
4104 case IDLE_SYNC: | |
4105 if (pcell->one_of_twelve) | |
4106 { | |
4107 if (pcell->c_sync EQ 0) | |
4108 nc_set_status (i, READ_FB_SB); | |
4109 else | |
4110 nc_set_status (i, FB_SB_SYNC); | |
4111 } | |
4112 else | |
4113 { | |
4114 if (pcell->c_sync EQ 0) | |
4115 { | |
4116 nc_set_status (i, IDLE); | |
4117 } | |
4118 } | |
4119 break; | |
4120 case READ_SB: | |
4121 if (pcell->one_of_twelve EQ FALSE) | |
4122 { | |
4123 pcell->tim_valid = TV_APPROX_TIMING_INFO; | |
4124 nc_set_status (i, IDLE); | |
4125 } | |
4126 break; | |
4127 case READ_BCCH_RR_NOT_INFORMED: | |
4128 case READ_BCCH: | |
4129 case READ_SB_BCCH: | |
4130 TRACE_EVENT("unexpected STATE_NC during NC_DEDICATED"); | |
4131 if (pcell->one_of_twelve) | |
4132 nc_set_status (i, READ_FB_SB); | |
4133 else | |
4134 { | |
4135 pcell->tim_valid = TV_APPROX_TIMING_INFO; | |
4136 nc_set_status (i, IDLE); | |
4137 } | |
4138 break; | |
4139 | |
4140 case FB_SB_FAILED: | |
4141 if (pcell->one_of_twelve EQ FALSE) | |
4142 nc_set_status (i, IDLE); | |
4143 else if (pcell->c_sync EQ 0) | |
4144 nc_set_status (i, READ_FB_SB); | |
4145 break; | |
4146 | |
4147 default: | |
4148 break; | |
4149 } | |
4150 break; | |
4151 case NC_IDLE: | |
4152 switch (pcell->status) | |
4153 { | |
4154 case INACTIVE: | |
4155 break; | |
4156 case IDLE: | |
4157 if (pcell->one_of_twelve) | |
4158 nc_set_status (i, READ_FB_SB); | |
4159 if (start_list EQ CHECK_FOR_CONFIRM) | |
4160 { | |
4161 if (pcell->tim_valid EQ TV_VALID_TIMING_INFO) | |
4162 pcell->tim_valid = TV_APPROX_TIMING_INFO; | |
4163 else if (pcell->tim_valid EQ TV_APPROX_TIMING_INFO) | |
4164 pcell->tim_valid = TV_INVALID_TIMING_INFO; | |
4165 } | |
4166 break; | |
4167 case READ_FB_SB: | |
4168 if (pcell->one_of_twelve EQ FALSE) | |
4169 { | |
4170 nc_set_status (i, IDLE); | |
4171 if (start_list EQ CHECK_FOR_CONFIRM AND pcell->tim_valid EQ TV_APPROX_TIMING_INFO) | |
4172 pcell->tim_valid = TV_INVALID_TIMING_INFO; | |
4173 } | |
4174 break; | |
4175 case FB_SB_SYNC: | |
4176 if (pcell->one_of_twelve EQ FALSE) | |
4177 { | |
4178 nc_set_status (i, IDLE_SYNC); | |
4179 } | |
4180 else | |
4181 { | |
4182 if (start_list) | |
4183 nc_set_status (i, READ_SB); | |
4184 if (pcell->one_of_six AND | |
4185 pcell->c_bcch EQ 0) | |
4186 nc_set_status (i, READ_SB_BCCH); | |
4187 } | |
4188 break; | |
4189 case FB_SB_SYNC_RR_NOT_INFORMED: | |
4190 if (pcell->one_of_six EQ FALSE) | |
4191 { | |
4192 if (pcell->one_of_twelve EQ FALSE) | |
4193 { | |
4194 nc_set_status (i, IDLE_SYNC); | |
4195 } | |
4196 else | |
4197 { | |
4198 nc_set_status (i, FB_SB_SYNC); | |
4199 } | |
4200 } | |
4201 break; | |
4202 case FB_SB_FAILED: | |
4203 if (pcell->one_of_twelve EQ FALSE) | |
4204 nc_set_status (i, IDLE); | |
4205 else if (pcell->c_sync EQ 0) | |
4206 nc_set_status (i, READ_FB_SB); | |
4207 break; | |
4208 case IDLE_SYNC: | |
4209 if (pcell->one_of_twelve) | |
4210 { | |
4211 if(pcell->one_of_six) | |
4212 { | |
4213 if (pcell->c_sync EQ 0) | |
4214 nc_set_status (i, READ_FB_SB); | |
4215 else | |
4216 nc_set_status (i, READ_BCCH_RR_NOT_INFORMED); | |
4217 } | |
4218 else | |
4219 { | |
4220 if (pcell->c_sync EQ 0) | |
4221 nc_set_status (i, READ_FB_SB); | |
4222 else | |
4223 nc_set_status (i, FB_SB_SYNC); | |
4224 } | |
4225 } | |
4226 else | |
4227 { | |
4228 if (pcell->c_sync EQ 0) | |
4229 { | |
4230 pcell->tim_valid = TV_APPROX_TIMING_INFO; | |
4231 nc_set_status (i, IDLE); | |
4232 } | |
4233 } | |
4234 break; | |
4235 case READ_SB: | |
4236 if (pcell->one_of_twelve EQ FALSE) | |
4237 { | |
4238 pcell->tim_valid = TV_APPROX_TIMING_INFO; | |
4239 nc_set_status (i, IDLE); | |
4240 } | |
4241 else | |
4242 { | |
4243 if (pcell->c_bcch EQ 0) | |
4244 nc_set_status (i, READ_SB_BCCH); | |
4245 } | |
4246 break; | |
4247 case READ_BCCH: | |
4248 if (pcell->one_of_six EQ FALSE) | |
4249 { | |
4250 if (pcell->one_of_twelve EQ FALSE) | |
4251 { | |
4252 nc_set_status (i, IDLE_SYNC); | |
4253 } | |
4254 else | |
4255 { | |
4256 nc_set_status (i, FB_SB_SYNC); | |
4257 } | |
4258 } | |
4259 break; | |
4260 case READ_BCCH_RR_NOT_INFORMED: | |
4261 if (pcell->one_of_six EQ FALSE) | |
4262 { | |
4263 if (pcell->one_of_twelve EQ FALSE) | |
4264 { | |
4265 nc_set_status (i, IDLE_SYNC); | |
4266 } | |
4267 else | |
4268 { | |
4269 nc_set_status (i, FB_SB_SYNC); | |
4270 } | |
4271 } | |
4272 break; | |
4273 | |
4274 case READ_SB_BCCH: | |
4275 if (pcell->one_of_six EQ FALSE) | |
4276 { | |
4277 if (pcell->one_of_twelve) | |
4278 nc_set_status(i, READ_SB); | |
4279 else | |
4280 { | |
4281 pcell->tim_valid = TV_APPROX_TIMING_INFO; | |
4282 nc_set_status (i, IDLE); | |
4283 } | |
4284 } | |
4285 break; | |
4286 | |
4287 default: | |
4288 break; | |
4289 } | |
4290 break; | |
4291 #ifdef GPRS | |
4292 case NC_PIM_PBCCH: | |
4293 case NC_PTM_PBCCH: /*XXX*/ | |
4294 case NC_CON_EST: /*in case of an updated list in CON_EST */ | |
4295 switch (pcell->status) | |
4296 { | |
4297 case IDLE: | |
4298 if(pcell->one_of_twelve) | |
4299 nc_set_status (i, READ_FB_SB); | |
4300 if (start_list EQ CHECK_FOR_CONFIRM) | |
4301 { | |
4302 if (pcell->tim_valid EQ TV_VALID_TIMING_INFO) | |
4303 pcell->tim_valid = TV_APPROX_TIMING_INFO; | |
4304 else if (pcell->tim_valid EQ TV_APPROX_TIMING_INFO) | |
4305 pcell->tim_valid = TV_INVALID_TIMING_INFO; | |
4306 } | |
4307 break; | |
4308 case FB_SB_SYNC: | |
4309 if(pcell->one_of_twelve EQ FALSE) | |
4310 nc_set_status (i, IDLE_SYNC); | |
4311 else | |
4312 { | |
4313 if (start_list) | |
4314 nc_set_status (i, READ_SB); | |
4315 } | |
4316 break; | |
4317 case FB_SB_FAILED: | |
4318 if(pcell->one_of_twelve EQ FALSE) | |
4319 remove_ncell_and_inform_grr(i); | |
4320 else | |
4321 if(pcell->c_sync EQ 0) | |
4322 nc_set_status (i, READ_FB_SB); | |
4323 break; | |
4324 case READ_FB_SB: | |
4325 break; | |
4326 case READ_SB: | |
4327 if (pcell->one_of_twelve EQ FALSE) | |
4328 { | |
4329 pcell->tim_valid = TV_APPROX_TIMING_INFO; | |
4330 nc_set_status (i, IDLE); | |
4331 } | |
4332 break; | |
4333 case IDLE_SYNC: | |
4334 if(pcell->c_sync EQ 0) | |
4335 remove_ncell_and_inform_grr(i); | |
4336 else | |
4337 { | |
4338 if(pcell->one_of_twelve) | |
4339 nc_set_status (i, FB_SB_SYNC); | |
4340 } | |
4341 break; | |
4342 case READ_BCCH_RR_NOT_INFORMED: | |
4343 case READ_BCCH: | |
4344 case FB_SB_SYNC_RR_NOT_INFORMED: | |
4345 if (pcell->one_of_twelve EQ FALSE) | |
4346 { | |
4347 nc_set_status (i, IDLE_SYNC); | |
4348 } | |
4349 break; | |
4350 default: | |
4351 TRACE_EVENT_P4("wrong state in check_st: i%d a%d 1o6%d st%d", i, | |
4352 pcell->ba_arfcn, | |
4353 pcell->one_of_six, | |
4354 pcell->status); | |
4355 break; | |
4356 } | |
4357 #endif | |
4358 break; | |
4359 default: | |
4360 break; | |
4361 }/*switch state*/ | |
4362 } /*if*/ | |
4363 } /*for*/ | |
4364 } | |
4365 | |
4366 /* | |
4367 +--------------------------------------------------------------------+ | |
4368 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
4369 | STATE : code ROUTINE : nc_build_rr_report_dedi | | |
4370 +--------------------------------------------------------------------+ | |
4371 | |
4372 PURPOSE : Fills a measurement report to RR with neighbour cell | |
4373 information in dedicated mode. | |
4374 In dedicated mode the serving cell may be included. | |
4375 | |
4376 */ | |
4377 LOCAL void nc_build_rr_report_dedi (T_MPH_MEASUREMENT_IND *rr_report) | |
4378 { | |
4379 UBYTE c_report = 0; | |
4380 UBYTE c_ba_list; | |
4381 UBYTE found = TRUE; | |
4382 UBYTE index; | |
4383 UBYTE i; | |
4384 UBYTE in_report[34]; | |
4385 T_NC * pcell1; | |
4386 | |
4387 memset (in_report, 0, 34); | |
4388 | |
4389 for ( i = 0; i < 6 AND found EQ TRUE; i++) | |
4390 { | |
4391 found = FALSE; | |
4392 index = NOT_PRESENT_8BIT; | |
4393 pcell1 = alr_data->nc_data.cell; | |
4394 | |
4395 for (c_ba_list = 0; c_ba_list < alr_data->nc_data.c_ba_arfcn; c_ba_list++, pcell1++) | |
4396 { | |
4397 if (in_report[c_ba_list] EQ FALSE AND pcell1->ba_status EQ IN_BA) | |
4398 { | |
4399 switch (pcell1->status) | |
4400 { | |
4401 case FB_SB_SYNC: | |
4402 case READ_SB: | |
4403 case READ_SB_PENDING: | |
4404 if (nc_ncell_in_plmn_permitted(pcell1->bsic)) | |
4405 { | |
4406 if ((pcell1->ba_arfcn NEQ alr_data->serving_cell AND | |
4407 pcell1->one_of_six) OR | |
4408 (pcell1->ba_arfcn EQ alr_data->serving_cell AND | |
4409 alr_data->nc_data.sc_included)) | |
4410 { | |
4411 if (index EQ NOT_PRESENT_8BIT) | |
4412 index = c_ba_list; | |
4413 else | |
4414 { | |
4415 if (pcell1->rxlev_average > | |
4416 alr_data->nc_data.cell[index].rxlev_average) | |
4417 index = c_ba_list; | |
4418 } | |
4419 } | |
4420 } | |
4421 break; | |
4422 } | |
4423 } | |
4424 } | |
4425 | |
4426 if (index NEQ NOT_PRESENT_8BIT) | |
4427 { | |
4428 T_NC* pcell = &alr_data->nc_data.cell[index]; | |
4429 found = TRUE; | |
4430 in_report[index] = TRUE; | |
4431 | |
4432 rr_report->ncells.arfcn[c_report] = pcell->ba_arfcn; | |
4433 | |
4434 if ((UBYTE)pcell->rxlev_average > 63) | |
4435 rr_report->ncells.rx_lev[c_report] = 63; | |
4436 else | |
4437 rr_report->ncells.rx_lev[c_report] = (UBYTE)pcell->rxlev_average; | |
4438 | |
4439 rr_report->ncells.bsic[c_report] = pcell->bsic; | |
4440 rr_report->ncells.time_alignmt[c_report] = pcell->time_align; | |
4441 rr_report->ncells.frame_offset[c_report++] = pcell->frame_offset; | |
4442 } | |
4443 | |
4444 } /*for (up to 6 ncells)*/ | |
4445 /* | |
4446 * insert serving cell values | |
4447 */ | |
4448 nc_fill_report_sc_dedi (rr_report, c_report); | |
4449 } | |
4450 | |
4451 /* | |
4452 +--------------------------------------------------------------------+ | |
4453 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
4454 | STATE : code ROUTINE : nc_rank_ncells | | |
4455 +--------------------------------------------------------------------+ | |
4456 | |
4457 PURPOSE : Searches for the six and additionally the twelve strongest neighbourcells. | |
4458 | |
4459 */ | |
4460 LOCAL void nc_rank_ncells (void) | |
4461 { | |
4462 USHORT c_found, i; | |
4463 USHORT last = (sizeof alr_data->nc_data.cell / | |
4464 sizeof alr_data->nc_data.cell[0]); | |
4465 UBYTE old_1of6[ sizeof alr_data->nc_data.cell / | |
4466 sizeof alr_data->nc_data.cell[0] ]; | |
4467 UBYTE num_1of6, hyst_rxlev, nc_conf_active = FALSE; | |
4468 | |
4469 num_1of6 = 0; | |
4470 hyst_rxlev = 63; | |
4471 alr_data->nc_data.new_strong_cell_detect = FALSE; | |
4472 | |
4473 for ( i = 0; i < last; i++ ) | |
4474 { | |
4475 old_1of6[i] = alr_data->nc_data.cell[i].one_of_six; | |
4476 alr_data->nc_data.cell[i].new_strong_cell = FALSE; | |
4477 | |
4478 if(old_1of6[i]) | |
4479 { | |
4480 num_1of6++; | |
4481 | |
4482 if(alr_data->nc_data.cell[i].rxlev_average < hyst_rxlev) | |
4483 hyst_rxlev = alr_data->nc_data.cell[i].rxlev_average; | |
4484 } | |
4485 | |
4486 alr_data->nc_data.cell[i].one_of_six = FALSE; | |
4487 | |
4488 } | |
4489 | |
4490 if(num_1of6 < MAX_RR_NCELL_CNT) | |
4491 hyst_rxlev = 0; | |
4492 | |
4493 if((GET_STATE(STATE_NC_PROC) EQ NC_CONFIRM) AND | |
4494 (GET_STATE(STATE_NC) EQ NC_DEDICATED) AND | |
4495 (!alr_data->nc_data.eotd_avail)) | |
4496 nc_conf_active = TRUE; | |
4497 | |
4498 c_found = 0; | |
4499 | |
4500 if ((std EQ STD_DUAL) OR (std EQ STD_DUAL_EGSM) OR (std EQ STD_DUAL_US)) | |
4501 { | |
4502 switch (alr_data->nc_data.multiband) | |
4503 { | |
4504 case MULTI_BAND_0: | |
4505 /* Find 6 cells from any band */ | |
4506 nc_find_cells (&c_found, MAX_RR_NCELL_CNT, NO_BAND_LIMITATION, ALR_RXLEV_AVERAGE_MIN); | |
4507 break; | |
4508 case MULTI_BAND_1: | |
4509 /* Find 1 cell from bands other than Serving cell band */ | |
4510 nc_find_cells (&c_found, 1, EXCLUDE_SC_BAND, ALR_RXLEV_AVERAGE_LWR_THR); | |
4511 | |
4512 /* Find 5 cells from the Serving cell band */ | |
4513 nc_find_cells (&c_found, MAX_RR_NCELL_CNT-1, ONLY_SC_BAND, ALR_RXLEV_AVERAGE_LWR_THR); | |
4514 | |
4515 /* If number of found cells are less than six, find the remaining from any band. | |
4516 * Also relax the Rxlev criteria | |
4517 */ | |
4518 nc_find_cells (&c_found, (USHORT)(MAX_RR_NCELL_CNT - c_found), NO_BAND_LIMITATION, | |
4519 ALR_RXLEV_AVERAGE_MIN); | |
4520 break; | |
4521 case MULTI_BAND_2: | |
4522 /* Find 2 cell from bands other than Serving cell band */ | |
4523 nc_find_cells (&c_found, 2, EXCLUDE_SC_BAND, ALR_RXLEV_AVERAGE_LWR_THR); | |
4524 | |
4525 /* Find 4 cells from the Serving cell band */ | |
4526 nc_find_cells (&c_found, MAX_RR_NCELL_CNT-2, ONLY_SC_BAND, ALR_RXLEV_AVERAGE_LWR_THR); | |
4527 | |
4528 /* If number of found cells are less than six, find the remaining from any band. | |
4529 * Also relax the Rxlev criteria | |
4530 */ | |
4531 nc_find_cells (&c_found, (USHORT)(MAX_RR_NCELL_CNT - c_found), NO_BAND_LIMITATION, | |
4532 ALR_RXLEV_AVERAGE_MIN); | |
4533 break; | |
4534 case MULTI_BAND_3: | |
4535 /* Find 3 cell from bands other than Serving cell band */ | |
4536 nc_find_cells (&c_found, 3, EXCLUDE_SC_BAND, ALR_RXLEV_AVERAGE_LWR_THR); | |
4537 | |
4538 /* Find 3 cells from the Serving cell band */ | |
4539 nc_find_cells (&c_found, MAX_RR_NCELL_CNT-3, ONLY_SC_BAND, ALR_RXLEV_AVERAGE_LWR_THR); | |
4540 | |
4541 /* If number of found cells are less than six, find the remaining from any band. | |
4542 * Also relax the Rxlev criteria | |
4543 */ | |
4544 nc_find_cells (&c_found, (USHORT)(MAX_RR_NCELL_CNT - c_found), NO_BAND_LIMITATION, | |
4545 ALR_RXLEV_AVERAGE_MIN); | |
4546 break; | |
4547 } | |
4548 } | |
4549 else | |
4550 nc_find_cells (&c_found, MAX_RR_NCELL_CNT, NO_BAND_LIMITATION, ALR_RXLEV_AVERAGE_MIN); | |
4551 | |
4552 for ( i = 0; i < last; i++ ) | |
4553 { | |
4554 if (alr_data->nc_data.cell[i].one_of_six AND !old_1of6[i] AND | |
4555 GET_STATE(STATE_NC) NEQ NC_DEDICATED) | |
4556 { /* the cell becomes one of six */ | |
4557 switch (alr_data->nc_data.cell[i].status) | |
4558 { | |
4559 case FB_SB_SYNC: | |
4560 /* the cell is treaded as synchronized, perform BCCH reading ASAP */ | |
4561 nc_set_status(i, READ_BCCH_RR_NOT_INFORMED); | |
4562 break; | |
4563 case READ_SB: | |
4564 case IDLE_SYNC: | |
4565 case FB_SB_FAILED: | |
4566 /* the cell shall be synchronized ASAP, then BCCH info is to send to RR */ | |
4567 nc_set_status(i, READ_FB_SB); | |
4568 break; | |
4569 case READ_SB_PENDING: | |
4570 /* after receipt of sync ind the BCCH is to read and to send to RR */ | |
4571 nc_set_status(i, READ_FB_SB_PENDING); | |
4572 break; | |
4573 default: | |
4574 break; | |
4575 } | |
4576 } | |
4577 if (old_1of6[i] AND | |
4578 !alr_data->nc_data.cell[i].one_of_six AND | |
4579 alr_data->nc_data.cell[i].status EQ FB_SB_SYNC) | |
4580 alr_data->nc_data.cell[i].c_attempt = 0; | |
4581 | |
4582 /* Check the new strong cell criteria when confirmation is active */ | |
4583 if(nc_conf_active) | |
4584 { | |
4585 nc_check_new_strong_cell(i, old_1of6[i], hyst_rxlev); | |
4586 | |
4587 } | |
4588 } | |
4589 | |
4590 nc_find_list_cells(); | |
4591 | |
4592 TRACE_EVENT_P1("New strong cell detect:%d", | |
4593 alr_data->nc_data.new_strong_cell_detect); | |
4594 } | |
4595 | |
4596 /* | |
4597 +--------------------------------------------------------------------+ | |
4598 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
4599 | STATE : code ROUTINE : nc_find_cells | | |
4600 +--------------------------------------------------------------------+ | |
4601 | |
4602 PURPOSE : Searches for the six strongest neighbourcells, | |
4603 using multiband parameter if needed. | |
4604 Called only in case of the value of 'std' is set to | |
4605 STD_DUAL, STD_DUAL_EGSM or STD_DUAL_US. | |
4606 (And therefore only for the combination of | |
4607 GSM900/E-GSM/DCS1800 or GSM850/PCS1900.) | |
4608 | |
4609 */ | |
4610 LOCAL void nc_find_cells (USHORT *c_found, USHORT max, UBYTE limitation, | |
4611 UBYTE min_rxlev) | |
4612 { | |
4613 int i, j; | |
4614 BOOL limit; | |
4615 int index; | |
4616 | |
4617 | |
4618 USHORT c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
4619 T_NC* pcell; | |
4620 UBYTE band_nc; | |
4621 UBYTE band_sc = get_band (alr_data->serving_cell); | |
4622 | |
4623 if (*c_found >= MAX_RR_NCELL_CNT) | |
4624 return; | |
4625 | |
4626 if (band_sc EQ BAND_E_GSM) | |
4627 band_sc = BAND_GSM_900; /* equal treatment of E-GSM and GSM900 */ | |
4628 | |
4629 for (j = 0, index = 0; (j < max) AND (index NEQ NOT_PRESENT_16BIT); j++) | |
4630 { | |
4631 index = NOT_PRESENT_16BIT; | |
4632 | |
4633 for (i = 0; i < c_ba_arfcn; i++) | |
4634 { | |
4635 pcell = &alr_data->nc_data.cell[i]; | |
4636 /* | |
4637 * The six strongest neighbour cells do not include cells | |
4638 * currently not belonging to BA list | |
4639 */ | |
4640 if (pcell->ba_status NEQ IN_BA) | |
4641 continue; | |
4642 | |
4643 switch (pcell->status) | |
4644 { | |
4645 case INACTIVE: | |
4646 case EXCLUDED: | |
4647 /* | |
4648 * The six strongest neighbour cells do not include failed ncells. | |
4649 */ | |
4650 break; | |
4651 default: | |
4652 if (pcell->ba_arfcn NEQ alr_data->serving_cell AND | |
4653 pcell->one_of_six EQ FALSE AND | |
4654 pcell->rxlev_average > min_rxlev) /* > -106 dBm */ | |
4655 { | |
4656 band_nc = get_band (pcell->ba_arfcn); | |
4657 if (band_nc EQ BAND_E_GSM) | |
4658 band_nc = BAND_GSM_900; /* equal treatment of E-GSM and GSM900 */ | |
4659 | |
4660 switch (limitation) | |
4661 { | |
4662 default: | |
4663 case NO_BAND_LIMITATION: | |
4664 limit = FALSE; | |
4665 break; | |
4666 case EXCLUDE_SC_BAND: | |
4667 limit = (band_sc EQ band_nc); | |
4668 break; | |
4669 case ONLY_SC_BAND: | |
4670 limit = (band_sc NEQ band_nc); | |
4671 break; | |
4672 } | |
4673 | |
4674 if (!limit) | |
4675 { | |
4676 if (index EQ NOT_PRESENT_16BIT) | |
4677 { | |
4678 index = i; | |
4679 } | |
4680 else | |
4681 { | |
4682 if (pcell->rxlev_average > | |
4683 alr_data->nc_data.cell[index].rxlev_average) | |
4684 { | |
4685 index = i; | |
4686 } | |
4687 } | |
4688 } | |
4689 } | |
4690 break; | |
4691 } /*ncell status*/ | |
4692 } | |
4693 | |
4694 if (index NEQ NOT_PRESENT_16BIT) | |
4695 { | |
4696 alr_data->nc_data.cell[index].one_of_six = TRUE; | |
4697 (*c_found)++; | |
4698 } | |
4699 } | |
4700 } | |
4701 | |
4702 | |
4703 /* | |
4704 +--------------------------------------------------------------------+ | |
4705 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
4706 | STATE : code ROUTINE : nc_find_list_cells | | |
4707 +--------------------------------------------------------------------+ | |
4708 | |
4709 PURPOSE : Searches for the 6 or 12 strongest neighbourcells | |
4710 | |
4711 */ | |
4712 LOCAL void nc_find_list_cells (void) | |
4713 { | |
4714 USHORT i, j; | |
4715 UBYTE found, c_found = 0; | |
4716 USHORT index; | |
4717 USHORT c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
4718 T_NC* pcell; | |
4719 | |
4720 for (i = 0, pcell = &alr_data->nc_data.cell[0]; i < c_ba_arfcn; i++, pcell++ ) | |
4721 { | |
4722 if ((pcell->one_of_twelve = pcell->one_of_six) EQ TRUE) | |
4723 c_found++; | |
4724 } | |
4725 /* | |
4726 * The flag one_of_six controls the property to include a neighbour cell | |
4727 * into the measurement report, | |
4728 * the flag one_of_twelve controls whether the ncell is included into the | |
4729 * synchronisation confirmation process. In case of EOTD up to 12 cell are | |
4730 * included, in case of non-EOTD 6 cells are sufficient. | |
4731 */ | |
4732 if (!alr_data->nc_data.eotd_avail) | |
4733 return; | |
4734 | |
4735 for (j = c_found, found = TRUE; (j < MAX_L1_SYNC_CNT) AND (found EQ TRUE); j++) | |
4736 { | |
4737 index = NOT_PRESENT_16BIT; | |
4738 found = FALSE; | |
4739 | |
4740 for (i = 0; i < c_ba_arfcn; i++) | |
4741 { | |
4742 pcell = &alr_data->nc_data.cell[i]; | |
4743 /* | |
4744 * The 12 strongest neighbour cells do not include ncells currently not belonging to BA list. | |
4745 */ | |
4746 if (pcell->ba_status NEQ IN_BA) | |
4747 continue; | |
4748 | |
4749 switch (pcell->status) | |
4750 { | |
4751 case INACTIVE: | |
4752 case EXCLUDED: | |
4753 /* | |
4754 * The 12 strongest neighbour cells do not include failed ncells. | |
4755 */ | |
4756 break; | |
4757 default: | |
4758 if (pcell->ba_arfcn NEQ alr_data->serving_cell AND | |
4759 pcell->one_of_twelve EQ FALSE AND | |
4760 pcell->rxlev_average > ALR_RXLEV_AVERAGE_MIN) /* > -110 dBm */ | |
4761 { | |
4762 if (index EQ NOT_PRESENT_16BIT) | |
4763 { | |
4764 index = i; | |
4765 found = TRUE; | |
4766 } | |
4767 else | |
4768 { | |
4769 if (pcell->rxlev_average > | |
4770 alr_data->nc_data.cell[index].rxlev_average) | |
4771 { | |
4772 index = i; | |
4773 found = TRUE; | |
4774 } | |
4775 } | |
4776 } | |
4777 break; | |
4778 } /*ncell status*/ | |
4779 } | |
4780 | |
4781 if (found AND (index NEQ NOT_PRESENT_16BIT)) | |
4782 alr_data->nc_data.cell[index].one_of_twelve = TRUE; | |
4783 } | |
4784 } | |
4785 | |
4786 /* | |
4787 +--------------------------------------------------------------------+ | |
4788 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
4789 | STATE : code ROUTINE : nc_store_rxlev | | |
4790 +--------------------------------------------------------------------+ | |
4791 | |
4792 PURPOSE : Stores the fieldstrength values of the neighbour cells. | |
4793 Calculates the average of the fieldstrength after five | |
4794 samples. | |
4795 | |
4796 */ | |
4797 | |
4798 | |
4799 LOCAL void nc_store_rxlev (T_MPHC_RXLEV_PERIODIC_IND *report) | |
4800 { | |
4801 USHORT i; | |
4802 USHORT index; | |
4803 UBYTE diff; | |
4804 int max_attempt; | |
4805 T_NC* pcell; | |
4806 | |
4807 ALR_TRACE_NC("store rxlev"); | |
4808 /* | |
4809 * Patch for 20.5 | |
4810 * The fieldstrength average for a new channel | |
4811 * increases too slow if more then eight channels | |
4812 * are in the neighbourcell list, because layer 1 | |
4813 * sends not raw data every paging period. | |
4814 */ | |
4815 if (test_house AND | |
4816 alr_data->nc_data.c_ba_arfcn > 8) | |
4817 max_attempt = 3; | |
4818 else | |
4819 max_attempt = 5; | |
4820 | |
4821 if (alr_data->nc_data.tim_state NEQ NC_TIM_STOPPED) | |
4822 { | |
4823 /* Decrement the 10sec timer counter variable by BS_PA_MFRMS */ | |
4824 alr_data->nc_data.c_ncsync_tim = (UBYTE)(alr_data->nc_data.c_ncsync_tim - alr_data->bs_pa_mfrms - 2); | |
4825 | |
4826 if ((signed char)(alr_data->nc_data.c_ncsync_tim) < 0) | |
4827 alr_data->nc_data.c_ncsync_tim = 0; | |
4828 | |
4829 if( alr_data->nc_data.c_ncsync_tim EQ 0 ) | |
4830 nc_ncsync_tim_expiry(); /* 10 sec have elapsed. Perform all requisite tasks */ | |
4831 } | |
4832 | |
4833 /* serving cell rxlev storage */ | |
4834 index = nc_get_index (alr_data->serving_cell); | |
4835 pcell = &alr_data->nc_data.cell[index]; | |
4836 | |
4837 if ( (signed char)report->s_rxlev < 0) | |
4838 report->s_rxlev = 0; | |
4839 | |
4840 if (pcell->c_rxlev EQ NOT_PRESENT_8BIT) | |
4841 { | |
4842 pcell->c_rxlev = 0; | |
4843 memset (pcell->rxlev, report->s_rxlev, 5); | |
4844 } | |
4845 else | |
4846 { | |
4847 pcell->rxlev[pcell->c_rxlev++] = report->s_rxlev; | |
4848 } | |
4849 pcell->c_rxlev %= 5; | |
4850 | |
4851 /* | |
4852 * store the results seperately for averaging when NC=1 or NC=2 | |
4853 */ | |
4854 #ifdef GPRS | |
4855 if(alr_data->nwctrl_meas_active) | |
4856 { | |
4857 pcell->nc_rxlev += report->s_rxlev; | |
4858 pcell->c_nc_rxlev++; | |
4859 } | |
4860 #endif | |
4861 | |
4862 /* | |
4863 * ncell rxlev storage | |
4864 */ | |
4865 for (i = 0; i < report->nbr_of_carriers; i++) | |
4866 { | |
4867 /* | |
4868 * The RX level from TI is signed in the SAP | |
4869 * we define it as unsigned | |
4870 */ | |
4871 if ((signed char) (report->result[i].rxlev) < 0) | |
4872 { | |
4873 report->result[i].rxlev = 0; | |
4874 } | |
4875 | |
4876 index = nc_get_index (ARFCN_TO_G23(report->result[i].radio_freq)); | |
4877 if (index NEQ NOT_PRESENT_16BIT AND | |
4878 index NEQ LAST_BSIC_REQ AND | |
4879 ARFCN_TO_G23(report->result[i].radio_freq) NEQ alr_data->serving_cell) | |
4880 { | |
4881 int temp; | |
4882 UBYTE rxlev = report->result[i].rxlev; | |
4883 pcell = &alr_data->nc_data.cell[index]; | |
4884 | |
4885 if (pcell->c_rxlev EQ NOT_PRESENT_8BIT) | |
4886 { | |
4887 /* | |
4888 * if it is a new cell, build an average from the first value | |
4889 * to speed up fb sb read | |
4890 */ | |
4891 pcell->rxlev[0] = rxlev; | |
4892 pcell->rxlev[1] = rxlev; | |
4893 pcell->rxlev[2] = rxlev; | |
4894 pcell->rxlev[3] = rxlev; | |
4895 pcell->rxlev[4] = rxlev; | |
4896 pcell->c_rxlev = 0; | |
4897 } | |
4898 else | |
4899 { | |
4900 pcell->rxlev[pcell->c_rxlev++] = rxlev; | |
4901 if (pcell->c_rxlev >= (UBYTE)max_attempt) | |
4902 pcell->c_rxlev = 0; | |
4903 } | |
4904 temp = pcell->rxlev[0] + | |
4905 pcell->rxlev[1] + | |
4906 pcell->rxlev[2]; | |
4907 | |
4908 if (max_attempt EQ 5) | |
4909 { | |
4910 temp += pcell->rxlev[3] + | |
4911 pcell->rxlev[4]; | |
4912 } | |
4913 | |
4914 pcell->rxlev_average = (UBYTE)(temp / max_attempt); | |
4915 /* | |
4916 * store the results seperately for averaging when NC=1 or NC=2 | |
4917 */ | |
4918 #ifdef GPRS | |
4919 if(alr_data->nwctrl_meas_active) | |
4920 { | |
4921 pcell->nc_rxlev += rxlev; | |
4922 pcell->c_nc_rxlev++; | |
4923 } | |
4924 #endif | |
4925 | |
4926 | |
4927 #if defined(TRACING) | |
4928 TRACE_EVENT_P4("NC%u[%d] rx=%d av=%d", | |
4929 index, | |
4930 pcell->ba_arfcn EQ NOT_PRESENT_16BIT ? -1 : pcell->ba_arfcn&ARFCN_MASK, | |
4931 report->result[i].rxlev, pcell->rxlev_average); | |
4932 #endif /* TRACING */ | |
4933 | |
4934 switch (pcell->status) | |
4935 { | |
4936 case INACTIVE: | |
4937 nc_set_status (index, IDLE); | |
4938 break; | |
4939 case EXCLUDED: | |
4940 diff = (UBYTE)(pcell->rxlev_average - pcell->last_rxlev); | |
4941 if (diff < 128 AND diff >= 6) | |
4942 { | |
4943 /* | |
4944 * result is positive and more than 6 dBm | |
4945 */ | |
4946 nc_set_status (index, IDLE); | |
4947 } | |
4948 break; | |
4949 default: | |
4950 break; | |
4951 } | |
4952 } | |
4953 } | |
4954 } | |
4955 | |
4956 /* | |
4957 +--------------------------------------------------------------------+ | |
4958 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
4959 | STATE : code ROUTINE : nc_find_serving_cell_entry | | |
4960 +--------------------------------------------------------------------+ | |
4961 | |
4962 PURPOSE : Finds an entry for serving cell | |
4963 in the BCCH allocation list. | |
4964 | |
4965 */ | |
4966 LOCAL T_NC* nc_find_serving_cell_entry (USHORT serving_cell) | |
4967 { | |
4968 T_NC* pcell; | |
4969 USHORT i; | |
4970 UBYTE last_alr = alr_data->nc_data.c_ba_arfcn; | |
4971 | |
4972 if (last_alr < LAST_BSIC_REQ) | |
4973 { | |
4974 pcell = &alr_data->nc_data.cell[last_alr]; | |
4975 #if defined(TRACING) | |
4976 TRACE_EVENT_P2 ("NC%u[%u] add", last_alr, serving_cell); | |
4977 #endif /* TRACING */ | |
4978 alr_data->nc_data.c_ba_arfcn = last_alr+1; /* store new last index */ | |
4979 i = last_alr; | |
4980 ALR_TRACE_ALL_NC (); | |
4981 } | |
4982 else | |
4983 { /* ALR list is full, search for an entry not in state IN_BA */ | |
4984 for (i = 0, pcell = alr_data->nc_data.cell; i < LAST_BSIC_REQ; i++, pcell++) | |
4985 { | |
4986 if (pcell->ba_status NEQ IN_BA) | |
4987 break; | |
4988 } /* for (i...) */ | |
4989 if (i >= LAST_BSIC_REQ) | |
4990 { /* | |
4991 * no entry found | |
4992 * reuse the last entry to make sure there is a place for serving cell | |
4993 */ | |
4994 i = LAST_BSIC_REQ-1; | |
4995 pcell = &alr_data->nc_data.cell[i]; | |
4996 } | |
4997 | |
4998 nc_stop_if_active(i); | |
4999 #if defined(TRACING) | |
5000 TRACE_EVENT_P2 ("NC%u[%u] replace", i, serving_cell); | |
5001 #endif /* TRACING */ | |
5002 } | |
5003 nc_set_status (i, FB_SB_SYNC); | |
5004 pcell->ba_status = IN_BA; /* even if not in the BA but other functions need it */ | |
5005 pcell->ba_arfcn = serving_cell; | |
5006 return pcell; | |
5007 } | |
5008 | |
5009 /* | |
5010 +--------------------------------------------------------------------+ | |
5011 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5012 | STATE : code ROUTINE : nc_add_serving_cell_ba_list| | |
5013 +--------------------------------------------------------------------+ | |
5014 | |
5015 PURPOSE : Adds serving cell to neighbourcell list. | |
5016 This function is called just before nc_start_reselect | |
5017 and not after the MPHC_NEW_SCELL_CNF. | |
5018 | |
5019 */ | |
5020 LOCAL void nc_add_serving_cell_ba_list (USHORT serving_cell) | |
5021 { | |
5022 USHORT index = nc_get_index (serving_cell); | |
5023 T_NC* pcell; | |
5024 | |
5025 /* | |
5026 * Add serving cell if not included | |
5027 */ | |
5028 switch (index) | |
5029 { | |
5030 case NOT_PRESENT_16BIT: | |
5031 case LAST_BSIC_REQ: | |
5032 /* serving cell isn´t inside the BA list */ | |
5033 pcell = nc_find_serving_cell_entry(serving_cell); | |
5034 pcell->bsic = alr_data->nc_data.cr_cell.bsic; | |
5035 pcell->frame_offset = alr_data->nc_data.cr_cell.frame_offset; | |
5036 pcell->time_align = alr_data->nc_data.cr_cell.time_align; | |
5037 break; | |
5038 | |
5039 default: | |
5040 if (index < ELEMENTS(alr_data->nc_data.cell)) | |
5041 { | |
5042 /* serving cell is already included in ba list */ | |
5043 /* For GPRS the scell may not be in FB_SB_SYNC so put it there */ | |
5044 pcell = &alr_data->nc_data.cell[index]; | |
5045 | |
5046 /* Check whether the cell has valid sync info */ | |
5047 if (pcell->bsic NEQ NOT_PRESENT_8BIT) | |
5048 { | |
5049 nc_set_status(index, FB_SB_SYNC); | |
5050 alr_data->nc_data.cell[index].one_of_six = FALSE; | |
5051 alr_data->nc_data.cell[index].ba_status = IN_BA; /* even if not in the BA but other functions need it */ | |
5052 } | |
5053 } | |
5054 break; | |
5055 } | |
5056 } | |
5057 | |
5058 /* | |
5059 +--------------------------------------------------------------------+ | |
5060 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5061 | STATE : code ROUTINE : nc_update_ba_list | | |
5062 +--------------------------------------------------------------------+ | |
5063 | |
5064 PURPOSE : Updates the BCCH allocation list. | |
5065 | |
5066 */ | |
5067 | |
5068 LOCAL void nc_update_ba_list (USHORT serving_cell, T_MPH_NEIGHBOURCELL_REQ *ncell_list) | |
5069 { | |
5070 USHORT n_rr; /* index of RR neighbor cell list */ | |
5071 USHORT n_alr; /* index of ALR neighbor cell list */ | |
5072 UBYTE last_alr; /* last index of ALR neighbor cell list */ | |
5073 USHORT arfcn; | |
5074 T_NC* pcell; | |
5075 | |
5076 alr_data->nc_data.multiband = ncell_list->multi_band; | |
5077 | |
5078 /* | |
5079 * remove or mark all channels which are not longer member of the | |
5080 * neighbour cell list. | |
5081 */ | |
5082 last_alr = alr_data->nc_data.c_ba_arfcn; /* current last index */ | |
5083 for (n_alr = 0; n_alr < last_alr; n_alr++) | |
5084 { | |
5085 pcell = &alr_data->nc_data.cell[n_alr]; | |
5086 arfcn = pcell->ba_arfcn; | |
5087 if (!nc_is_in_ncell_list (arfcn, ncell_list) AND | |
5088 (arfcn NEQ serving_cell)) | |
5089 { | |
5090 if (GET_STATE(STATE_NC) EQ NC_IDLE) | |
5091 { /* the RR neighbor cell list is complete */ | |
5092 last_alr = nc_remove_channel_from_ba_list (n_alr); | |
5093 #if defined(TRACING) | |
5094 TRACE_EVENT_P2 ("NC%u[%u] remove", n_alr, arfcn); | |
5095 #endif /* TRACING */ | |
5096 n_alr--; | |
5097 ALR_TRACE_ALL_NC (); | |
5098 } | |
5099 else | |
5100 { /* the RR neighbor cell list may be incomplete so mark only the entry */ | |
5101 if (pcell->ba_status EQ IN_BA) | |
5102 { | |
5103 pcell->ba_status = NOT_IN_BA_SHORT; | |
5104 | |
5105 #if defined(TRACING) | |
5106 TRACE_EVENT_P2 ("NC%u[%u] -> NOT_IN_BA_SHORT", n_alr, arfcn); | |
5107 #endif /* TRACING */ | |
5108 } | |
5109 } | |
5110 } | |
5111 } | |
5112 | |
5113 /* | |
5114 * add all new channels. | |
5115 */ | |
5116 for (n_rr = 0; n_rr < MAX_NEIGHBOURCELLS; n_rr++) | |
5117 { | |
5118 arfcn = ncell_list->arfcn[n_rr]; | |
5119 if (arfcn EQ NOT_PRESENT_16BIT) | |
5120 break; /* no more entries in the RR ncell_list */ | |
5121 | |
5122 n_alr = nc_get_index (arfcn); | |
5123 | |
5124 if (arfcn NEQ serving_cell) | |
5125 { | |
5126 if (n_alr EQ NOT_PRESENT_16BIT OR n_alr EQ LAST_BSIC_REQ) | |
5127 { | |
5128 if (last_alr < BA_LIST_SIZE) | |
5129 { | |
5130 pcell = &alr_data->nc_data.cell[last_alr]; | |
5131 | |
5132 #if defined(TRACING) | |
5133 TRACE_EVENT_P2 ("NC%u[%u] add", last_alr, arfcn); | |
5134 #endif /* TRACING */ | |
5135 pcell->ba_arfcn = arfcn; | |
5136 nc_set_status (last_alr, INACTIVE); | |
5137 pcell->ba_status = IN_BA; | |
5138 last_alr++; /* increment last index */ | |
5139 } | |
5140 else | |
5141 { /* ALR list is full, search for an entry not in state IN_BA */ | |
5142 USHORT i; | |
5143 for (i = 0, pcell = alr_data->nc_data.cell; i < BA_LIST_SIZE; i++, pcell++) | |
5144 { | |
5145 if (pcell->ba_status NEQ IN_BA AND pcell->ba_arfcn NEQ serving_cell) | |
5146 { | |
5147 nc_stop_if_active(i); | |
5148 #if defined(TRACING) | |
5149 TRACE_EVENT_P2 ("NC%u[%u] replace", i, arfcn); | |
5150 #endif /* TRACING */ | |
5151 pcell->ba_arfcn = arfcn; | |
5152 nc_set_status (i, INACTIVE); | |
5153 pcell->ba_status = IN_BA; | |
5154 break; | |
5155 } | |
5156 } /* for (i...) */ | |
5157 } | |
5158 } | |
5159 else | |
5160 { | |
5161 #if defined(TRACING) | |
5162 if (alr_data->nc_data.cell[n_alr].ba_status NEQ IN_BA) | |
5163 TRACE_EVENT_P2 ("NC%u[%u] -> IN_BA", n_alr, arfcn); | |
5164 #endif | |
5165 alr_data->nc_data.cell[n_alr].ba_status = IN_BA; | |
5166 } | |
5167 } /* if (arfcn NEQ serving_cell) */ | |
5168 } | |
5169 | |
5170 /* | |
5171 * store whether SC was included into the BA list by the net | |
5172 */ | |
5173 if (nc_is_in_ncell_list (serving_cell, ncell_list)) | |
5174 { | |
5175 alr_data->nc_data.sc_included = TRUE; | |
5176 } | |
5177 else | |
5178 { | |
5179 alr_data->nc_data.sc_included = FALSE; | |
5180 } | |
5181 alr_data->nc_data.c_ba_arfcn = last_alr; /* store new last index */ | |
5182 | |
5183 /* | |
5184 * Add serving cell if not included | |
5185 */ | |
5186 n_alr = nc_get_index (serving_cell); | |
5187 switch (n_alr) | |
5188 { | |
5189 case NOT_PRESENT_16BIT: | |
5190 case LAST_BSIC_REQ: | |
5191 pcell = nc_find_serving_cell_entry(serving_cell); | |
5192 | |
5193 pcell->bsic = alr_data->bsic; | |
5194 pcell->frame_offset = 0; | |
5195 pcell->time_align = 0; | |
5196 break; | |
5197 | |
5198 default: | |
5199 /* serving cell is already included */ | |
5200 pcell = &alr_data->nc_data.cell[n_alr]; | |
5201 pcell->bsic = alr_data->bsic; | |
5202 pcell->frame_offset = 0; | |
5203 pcell->time_align = 0; | |
5204 pcell->ba_status = IN_BA; /* even if not in the BA but other functions need it */ | |
5205 nc_set_status (n_alr, FB_SB_SYNC); /* make sure the SC is reported in measurement reports if included into BA list */ | |
5206 break; | |
5207 } | |
5208 | |
5209 /* | |
5210 * reset status of neighbour cells with failed | |
5211 * synchronisation attempts. | |
5212 */ | |
5213 for (n_alr = 0; n_alr < last_alr; n_alr++) | |
5214 { | |
5215 switch (alr_data->nc_data.cell[n_alr].status) | |
5216 { | |
5217 case FB_SB_FAILED: | |
5218 case EXCLUDED: | |
5219 alr_data->nc_data.cell[n_alr].tim_valid = TV_INVALID_TIMING_INFO; | |
5220 nc_set_status (n_alr, IDLE); | |
5221 break; | |
5222 } | |
5223 } | |
5224 | |
5225 /* | |
5226 * Reorder the entries. The goal is that the propably strongest neigbour cells | |
5227 * are measured in the first measurement period of a subsequent | |
5228 * MPHC_RXLEV_PERIODIC_REQ/IND. The appropriate arfcn's are the first ones in | |
5229 * ncell_list->arfcn | |
5230 */ | |
5231 if (last_alr > 8) | |
5232 { | |
5233 T_NC temp, *prr, *palr; | |
5234 | |
5235 for (n_rr = 0; n_rr < 8 && ncell_list->arfcn[n_rr] NEQ NOT_PRESENT_16BIT; n_rr++) | |
5236 { | |
5237 n_alr = nc_get_index (ncell_list->arfcn[n_rr]); | |
5238 if (n_rr NEQ n_alr) | |
5239 { | |
5240 palr = &(alr_data->nc_data.cell[n_alr]); | |
5241 prr = &(alr_data->nc_data.cell[n_rr]); | |
5242 memcpy(&temp, palr, sizeof(T_NC)); | |
5243 memcpy(palr, prr, sizeof(T_NC)); | |
5244 memcpy(prr, &temp, sizeof(T_NC)); | |
5245 /*TRACE_EVENT_P4("reordered NC%u[%u] and NC%u[%u]", | |
5246 n_rr, | |
5247 ncell_list->arfcn[n_rr], | |
5248 n_alr, ncell_list->arfcn[n_alr]);*/ | |
5249 } | |
5250 } | |
5251 } | |
5252 | |
5253 ALR_TRACE_ALL_NC (); | |
5254 } | |
5255 | |
5256 /* | |
5257 +--------------------------------------------------------------------+ | |
5258 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5259 | STATE : code ROUTINE : nc_new_serving_cell | | |
5260 +--------------------------------------------------------------------+ | |
5261 | |
5262 PURPOSE : Store old, set new serving cell, and add to neighbourcell list. | |
5263 | |
5264 */ | |
5265 GLOBAL void nc_new_serving_cell (USHORT serving_cell) | |
5266 { | |
5267 alr_data->old_serving_cell = alr_data->serving_cell; | |
5268 alr_data->serving_cell = serving_cell; | |
5269 alr_data->sc_band = get_band (alr_data->serving_cell); | |
5270 nc_add_serving_cell_ba_list(serving_cell); | |
5271 } | |
5272 | |
5273 /* | |
5274 +--------------------------------------------------------------------+ | |
5275 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5276 | STATE : code ROUTINE : nc_is_in_ncell_list | | |
5277 +--------------------------------------------------------------------+ | |
5278 | |
5279 PURPOSE : Checks whether a channel is in the ncell_list of RR. | |
5280 | |
5281 */ | |
5282 LOCAL UBYTE nc_is_in_ncell_list (USHORT channel, T_MPH_NEIGHBOURCELL_REQ *ncell_list) | |
5283 { | |
5284 USHORT i; | |
5285 | |
5286 for (i = 0; i < MAX_NEIGHBOURCELLS AND ncell_list->arfcn[i] NEQ NOT_PRESENT_16BIT; i++) | |
5287 { | |
5288 if (channel EQ ncell_list->arfcn[i]) | |
5289 return TRUE; | |
5290 } | |
5291 | |
5292 return FALSE; | |
5293 } | |
5294 | |
5295 /* | |
5296 +--------------------------------------------------------------------+ | |
5297 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5298 | STATE : code ROUTINE : nc_remove_channel_from_ba_list | | |
5299 +--------------------------------------------------------------------+ | |
5300 | |
5301 PURPOSE : Removes one channel from the BCCH allocation. | |
5302 | |
5303 */ | |
5304 | |
5305 LOCAL UBYTE nc_remove_channel_from_ba_list (USHORT index) | |
5306 { | |
5307 USHORT i; | |
5308 UBYTE c_ba_arfcn; | |
5309 | |
5310 switch(alr_data->nc_data.cell[index].status) | |
5311 { | |
5312 case READ_SB_PENDING: | |
5313 case READ_SB_BCCH_PENDING: | |
5314 if ( alr_data->nc_data.eotd_avail AND | |
5315 ( GET_STATE(STATE_NC_PROC) EQ NC_CONFIRM) ) | |
5316 { | |
5317 /* we cannot stop this | |
5318 * because we are using a list_req | |
5319 */ | |
5320 nc_set_status(index, INACTIVE); | |
5321 break; | |
5322 } | |
5323 /*lint -fallthrough*/ | |
5324 case READ_FB_SB_PENDING: | |
5325 /* | |
5326 * sync request is ongoing in layer 1. | |
5327 */ | |
5328 nc_stop_sync (index, INACTIVE); | |
5329 break; | |
5330 case READ_BCCH_PENDING: | |
5331 case READ_BCCH_PENDING_RR_NOT_INFORMED: | |
5332 /* | |
5333 * stop pending BCCH request | |
5334 */ | |
5335 nc_stop_bcch (index, INACTIVE); | |
5336 break; | |
5337 default: | |
5338 nc_set_status (index, INACTIVE); | |
5339 break; | |
5340 } | |
5341 | |
5342 c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
5343 for (i = index + 1; i < c_ba_arfcn; i++) | |
5344 { | |
5345 memcpy (&alr_data->nc_data.cell[i - 1],&alr_data->nc_data.cell[i],sizeof(T_NC)); /*shift NC*/ | |
5346 } | |
5347 memset (&alr_data->nc_data.cell[i - 1],0,sizeof (T_NC));/*delete old content of obsolete ba_list entry*/ | |
5348 | |
5349 alr_data->nc_data.c_ba_arfcn--; | |
5350 return (alr_data->nc_data.c_ba_arfcn); | |
5351 } | |
5352 | |
5353 | |
5354 /* | |
5355 +--------------------------------------------------------------------+ | |
5356 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5357 | STATE : code ROUTINE : nc_get_index | | |
5358 +--------------------------------------------------------------------+ | |
5359 | |
5360 PURPOSE : Calculates the index in the BCCH allocation. | |
5361 | |
5362 */ | |
5363 | |
5364 GLOBAL USHORT nc_get_index (USHORT arfcn) | |
5365 { | |
5366 USHORT i; | |
5367 T_NC *pcell; /* use pointer to increase processing speed */ | |
5368 USHORT last_alr; /* last index of ALR neighbor cell list */ | |
5369 | |
5370 last_alr = alr_data->nc_data.c_ba_arfcn; | |
5371 pcell = &alr_data->nc_data.cell[0]; /* pointer to first cell */ | |
5372 for (i = 0; i < last_alr; i++, pcell++) | |
5373 { | |
5374 if (arfcn EQ pcell->ba_arfcn) | |
5375 return i; | |
5376 } | |
5377 | |
5378 if (arfcn EQ alr_data->nc_data.cell[LAST_BSIC_REQ].ba_arfcn) | |
5379 return LAST_BSIC_REQ; | |
5380 | |
5381 return NOT_PRESENT_16BIT; | |
5382 } | |
5383 /* | |
5384 +--------------------------------------------------------------------+ | |
5385 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5386 | STATE : code ROUTINE : nc_build_sync_req | | |
5387 +--------------------------------------------------------------------+ | |
5388 | |
5389 PURPOSE : Builds an MPHC_NCELL_SYNC_REQ and sends it to L1. | |
5390 | |
5391 */ | |
5392 LOCAL void nc_build_sync_req (USHORT index) | |
5393 { | |
5394 T_NC * p_ncell = &alr_data->nc_data.cell[index]; | |
5395 PALLOC (sync_req, MPHC_NCELL_SYNC_REQ); | |
5396 | |
5397 sync_req->radio_freq = ARFCN_TO_L1(p_ncell->ba_arfcn); | |
5398 if (p_ncell->tim_valid EQ TV_INVALID_TIMING_INFO) | |
5399 { | |
5400 sync_req->fn_offset = 0; | |
5401 sync_req->time_alignment = 0; | |
5402 } | |
5403 else | |
5404 { | |
5405 sync_req->fn_offset = p_ncell->frame_offset; | |
5406 sync_req->time_alignment = p_ncell->time_align; | |
5407 } | |
5408 sync_req->timing_validity = p_ncell->tim_valid; | |
5409 TRACE_EVENT_P4("nc_build_sync_req[%d] timing_validity=%d fn_offset=%ld, time_alignment=%ld", | |
5410 p_ncell->ba_arfcn, | |
5411 sync_req->timing_validity, | |
5412 sync_req->fn_offset, | |
5413 sync_req->time_alignment); | |
5414 ma_nc_sync_req (sync_req); | |
5415 | |
5416 ALR_EM_READ_NEIGHBOURCELL_SB; | |
5417 | |
5418 nc_set_status (index, READ_FB_SB_PENDING); | |
5419 alr_data->nc_data.c_sync_req++; | |
5420 } | |
5421 | |
5422 | |
5423 /* | |
5424 +--------------------------------------------------------------------+ | |
5425 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5426 | STATE : code ROUTINE : nc_process_status | | |
5427 +--------------------------------------------------------------------+ | |
5428 | |
5429 PURPOSE : Starts a specific procedure for neighbour cells like | |
5430 synchronisation to frequency correction burst and | |
5431 synchron burst, confirmation of synchron burst or | |
5432 reading of BCCH. With the new ALR interface it's possible | |
5433 to send up to 12 SYNC_REQ's and BCCH_REQ's. | |
5434 | |
5435 */ | |
5436 | |
5437 LOCAL void nc_process_status (void) | |
5438 { | |
5439 UBYTE st = GET_STATE(STATE_NC); | |
5440 | |
5441 /* Sync requests for New cells are allowed only in dedicated state | |
5442 * when eotd is not enabled. Fix for | |
5443 */ | |
5444 if(((alr_data->nc_data.eotd_avail) OR ( st NEQ NC_DEDICATED)) AND | |
5445 (GET_STATE(STATE_NC_PROC) EQ NC_CONFIRM)) | |
5446 return; | |
5447 | |
5448 #ifdef GPRS | |
5449 if((st EQ NC_IDLE AND !ma_is_ptm()) OR | |
5450 st EQ NC_PIM_PBCCH ) | |
5451 nc_process_status_last_bsic(); | |
5452 #else | |
5453 nc_process_status_last_bsic(); | |
5454 #endif | |
5455 | |
5456 | |
5457 if(alr_data->plmn_search_running) | |
5458 return; | |
5459 | |
5460 #ifdef GPRS | |
5461 if(st EQ NC_PIM_PBCCH OR | |
5462 st EQ NC_PTM_PBCCH ) | |
5463 nc_process_status_sync_gprs(); | |
5464 else | |
5465 #endif | |
5466 nc_process_status_sync(); | |
5467 | |
5468 if(st EQ NC_IDLE) | |
5469 nc_process_status_bcch(); | |
5470 } | |
5471 | |
5472 /* | |
5473 +--------------------------------------------------------------------+ | |
5474 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5475 | STATE : code ROUTINE : nc_process_status_last_bsic| | |
5476 +--------------------------------------------------------------------+ | |
5477 | |
5478 PURPOSE : When doing idle mode cell selection we use | |
5479 LAST_BSIC_REQ for storing the information of the cell. | |
5480 This has priority over normal neighbour cell monitoring. | |
5481 | |
5482 */ | |
5483 | |
5484 | |
5485 LOCAL void nc_process_status_last_bsic(void) | |
5486 { | |
5487 T_NC* pbsic = &alr_data->nc_data.cell[LAST_BSIC_REQ]; | |
5488 | |
5489 | |
5490 switch (pbsic->status) | |
5491 { | |
5492 case READ_FB_SB: | |
5493 if (alr_data->nc_data.c_sync_req < MAX_L1_SYNC_CNT) | |
5494 { | |
5495 pbsic->tim_valid = TV_INVALID_TIMING_INFO; | |
5496 nc_build_sync_req (LAST_BSIC_REQ); | |
5497 ALR_TRACE_NC ("ncell_sync_req HPLMN"); | |
5498 | |
5499 /* If the Mobile is in page mode REORG the NC search cannot be | |
5500 * performed because L1 is too busy listening to the PCH. Therefore | |
5501 * the page mode is changed from REORG to REORG_NC_SYNC (NORMAL). | |
5502 */ | |
5503 if(alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG OR | |
5504 alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG_CS) | |
5505 { | |
5506 page_mode_before_hplmn_search = alr_data->pch_data.pl_idle.page_mode; | |
5507 alr_data->pch_data.pl_idle.page_mode = PGM_REORG_NC_SYNC; | |
5508 pch_start_ccch_req (); | |
5509 ALR_TRACE_NC ("HPLMN search cannot be performed with REORG - possible loss of pagings"); | |
5510 } | |
5511 | |
5512 } | |
5513 return ; | |
5514 | |
5515 case READ_BCCH: | |
5516 if (alr_data->nc_data.c_bcch_req < MAX_L1_BCCH_CNT) | |
5517 { | |
5518 PALLOC (ncell_bcch, MPHC_NCELL_BCCH_REQ); | |
5519 | |
5520 ncell_bcch->radio_freq = ARFCN_TO_L1(pbsic->ba_arfcn); | |
5521 ncell_bcch->fn_offset = pbsic->frame_offset; | |
5522 ncell_bcch->time_alignment = pbsic->time_align; | |
5523 /* | |
5524 * The training sequence code on broadcast and common control channels | |
5525 * has to be equal to the base station color code see GSM 5.02 | |
5526 */ | |
5527 ncell_bcch->tsc = (UBYTE)(pbsic->bsic & ONLY_BCC); | |
5528 /* | |
5529 * Read SI 3/4 to get the MNC/MCC | |
5530 */ | |
5531 pbsic->blocks_required = | |
5532 ncell_bcch->bcch_blocks_required = NCELL_BCCH_SI_3_4; | |
5533 ncell_bcch->gprs_prio = GPRS_PRIO_NORM; | |
5534 | |
5535 ma_nc_bcch_req (ncell_bcch); | |
5536 alr_data->nc_data.c_bcch_req++; | |
5537 nc_set_status (LAST_BSIC_REQ, READ_BCCH_PENDING); | |
5538 } | |
5539 return; | |
5540 case READ_FB_SB_PENDING: | |
5541 case READ_BCCH_PENDING: | |
5542 return; | |
5543 default: | |
5544 break; | |
5545 } | |
5546 } | |
5547 | |
5548 | |
5549 /* | |
5550 +--------------------------------------------------------------------+ | |
5551 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5552 | STATE : code ROUTINE : nc_process_status_sync | | |
5553 +--------------------------------------------------------------------+ | |
5554 | |
5555 PURPOSE : Processes cell synchronisation. | |
5556 | |
5557 */ | |
5558 | |
5559 | |
5560 | |
5561 LOCAL void nc_process_status_sync(void) | |
5562 { | |
5563 USHORT i; | |
5564 USHORT index; | |
5565 T_NC* pbsic = &alr_data->nc_data.cell[LAST_BSIC_REQ]; | |
5566 | |
5567 /* Sync requests for New cells are allowed only in dedicated state | |
5568 * when eotd is not enabled. Patch for | |
5569 */ | |
5570 if((!alr_data->nc_data.eotd_avail) AND | |
5571 ( GET_STATE(STATE_NC) EQ NC_DEDICATED) AND | |
5572 (GET_STATE(STATE_NC_PROC) EQ NC_CONFIRM)) | |
5573 { | |
5574 if(alr_data->nc_data.new_strong_cell_detect) | |
5575 nc_handle_new_strong_cells(); | |
5576 | |
5577 alr_data->nc_data.new_strong_cell_detect = FALSE; | |
5578 return; | |
5579 } | |
5580 | |
5581 while (alr_data->nc_data.c_sync_req < MAX_L1_SYNC_CNT) | |
5582 { | |
5583 /* | |
5584 * It is possible to send more sync requests to layer 1 | |
5585 */ | |
5586 USHORT c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
5587 index = NOT_PRESENT_16BIT; | |
5588 | |
5589 for (i = 0; i < c_ba_arfcn; i++) | |
5590 { | |
5591 /* | |
5592 * search for the candidate with the highest fieldstrength | |
5593 */ | |
5594 T_NC* pcell = &alr_data->nc_data.cell[i]; | |
5595 | |
5596 if ((pcell->ba_arfcn NEQ pbsic->ba_arfcn) AND | |
5597 (pcell->ba_arfcn NEQ alr_data->serving_cell)) | |
5598 { | |
5599 switch (pcell->status) | |
5600 { | |
5601 case READ_FB_SB: | |
5602 if (index EQ NOT_PRESENT_16BIT) | |
5603 index = i; | |
5604 else | |
5605 { | |
5606 if (pcell->rxlev_average > | |
5607 alr_data->nc_data.cell[index].rxlev_average) | |
5608 index = i; | |
5609 } | |
5610 break; | |
5611 default: | |
5612 break; | |
5613 } | |
5614 } | |
5615 } | |
5616 | |
5617 if (index NEQ NOT_PRESENT_16BIT) | |
5618 { | |
5619 /* | |
5620 * Request synchronisation for this cell | |
5621 */ | |
5622 nc_build_sync_req(index); | |
5623 ALR_TRACE_NC ("ncell_sync_req"); | |
5624 } | |
5625 else | |
5626 break; /*while loop */ | |
5627 } /* while( c_sync_req < MAX_L1_SYNC_CNT) */ | |
5628 } | |
5629 | |
5630 /* | |
5631 +--------------------------------------------------------------------+ | |
5632 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5633 | STATE : code ROUTINE : nc_process_status_sync_gprs| | |
5634 +--------------------------------------------------------------------+ | |
5635 | |
5636 PURPOSE : Processes GPRS cell synchronisation. | |
5637 | |
5638 */ | |
5639 | |
5640 | |
5641 #ifdef GPRS /*XXX*/ | |
5642 LOCAL void nc_process_status_sync_gprs(void) | |
5643 { | |
5644 USHORT i; | |
5645 T_NC* pbsic = &alr_data->nc_data.cell[LAST_BSIC_REQ]; | |
5646 USHORT c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
5647 | |
5648 | |
5649 for (i = 0; i < c_ba_arfcn AND alr_data->nc_data.c_sync_req < MAX_L1_SYNC_CNT; i++) | |
5650 { | |
5651 /* | |
5652 * search for the candidate with the highest fieldstrength | |
5653 */ | |
5654 T_NC* pcell = &alr_data->nc_data.cell[i]; | |
5655 | |
5656 if ((pcell->ba_arfcn NEQ pbsic->ba_arfcn) AND | |
5657 (pcell->ba_arfcn NEQ alr_data->serving_cell) AND | |
5658 (pcell->status EQ READ_FB_SB)) | |
5659 { | |
5660 /* | |
5661 * Request synchronisation for this cell | |
5662 */ | |
5663 nc_build_sync_req(i); | |
5664 ALR_TRACE_NC ("ncell_sync_req"); | |
5665 } | |
5666 } | |
5667 } | |
5668 | |
5669 /* | |
5670 +--------------------------------------------------------------------+ | |
5671 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5672 | STATE : code ROUTINE : nc_sync_failed_gprs | | |
5673 +--------------------------------------------------------------------+ | |
5674 | |
5675 PURPOSE : Handles synchronisation failed situation | |
5676 | |
5677 */ | |
5678 | |
5679 | |
5680 LOCAL void nc_sync_failed_gprs(USHORT index) | |
5681 { | |
5682 alr_data->nc_data.cell[index].c_sync = 1; /*XXX*/ | |
5683 nc_set_status (index, FB_SB_FAILED); | |
5684 nc_inform_grr_of_ncell(index, GRR_SB_NOT_FOUND); | |
5685 } | |
5686 #endif | |
5687 | |
5688 | |
5689 /* | |
5690 +--------------------------------------------------------------------+ | |
5691 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5692 | STATE : code ROUTINE : nc_process_status_bcch | | |
5693 +--------------------------------------------------------------------+ | |
5694 | |
5695 PURPOSE : Processes CB status | |
5696 | |
5697 */ | |
5698 | |
5699 | |
5700 LOCAL void nc_process_status_bcch(void) | |
5701 { | |
5702 USHORT i; | |
5703 USHORT index; | |
5704 T_NC* pbsic = &alr_data->nc_data.cell[LAST_BSIC_REQ]; | |
5705 | |
5706 while (alr_data->nc_data.c_bcch_req < MAX_L1_BCCH_CNT) | |
5707 { | |
5708 /* | |
5709 * It is possible to send more BCCH request to layer 1 | |
5710 */ | |
5711 USHORT c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
5712 index = NOT_PRESENT_16BIT; | |
5713 | |
5714 for (i = 0; i < c_ba_arfcn; i++) | |
5715 { | |
5716 /* | |
5717 * search for the candidate with the highest fieldstrength | |
5718 */ | |
5719 T_NC* pcell = &alr_data->nc_data.cell[i]; | |
5720 | |
5721 if ((pcell->ba_arfcn NEQ pbsic->ba_arfcn) AND | |
5722 (pcell->ba_arfcn NEQ alr_data->serving_cell)) | |
5723 { | |
5724 switch (pcell->status) | |
5725 { | |
5726 case READ_BCCH: | |
5727 case READ_BCCH_RR_NOT_INFORMED: | |
5728 if (index EQ NOT_PRESENT_16BIT) | |
5729 index = i; | |
5730 else | |
5731 { | |
5732 if (pcell->rxlev_average > | |
5733 alr_data->nc_data.cell[index].rxlev_average) | |
5734 index = i; | |
5735 } | |
5736 break; | |
5737 default: | |
5738 break; | |
5739 } | |
5740 } | |
5741 } | |
5742 | |
5743 if (index NEQ NOT_PRESENT_16BIT) | |
5744 { | |
5745 /* | |
5746 * Request BCCH reading for this cell | |
5747 */ | |
5748 T_NC* pcell = &alr_data->nc_data.cell[index]; | |
5749 PALLOC (ncell_bcch, MPHC_NCELL_BCCH_REQ); | |
5750 | |
5751 ncell_bcch->radio_freq = ARFCN_TO_L1(pcell->ba_arfcn); | |
5752 ncell_bcch->fn_offset = pcell->frame_offset; | |
5753 ncell_bcch->time_alignment = pcell->time_align; | |
5754 /* | |
5755 * The training sequence code on broadcast and common control channels | |
5756 * has to be equal to the Base Station Colour Code (BCC), | |
5757 * see 3GPP TS 5.02, section 5.2.3 and | |
5758 * 3GPP TS 03.03, section 4.3.2 Base Station Identify Code (BSIC) | |
5759 */ | |
5760 ncell_bcch->tsc = (UBYTE)(pcell->bsic & ONLY_BCC); | |
5761 pcell->blocks_required = | |
5762 ncell_bcch->bcch_blocks_required = NCELL_BCCH_SI_3_4; | |
5763 #ifdef GPRS | |
5764 /*if the mobile is in PTM the GPRS_PRIORITY must be set to TOP*/ | |
5765 if(ma_is_ptm()) | |
5766 { | |
5767 ncell_bcch->gprs_prio = GPRS_PRIO_TOP; | |
5768 } | |
5769 else | |
5770 #endif | |
5771 ncell_bcch->gprs_prio = GPRS_PRIO_NORM; | |
5772 | |
5773 | |
5774 ma_nc_bcch_req (ncell_bcch); | |
5775 | |
5776 ALR_TRACE_NC("ncell_bcch_read"); | |
5777 | |
5778 alr_data->nc_data.c_bcch_req++; | |
5779 /* | |
5780 * read a maximum of four blocks | |
5781 * | |
5782 * sys info 3 normal BCCH TC 2 or 6 | |
5783 * sys info 4 normal BCCH TC 3 or 7 | |
5784 */ | |
5785 if(pcell->status EQ READ_BCCH) | |
5786 nc_set_status (index, READ_BCCH_PENDING); | |
5787 else | |
5788 nc_set_status (index, READ_BCCH_PENDING_RR_NOT_INFORMED); | |
5789 } | |
5790 else | |
5791 break; /*while loop */ | |
5792 } /* while(c_bcch_req < MAX_L1_BCCH_CNT)*/ | |
5793 } | |
5794 | |
5795 /* | |
5796 +--------------------------------------------------------------------+ | |
5797 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5798 | STATE : code ROUTINE : nc_ncell_in_plmn_permitted | | |
5799 +--------------------------------------------------------------------+ | |
5800 | |
5801 PURPOSE : checks whether the national colour code (ncc) is member | |
5802 of the ncc permitted field. | |
5803 | |
5804 */ | |
5805 static const UBYTE ncc_bit_mask[8] = | |
5806 { | |
5807 BIT_0, BIT_1, BIT_2, BIT_3, | |
5808 BIT_4, BIT_5, BIT_6, BIT_7 | |
5809 }; | |
5810 | |
5811 LOCAL BOOL nc_ncell_in_plmn_permitted (UBYTE bsic) | |
5812 { | |
5813 return ((BOOL) ((UBYTE) (alr_data->ncc_permitted & | |
5814 ncc_bit_mask[(bsic >> 3) & BIT_012])) NEQ 0); | |
5815 } | |
5816 | |
5817 | |
5818 /* | |
5819 +--------------------------------------------------------------------+ | |
5820 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5821 | STATE : code ROUTINE : nc_store_dedicated | | |
5822 +--------------------------------------------------------------------+ | |
5823 | |
5824 PURPOSE : Stores the values of the neighbour cells | |
5825 and the serving cell. | |
5826 | |
5827 */ | |
5828 LOCAL void nc_store_dedicated (T_MPHC_MEAS_REPORT *report) | |
5829 { | |
5830 USHORT i; | |
5831 USHORT index; | |
5832 USHORT c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
5833 | |
5834 if (alr_data->nc_data.tim_state NEQ NC_TIM_STOPPED) | |
5835 { | |
5836 /* Decrement the 10sec timer counter variable by 2 */ | |
5837 alr_data->nc_data.c_ncsync_tim = alr_data->nc_data.c_ncsync_tim-2; | |
5838 | |
5839 if ((signed char)( alr_data->nc_data.c_ncsync_tim) < 0) | |
5840 alr_data->nc_data.c_ncsync_tim = 0; | |
5841 | |
5842 if( alr_data->nc_data.c_ncsync_tim EQ 0 ) /* 10 sec have elapsed. Perform all requisite tasks */ | |
5843 nc_ncsync_tim_expiry(); | |
5844 } | |
5845 | |
5846 for (i = 0; i < report->no_of_ncells_meas; i++) | |
5847 { | |
5848 T_NC* pcell; | |
5849 T_res_list* plist = &report->ncell_meas.res_list[i]; | |
5850 | |
5851 index = nc_get_index (ARFCN_TO_G23(plist->bcch_freq)); | |
5852 if ((index EQ NOT_PRESENT_16BIT) OR (index EQ LAST_BSIC_REQ)) | |
5853 continue; | |
5854 pcell = &alr_data->nc_data.cell[index]; | |
5855 | |
5856 if (plist->rxlev_nbr_meas EQ 0) | |
5857 pcell->rxlev_average = 0; | |
5858 else | |
5859 { | |
5860 if ((signed short)(plist->rxlev_acc) < 0) | |
5861 plist->rxlev_acc = 0; | |
5862 | |
5863 /* why this casting? - a "real" expression is of type int */ | |
5864 pcell->rxlev_average = (UBYTE)(plist->rxlev_acc/plist->rxlev_nbr_meas); | |
5865 } | |
5866 if (pcell->status EQ INACTIVE) | |
5867 nc_set_status (index, IDLE); | |
5868 | |
5869 if (pcell->status EQ EXCLUDED) | |
5870 { | |
5871 int diff; | |
5872 | |
5873 diff = pcell->rxlev_average - pcell->last_rxlev; | |
5874 | |
5875 if (diff >= 6) | |
5876 { | |
5877 /* | |
5878 * result is positive and more than 6 dBm | |
5879 */ | |
5880 nc_set_status (index, IDLE); | |
5881 } | |
5882 } | |
5883 } | |
5884 | |
5885 | |
5886 alr_data->nc_data.act_dtx = report->dtx_used; | |
5887 | |
5888 if (report->rxlev_full_nbr_meas EQ 0) | |
5889 alr_data->nc_data.rxlev_full = 0; | |
5890 else | |
5891 { | |
5892 if ((signed short)(report->rxlev_full_acc) < 0) | |
5893 report->rxlev_full_acc = 0; | |
5894 | |
5895 alr_data->nc_data.rxlev_full = | |
5896 (UBYTE)(report->rxlev_full_acc / report->rxlev_full_nbr_meas); | |
5897 } | |
5898 | |
5899 if (report->rxlev_sub_nbr_meas EQ 0) | |
5900 alr_data->nc_data.rxlev_sub = 0; | |
5901 else | |
5902 { | |
5903 if ((signed short)(report->rxlev_sub_acc) < 0) | |
5904 report->rxlev_sub_acc = 0; | |
5905 alr_data->nc_data.rxlev_sub = (UBYTE)(report->rxlev_sub_acc / report->rxlev_sub_nbr_meas); | |
5906 } | |
5907 | |
5908 alr_data->nc_data.rxqual_full = | |
5909 nc_convert_quality (report->rxqual_full_acc_errors, | |
5910 report->rxqual_full_nbr_bits); | |
5911 | |
5912 alr_data->nc_data.rxqual_sub = | |
5913 nc_convert_quality (report->rxqual_sub_acc_errors, | |
5914 report->rxqual_sub_nbr_bits); | |
5915 } | |
5916 | |
5917 | |
5918 | |
5919 /* | |
5920 +--------------------------------------------------------------------+ | |
5921 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5922 | STATE : code ROUTINE : nc_convert_quality | | |
5923 +--------------------------------------------------------------------+ | |
5924 | |
5925 PURPOSE : Calculates the quality Value. | |
5926 | |
5927 */ | |
5928 | |
5929 LOCAL UBYTE nc_convert_quality (USHORT errors, USHORT total) | |
5930 { | |
5931 USHORT quality; | |
5932 | |
5933 if (total EQ 0) | |
5934 quality = 0; | |
5935 else | |
5936 quality = (USHORT)((errors * 500) / total); | |
5937 | |
5938 if (quality EQ 0) | |
5939 return 0; /* RX_QUAL_0 */ | |
5940 | |
5941 if (quality EQ 1) | |
5942 return 1; /* RX_QUAL_1 */ | |
5943 | |
5944 if (quality < 4) | |
5945 return 2; /* RX_QUAL_2 */ | |
5946 | |
5947 if (quality < 8) | |
5948 return 3; /* RX_QUAL_3 */ | |
5949 | |
5950 if (quality < 16) | |
5951 return 4; /* RX_QUAL_4 */ | |
5952 | |
5953 if (quality < 32) | |
5954 return 5; /* RX_QUAL_5 */ | |
5955 | |
5956 if (quality < 64) | |
5957 return 6; /* RX_QUAL_6 */ | |
5958 | |
5959 return 7; /* RX_QUAL_7 */ | |
5960 | |
5961 } | |
5962 | |
5963 /* | |
5964 +--------------------------------------------------------------------+ | |
5965 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
5966 | STATE : code ROUTINE : nc_release_bcch | | |
5967 +--------------------------------------------------------------------+ | |
5968 | |
5969 PURPOSE : Check if we have read the BCCH of a ncell but RR has | |
5970 not yet received the data because this cell has not | |
5971 been reported to RR before. | |
5972 */ | |
5973 | |
5974 LOCAL void nc_release_bcch (void) | |
5975 { | |
5976 USHORT i; | |
5977 USHORT c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
5978 /* | |
5979 * for every ncell | |
5980 */ | |
5981 for (i = 0; i < c_ba_arfcn; i++) | |
5982 { | |
5983 T_NC* pcell = &alr_data->nc_data.cell[i]; | |
5984 | |
5985 switch (pcell->status) | |
5986 { | |
5987 case FB_SB_SYNC_RR_NOT_INFORMED: | |
5988 /* | |
5989 * Reading of the BCCH of the neighbourcell is performed, | |
5990 * but RR has been just informed with a measurement report | |
5991 * about synchronisation. | |
5992 */ | |
5993 if(pcell->mph_unitdata_ind NEQ NULL) | |
5994 { | |
5995 ALR_TRACE_NC ("send 34"); | |
5996 | |
5997 /* | |
5998 * a system info type 3 or 4 message is stored. | |
5999 * Send the message to RR and clear the internal variable. | |
6000 */ | |
6001 PSENDX(RR, pcell->mph_unitdata_ind); | |
6002 pcell->mph_unitdata_ind = NULL; | |
6003 } | |
6004 | |
6005 if(pcell->mph_unitdata_ind78 NEQ NULL) | |
6006 { | |
6007 ALR_TRACE_NC ("send 78"); | |
6008 | |
6009 /* | |
6010 * a system info type 7 or 8 message is stored. | |
6011 * Send the message to RR and clear the internal variable. | |
6012 */ | |
6013 PSENDX(RR, pcell->mph_unitdata_ind78); | |
6014 pcell->mph_unitdata_ind78 = NULL; | |
6015 } | |
6016 | |
6017 /* | |
6018 * set status to FB_SB_SYNC, that means RR is completely informed. | |
6019 */ | |
6020 nc_set_fb_sb_sync_initial (i); | |
6021 break; | |
6022 | |
6023 default: | |
6024 break; | |
6025 } | |
6026 } | |
6027 } | |
6028 | |
6029 /* | |
6030 +--------------------------------------------------------------------+ | |
6031 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
6032 | STATE : code ROUTINE : nc_store_bcch | | |
6033 +--------------------------------------------------------------------+ | |
6034 | |
6035 PURPOSE : Temporarily store BCCH data for ncell. | |
6036 | |
6037 */ | |
6038 | |
6039 LOCAL void nc_store_bcch (T_MPHC_DATA_IND* data_ind, USHORT index, UBYTE sys_info_78) | |
6040 { | |
6041 #define SYS_INFO_LEN 24 | |
6042 | |
6043 USHORT len_in_bits = SYS_INFO_LEN * BITS_PER_BYTE; | |
6044 T_NC* pcell = &alr_data->nc_data.cell[index]; | |
6045 /* | |
6046 * Allocate a SDU for sending later to RR | |
6047 */ | |
6048 PALLOC_SDU (data_out, MPH_UNITDATA_IND, len_in_bits); | |
6049 | |
6050 /* | |
6051 * set length and offset, but cut IE and Pseudo Length | |
6052 */ | |
6053 data_out->sdu.l_buf = (SYS_INFO_LEN - 2) * BITS_PER_BYTE; | |
6054 data_out->sdu.o_buf = 1 * BITS_PER_BYTE; | |
6055 | |
6056 /* | |
6057 * copy content of the message | |
6058 */ | |
6059 memcpy (data_out->sdu.buf, &data_ind->l2_frame, SYS_INFO_LEN - 1);/*lint !e419 (Warning -- Apparent data overrun)*/ | |
6060 | |
6061 /* | |
6062 * set BCCH frequency of the message | |
6063 */ | |
6064 data_out->arfcn = ARFCN_TO_G23(data_ind->radio_freq)&ARFCN_MASK; | |
6065 data_out->fn = data_ind->fn; | |
6066 | |
6067 if (sys_info_78) | |
6068 { | |
6069 ALR_TRACE_NC ("store 78"); | |
6070 | |
6071 /* | |
6072 * if it is a system info 7 or 8 message, free the previous | |
6073 * stored message, if something is stored and store the new | |
6074 * one. | |
6075 */ | |
6076 if (pcell->mph_unitdata_ind78 NEQ NULL) | |
6077 { | |
6078 ALR_TRACE_NC ("store,free old 78"); | |
6079 | |
6080 PFREE(pcell->mph_unitdata_ind78); | |
6081 } | |
6082 | |
6083 pcell->mph_unitdata_ind78 = data_out; | |
6084 | |
6085 } | |
6086 else | |
6087 { | |
6088 ALR_TRACE_NC ("store 34"); | |
6089 | |
6090 /* | |
6091 * if it is a system info 3 or 4 message, free the previous | |
6092 * stored message, if something is stored and store the new | |
6093 * one. | |
6094 */ | |
6095 if (pcell->mph_unitdata_ind NEQ NULL) | |
6096 { | |
6097 ALR_TRACE_NC( "store,free old 34"); | |
6098 | |
6099 PFREE(pcell->mph_unitdata_ind); | |
6100 } | |
6101 | |
6102 pcell->mph_unitdata_ind = data_out; | |
6103 | |
6104 } | |
6105 } | |
6106 | |
6107 | |
6108 /* | |
6109 +--------------------------------------------------------------------+ | |
6110 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
6111 | STATE : code ROUTINE : nc_sys_info_78_required | | |
6112 +--------------------------------------------------------------------+ | |
6113 | |
6114 PURPOSE : The function checks whether sys info 7 or 8 are expected | |
6115 and required. | |
6116 | |
6117 */ | |
6118 | |
6119 LOCAL UBYTE nc_sys_info_78_required (USHORT index) | |
6120 { | |
6121 if (alr_data->nc_data.cell[index].mph_unitdata_ind NEQ 0) | |
6122 { | |
6123 T_sdu * sdu = &alr_data->nc_data.cell[index].mph_unitdata_ind->sdu; | |
6124 /*lint -e415 (Warning -- creation of out-of-bounds pointer)*/ | |
6125 /*lint -e416 (Warning -- access of out-of-bounds pointer)*/ | |
6126 if ((sdu->buf[SI_CONTENTS_CS2] & ONLY_ACS) NEQ 0) | |
6127 return TRUE; | |
6128 /*lint +e415 (Warning -- creation of out-of-bounds pointer)*/ | |
6129 /*lint +e416 (Warning -- access of out-of-bounds pointer)*/ | |
6130 } | |
6131 return FALSE; | |
6132 } | |
6133 | |
6134 /* | |
6135 +--------------------------------------------------------------------+ | |
6136 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
6137 | STATE : code ROUTINE : nc_stop_bcch | | |
6138 +--------------------------------------------------------------------+ | |
6139 | |
6140 PURPOSE : Stop a pending BCCH. | |
6141 | |
6142 */ | |
6143 | |
6144 LOCAL void nc_stop_bcch (USHORT index, UBYTE new_status) | |
6145 { | |
6146 /* | |
6147 * L3 may avoid sending a stop message to terminate a NCELL_BCCH process | |
6148 * if there no more pending request in L1 | |
6149 */ | |
6150 | |
6151 if (alr_data->nc_data.c_bcch_req > 0) | |
6152 { | |
6153 /* | |
6154 * stop BCCH request in layer 1. | |
6155 */ | |
6156 ma_nc_stop_ncell_bcch_req(alr_data->nc_data.cell[index].ba_arfcn); | |
6157 | |
6158 /* | |
6159 * decrement counter of pending requests | |
6160 */ | |
6161 alr_data->nc_data.c_bcch_req--; | |
6162 } | |
6163 | |
6164 /* | |
6165 * set new status | |
6166 */ | |
6167 nc_set_status (index, new_status); | |
6168 } | |
6169 | |
6170 | |
6171 /* | |
6172 +--------------------------------------------------------------------+ | |
6173 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
6174 | STATE : code ROUTINE : nc_stop_sync | | |
6175 +--------------------------------------------------------------------+ | |
6176 | |
6177 PURPOSE : Stop a pending Sync request. | |
6178 | |
6179 */ | |
6180 | |
6181 LOCAL void nc_stop_sync (USHORT index, UBYTE new_status) | |
6182 { | |
6183 /* | |
6184 * L3 may avoid sending a stop message to terminate a NCELL_SYNC process | |
6185 * if there no more pending request in L1 | |
6186 */ | |
6187 | |
6188 if (alr_data->nc_data.c_sync_req > 0) | |
6189 { | |
6190 /* | |
6191 * stop sync request in layer 1. | |
6192 */ | |
6193 ma_nc_stop_ncell_sync_req (alr_data->nc_data.cell[index].ba_arfcn); | |
6194 | |
6195 /* | |
6196 * decrement counter of pending requests | |
6197 */ | |
6198 alr_data->nc_data.c_sync_req--; | |
6199 /* | |
6200 * check whether the confirmation procedure is finished indirectly | |
6201 */ | |
6202 if (alr_data->nc_data.c_sync_req EQ 0 AND | |
6203 alr_data->nc_data.eotd_avail EQ FALSE AND | |
6204 GET_STATE(STATE_NC_PROC) EQ NC_CONFIRM) | |
6205 { | |
6206 nc_enable_conf(); | |
6207 } | |
6208 } | |
6209 | |
6210 /* | |
6211 * set new status | |
6212 */ | |
6213 nc_set_status (index, new_status); | |
6214 } | |
6215 | |
6216 /* | |
6217 +--------------------------------------------------------------------+ | |
6218 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
6219 | STATE : code ROUTINE : nc_clean_store_bcch | | |
6220 +--------------------------------------------------------------------+ | |
6221 | |
6222 PURPOSE : Clean a stored BCCH. | |
6223 | |
6224 */ | |
6225 | |
6226 LOCAL void nc_clean_store_bcch (USHORT index) | |
6227 { | |
6228 T_NC* pcell = &alr_data->nc_data.cell[index]; | |
6229 if (pcell->mph_unitdata_ind NEQ NULL) | |
6230 { | |
6231 ALR_TRACE_NC ("free 34"); | |
6232 | |
6233 /* | |
6234 * a system info type 3 or 4 message is stored | |
6235 * then free the message and clean the pointer. | |
6236 */ | |
6237 | |
6238 PFREE(pcell->mph_unitdata_ind); | |
6239 pcell->mph_unitdata_ind = NULL; | |
6240 | |
6241 } | |
6242 | |
6243 if(pcell->mph_unitdata_ind78 NEQ NULL) | |
6244 { | |
6245 ALR_TRACE_NC ("free 78"); | |
6246 | |
6247 /* | |
6248 * a system info type 7 or 8 message is stored | |
6249 * then free the message and clean the pointer. | |
6250 */ | |
6251 | |
6252 PFREE(pcell->mph_unitdata_ind78); | |
6253 pcell->mph_unitdata_ind78 = NULL; | |
6254 } | |
6255 } | |
6256 | |
6257 /* | |
6258 +--------------------------------------------------------------------+ | |
6259 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
6260 | STATE : code ROUTINE : nc_check_bsic | | |
6261 +--------------------------------------------------------------------+ | |
6262 | |
6263 PURPOSE : Check a base station identification code of a neighbourcell | |
6264 The following return values are possible: | |
6265 | |
6266 NC_CHECK_OK : BSIC has not changed and is permitted. | |
6267 NC_CHECK_NCC_FAILED : NCC permitted check has failed | |
6268 NC_CHECK_BSIC_CHANGED : a BSIC change has occured | |
6269 | |
6270 | |
6271 */ | |
6272 | |
6273 LOCAL UBYTE nc_check_bsic (USHORT index, UBYTE bsic) | |
6274 { | |
6275 /* | |
6276 * check only the lowest 6 bits (= NCC + BCC) | |
6277 */ | |
6278 bsic = (UBYTE)(bsic & ONLY_BSIC); | |
6279 | |
6280 /* | |
6281 * first check whether ncc is member of the ncc permitted field | |
6282 */ | |
6283 if (!nc_ncell_in_plmn_permitted (bsic)) | |
6284 return NC_CHECK_NCC_FAILED; | |
6285 | |
6286 /* | |
6287 * no bsic stored until now. | |
6288 */ | |
6289 if (alr_data->nc_data.cell[index].bsic EQ NOT_PRESENT_8BIT) | |
6290 return NC_CHECK_OK; | |
6291 | |
6292 /* | |
6293 * check against BSIC changes | |
6294 */ | |
6295 if (alr_data->nc_data.cell[index].bsic NEQ bsic) | |
6296 return NC_CHECK_BSIC_CHANGED; | |
6297 | |
6298 /* | |
6299 * all checks passed | |
6300 */ | |
6301 return NC_CHECK_OK; | |
6302 } | |
6303 | |
6304 | |
6305 /* | |
6306 +--------------------------------------------------------------------+ | |
6307 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
6308 | STATE : code ROUTINE : nc_check_new_ncc_permitted | | |
6309 +--------------------------------------------------------------------+ | |
6310 | |
6311 PURPOSE : Checks whether status transitions are needed after reception | |
6312 of a changed NCC permitted field. | |
6313 | |
6314 */ | |
6315 | |
6316 GLOBAL void nc_check_new_ncc_permitted (UBYTE new_ncc_permitted) | |
6317 { | |
6318 USHORT i; | |
6319 USHORT c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
6320 if (new_ncc_permitted NEQ alr_data->ncc_permitted) | |
6321 { | |
6322 /* | |
6323 * a change has occured, so store new value and check all cells | |
6324 */ | |
6325 alr_data->ncc_permitted = new_ncc_permitted; | |
6326 | |
6327 for (i = 0; i < c_ba_arfcn; i++) | |
6328 { | |
6329 switch (alr_data->nc_data.cell[i].status) | |
6330 { | |
6331 case FB_SB_SYNC: | |
6332 case FB_SB_SYNC_RR_NOT_INFORMED: | |
6333 case READ_SB: | |
6334 case READ_BCCH: | |
6335 case IDLE_SYNC: | |
6336 case READ_SB_BCCH: | |
6337 case READ_BCCH_RR_NOT_INFORMED: | |
6338 if (nc_ncell_in_plmn_permitted(alr_data->nc_data.cell[i].bsic) EQ FALSE) | |
6339 nc_set_status (i, EXCLUDED); | |
6340 break; | |
6341 | |
6342 case READ_BCCH_PENDING: | |
6343 case READ_BCCH_PENDING_RR_NOT_INFORMED: | |
6344 if (nc_ncell_in_plmn_permitted(alr_data->nc_data.cell[i].bsic) EQ FALSE) | |
6345 nc_set_status (i, EXCLUDED); | |
6346 break; | |
6347 | |
6348 case EXCLUDED: | |
6349 /* | |
6350 * give channel a new chance | |
6351 */ | |
6352 nc_set_status (i, IDLE); | |
6353 break; | |
6354 } | |
6355 } | |
6356 } | |
6357 } | |
6358 | |
6359 #if !defined(DEFINE_OLD_NC_STATUS) | |
6360 LOCAL UBYTE nc_get_nc_status(UBYTE status) | |
6361 { | |
6362 UBYTE st; | |
6363 | |
6364 switch (status) | |
6365 { | |
6366 case INACTIVE:st=0;break; | |
6367 case IDLE:st=1;break; | |
6368 case READ_BCCH:st=2;break; | |
6369 case FB_SB_SYNC:st=3;break; | |
6370 case FB_SB_FAILED:st=4;break; | |
6371 case READ_FB_SB:st=5;break; | |
6372 case READ_SB:st=6;break; | |
6373 case IDLE_SYNC:st=7;break; | |
6374 case EXCLUDED:st=8;break; | |
6375 case FB_SB_SYNC_RR_NOT_INFORMED:st=9;break; | |
6376 case READ_SB_BCCH:st=10;break; | |
6377 case READ_BCCH_PENDING:st=11;break; | |
6378 case READ_FB_SB_PENDING:st=12;break; | |
6379 case READ_SB_PENDING:st=13;break; | |
6380 case READ_SB_BCCH_PENDING:st=14;break; | |
6381 case READ_BCCH_RR_NOT_INFORMED:st=15;break; | |
6382 case READ_BCCH_PENDING_RR_NOT_INFORMED:st=16;break; | |
6383 default:st=17;break; | |
6384 } | |
6385 | |
6386 return st; | |
6387 } | |
6388 #else /* DEFINE_OLD_NC_STATUS */ | |
6389 #define nc_get_nc_status(st) (((int)(st) >= 18) ? 18 : (st)) | |
6390 #endif /* DEFINE_OLD_NC_STATUS */ | |
6391 | |
6392 #if !defined(NTRACE) && defined(TRACING) | |
6393 LOCAL const char * nc_get_nc_state_str(UBYTE status) | |
6394 { | |
6395 return alr_nc_state_trc[nc_get_nc_status(status)]; | |
6396 } | |
6397 #endif /* !NTRACE && TRACING */ | |
6398 #if 0 /* not needed currently */ | |
6399 #if defined(TRACING) | |
6400 /* | |
6401 +--------------------------------------------------------------------+ | |
6402 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
6403 | STATE : code ROUTINE : nc_get_status | | |
6404 +--------------------------------------------------------------------+ | |
6405 | |
6406 PURPOSE : The function returns the status for a channel. | |
6407 | |
6408 */ | |
6409 | |
6410 LOCAL UBYTE nc_get_status (USHORT index) | |
6411 { | |
6412 /* use pointer to save time and ROM */ | |
6413 T_NC* pcell = &alr_data->nc_data.cell[index]; | |
6414 | |
6415 TRACE_USER_CLASS_P3 (TC_USER1, "NC%u[%d] %s", | |
6416 index, | |
6417 pcell->ba_arfcn EQ NOT_PRESENT_16BIT ? -1 : pcell->ba_arfcn&ARFCN_MASK, | |
6418 nc_get_nc_state_str(pcell->status)); | |
6419 | |
6420 return pcell->status; | |
6421 } | |
6422 #endif /* TRACING */ | |
6423 #endif /* 0|1 */ | |
6424 /* | |
6425 +--------------------------------------------------------------------+ | |
6426 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
6427 | STATE : code ROUTINE : nc_set_status | | |
6428 +--------------------------------------------------------------------+ | |
6429 | |
6430 PURPOSE : The function sets a new status for a channel. Depending on | |
6431 the new status several variables which are not valid in | |
6432 the new status are initialised to their default values. | |
6433 | |
6434 | |
6435 */ | |
6436 | |
6437 GLOBAL void nc_set_status (USHORT index, UBYTE new_status) | |
6438 { | |
6439 /* use pointer to save time and ROM */ | |
6440 T_NC* pcell = &alr_data->nc_data.cell[index]; | |
6441 | |
6442 #if defined(TRACING) | |
6443 TRACE_EVENT_P4 ("NC%u[%d] %s -> %s", | |
6444 index, | |
6445 pcell->ba_arfcn EQ NOT_PRESENT_16BIT ? -1 : pcell->ba_arfcn&ARFCN_MASK, | |
6446 nc_get_nc_state_str(pcell->status), | |
6447 nc_get_nc_state_str(new_status)); | |
6448 #endif /* TRACING */ | |
6449 | |
6450 switch (new_status) | |
6451 { | |
6452 case INACTIVE: | |
6453 pcell->bsic = NOT_PRESENT_8BIT; | |
6454 pcell->frame_offset = NOT_PRESENT_32BIT; | |
6455 pcell->time_align = NOT_PRESENT_32BIT; | |
6456 pcell->last_rxlev = 0; | |
6457 pcell->c_rxlev = NOT_PRESENT_8BIT; | |
6458 pcell->rxlev_average = 0; | |
6459 memset (pcell->rxlev, 0, 5); | |
6460 pcell->one_of_six = FALSE; | |
6461 pcell->one_of_twelve = FALSE; | |
6462 pcell->c_attempt = 0; | |
6463 pcell->c_bcch = C_INVALID_BCCH; | |
6464 pcell->c_sync = C_INVALID_SYNC; | |
6465 pcell->tim_valid = TV_INVALID_TIMING_INFO; | |
6466 pcell->blocks_required = 0; | |
6467 pcell->c_error = 0; | |
6468 nc_clean_store_bcch (index); | |
6469 break; | |
6470 | |
6471 case IDLE: | |
6472 pcell->bsic = NOT_PRESENT_8BIT; | |
6473 /* pcell->frame_offset = 0; | |
6474 pcell->time_align = 0; | |
6475 pcell->last_rxlev = 0; */ | |
6476 pcell->one_of_six = FALSE; | |
6477 pcell->one_of_twelve = FALSE; | |
6478 /*pcell->c_attempt = 0;*/ | |
6479 pcell->c_bcch = C_INVALID_BCCH; | |
6480 pcell->c_sync = C_INVALID_SYNC; | |
6481 pcell->blocks_required = 0; | |
6482 pcell->c_error = 0; | |
6483 nc_clean_store_bcch (index); | |
6484 break; | |
6485 | |
6486 case READ_FB_SB: | |
6487 case READ_FB_SB_PENDING: | |
6488 pcell->bsic = NOT_PRESENT_8BIT; | |
6489 /* pcell->frame_offset = 0; | |
6490 pcell->time_align = 0; */ | |
6491 pcell->last_rxlev = 0; | |
6492 pcell->c_bcch = C_INVALID_BCCH; | |
6493 pcell->c_sync = C_INVALID_SYNC; | |
6494 pcell->blocks_required = 0; | |
6495 pcell->c_error = 0; | |
6496 nc_clean_store_bcch (index); | |
6497 break; | |
6498 | |
6499 case READ_BCCH: | |
6500 pcell->last_rxlev = 0; | |
6501 /*pcell->c_attempt = 0;*/ | |
6502 pcell->c_bcch = C_INVALID_BCCH; | |
6503 pcell->c_sync = C_INVALID_SYNC; | |
6504 pcell->c_error = 0; | |
6505 pcell->blocks_required = 0; | |
6506 nc_clean_store_bcch (index); | |
6507 break; | |
6508 case READ_BCCH_RR_NOT_INFORMED: | |
6509 pcell->last_rxlev = 0; | |
6510 pcell->c_bcch = C_INVALID_BCCH; | |
6511 pcell->c_sync = C_INVALID_SYNC; | |
6512 pcell->c_error = 0; | |
6513 pcell->blocks_required = 0; | |
6514 nc_clean_store_bcch (index); | |
6515 break; | |
6516 | |
6517 case FB_SB_SYNC_RR_NOT_INFORMED: | |
6518 pcell->last_rxlev = 0; | |
6519 pcell->c_bcch = C_INVALID_BCCH; | |
6520 pcell->c_sync = C_INVALID_SYNC; | |
6521 pcell->blocks_required = 0; | |
6522 pcell->c_attempt = 0; | |
6523 pcell->c_error = 0; | |
6524 break; | |
6525 | |
6526 case FB_SB_SYNC: | |
6527 pcell->last_rxlev = 0; | |
6528 pcell->blocks_required = 0; | |
6529 if (!pcell->one_of_six) | |
6530 pcell->c_attempt = 0; | |
6531 pcell->c_error = 0; | |
6532 pcell->c_sync = C_INVALID_SYNC; | |
6533 nc_clean_store_bcch (index); | |
6534 break; | |
6535 | |
6536 case READ_SB: | |
6537 case READ_SB_PENDING: | |
6538 pcell->last_rxlev = 0; | |
6539 pcell->c_sync = C_INVALID_SYNC; | |
6540 pcell->blocks_required = 0; | |
6541 /*pcell->c_attempt = 0;*/ | |
6542 pcell->c_error = 0; | |
6543 nc_clean_store_bcch (index); | |
6544 break; | |
6545 | |
6546 case READ_SB_BCCH: | |
6547 case READ_SB_BCCH_PENDING: | |
6548 pcell->last_rxlev = 0; | |
6549 pcell->c_bcch = C_INVALID_BCCH; | |
6550 pcell->c_sync = C_INVALID_SYNC; | |
6551 pcell->blocks_required = 0; | |
6552 pcell->c_error = 0; | |
6553 /*pcell->c_attempt = 0;*/ | |
6554 nc_clean_store_bcch (index); | |
6555 break; | |
6556 | |
6557 | |
6558 case IDLE_SYNC: | |
6559 pcell->last_rxlev = 0; | |
6560 pcell->c_bcch = C_INVALID_BCCH; | |
6561 pcell->one_of_six = FALSE; | |
6562 pcell->one_of_twelve = FALSE; | |
6563 pcell->c_attempt = 0; | |
6564 pcell->blocks_required = 0; | |
6565 pcell->c_error = 0; | |
6566 pcell->c_sync = alr_data->nc_data.c_nc_timer; /*TODO maybe move this to a function*/ | |
6567 nc_clean_store_bcch (index); | |
6568 break; | |
6569 | |
6570 case FB_SB_FAILED: | |
6571 pcell->bsic = NOT_PRESENT_8BIT; | |
6572 if (pcell->status EQ READ_FB_SB_PENDING) | |
6573 { | |
6574 pcell->frame_offset = NOT_PRESENT_32BIT; | |
6575 pcell->time_align = NOT_PRESENT_32BIT; | |
6576 pcell->tim_valid = TV_INVALID_TIMING_INFO; | |
6577 } | |
6578 else | |
6579 pcell->tim_valid = TV_APPROX_TIMING_INFO; | |
6580 pcell->last_rxlev = 0; | |
6581 pcell->c_bcch = C_INVALID_BCCH; | |
6582 pcell->blocks_required = 0; | |
6583 pcell->c_error = 0; | |
6584 nc_clean_store_bcch (index); | |
6585 break; | |
6586 | |
6587 case EXCLUDED: | |
6588 pcell->bsic = NOT_PRESENT_8BIT; | |
6589 pcell->frame_offset = NOT_PRESENT_32BIT; | |
6590 pcell->time_align = NOT_PRESENT_32BIT; | |
6591 pcell->one_of_six = FALSE; | |
6592 pcell->one_of_twelve = FALSE; | |
6593 pcell->last_rxlev = pcell->rxlev_average; /* TODO maybe move this to a function */ | |
6594 pcell->c_attempt = 0; | |
6595 pcell->c_bcch = C_INVALID_BCCH; | |
6596 pcell->c_sync = C_INVALID_SYNC; | |
6597 pcell->tim_valid = TV_INVALID_TIMING_INFO; | |
6598 pcell->blocks_required = 0; | |
6599 pcell->c_error = 0; | |
6600 nc_clean_store_bcch (index); | |
6601 break; | |
6602 | |
6603 case READ_BCCH_PENDING: | |
6604 case READ_BCCH_PENDING_RR_NOT_INFORMED: | |
6605 pcell->last_rxlev = 0; | |
6606 /*pcell->c_attempt = 0;*/ | |
6607 pcell->c_bcch = C_INVALID_BCCH; | |
6608 pcell->c_sync = C_INVALID_SYNC; | |
6609 nc_clean_store_bcch (index); | |
6610 break; | |
6611 } | |
6612 | |
6613 /* | |
6614 * set new status | |
6615 */ | |
6616 pcell->status = new_status; | |
6617 } | |
6618 | |
6619 GLOBAL void nc_check_activity (void) | |
6620 { | |
6621 int i; | |
6622 switch(GET_STATE(STATE_NC)) | |
6623 { | |
6624 case NC_IDLE: | |
6625 /* count number of reports */ | |
6626 alr_data->nc_data.c_reports++; | |
6627 | |
6628 nc_rank_ncells (); | |
6629 nc_check_status (CHECK_FOR_ACQUIRE_AND_BCCH_AND_FAIL); | |
6630 nc_process_status(); | |
6631 | |
6632 if (first_period AND !first_l1_meas) | |
6633 { | |
6634 if (alr_data->nc_data.c_reports EQ alr_data->nc_data.max_reports OR | |
6635 alr_data->nc_data.c_reports EQ alr_data->nc_data.max_reports - 1) | |
6636 { | |
6637 UBYTE all_sync = TRUE; | |
6638 /* | |
6639 * for every ncell | |
6640 */ | |
6641 for (i = 0; i < alr_data->nc_data.c_ba_arfcn; i++) | |
6642 { | |
6643 if (alr_data->nc_data.cell[i].status EQ READ_BCCH_PENDING OR | |
6644 alr_data->nc_data.cell[i].status EQ READ_BCCH_PENDING_RR_NOT_INFORMED) | |
6645 { | |
6646 /* not all needed SI are read yet */ | |
6647 all_sync = FALSE; | |
6648 break; | |
6649 } | |
6650 } | |
6651 if (!all_sync AND | |
6652 alr_data->nc_data.c_reports EQ alr_data->nc_data.max_reports) | |
6653 { | |
6654 /* spend an additional reporting period to give FTA 20.7 a better chance to pass */ | |
6655 alr_data->nc_data.c_reports--; | |
6656 first_period = FALSE; | |
6657 ALR_TRACE_NC ("one additional period"); | |
6658 } | |
6659 else if (all_sync AND | |
6660 alr_data->nc_data.c_reports EQ alr_data->nc_data.max_reports - 1) | |
6661 { | |
6662 /* skip an additional reporting period to give FTA 20.19 a better chance to pass */ | |
6663 alr_data->nc_data.c_reports++; | |
6664 first_period = FALSE; | |
6665 ALR_TRACE_NC ("one period skipped"); | |
6666 } | |
6667 } | |
6668 } | |
6669 first_l1_meas = FALSE; | |
6670 | |
6671 #if defined(_SIMULATION_) | |
6672 TRACE_EVENT_P2 ("c_reports=%u/%u", | |
6673 alr_data->nc_data.c_reports, alr_data->nc_data.max_reports); | |
6674 #endif /* WIN32 */ | |
6675 | |
6676 /* check if 5sec have passed, we then have to inform RR */ | |
6677 if (alr_data->nc_data.c_reports EQ alr_data->nc_data.max_reports) | |
6678 { | |
6679 USHORT index, average; | |
6680 T_NC* pcell; | |
6681 PALLOC (report, MPH_MEASUREMENT_IND); | |
6682 memset (report, 0, sizeof (T_MPH_MEASUREMENT_IND)); | |
6683 | |
6684 first_period = FALSE; | |
6685 #ifdef GPRS | |
6686 report->gprs_sync = NORMAL_MEAS_REP; | |
6687 #endif | |
6688 | |
6689 report->arfcn = alr_data->serving_cell; | |
6690 | |
6691 average = 0; | |
6692 index = nc_get_index(alr_data->serving_cell); | |
6693 if ( index NEQ NOT_PRESENT_16BIT ) | |
6694 { | |
6695 pcell = &alr_data->nc_data.cell[index]; | |
6696 pcell->rxlev_average = 0; /* Is this really needed? */ | |
6697 for (i = 0; i < 5; i++) | |
6698 average += pcell->rxlev[i]; | |
6699 } | |
6700 | |
6701 report->rx_lev_full = (UBYTE) (average / 5); | |
6702 report->fn_offset = alr_data->nc_data.fn_offset; | |
6703 | |
6704 alr_data->nc_data.c_reports = 0; | |
6705 | |
6706 nc_build_rr_report (report); | |
6707 ma_nc_report_res (report); | |
6708 nc_release_bcch (); | |
6709 } | |
6710 break; | |
6711 case NC_DEDICATED: | |
6712 nc_rank_ncells (); | |
6713 nc_check_status (CHECK_FOR_ACQUIRE_AND_BCCH_AND_FAIL); | |
6714 nc_process_status(); | |
6715 { | |
6716 PALLOC(mph_measurement_ind, MPH_MEASUREMENT_IND); | |
6717 #ifdef GPRS | |
6718 mph_measurement_ind->gprs_sync = NORMAL_MEAS_REP; | |
6719 #endif | |
6720 nc_build_rr_report_dedi (mph_measurement_ind); | |
6721 ma_nc_report_res (mph_measurement_ind); | |
6722 } | |
6723 break; | |
6724 default: | |
6725 break; | |
6726 } | |
6727 } | |
6728 | |
6729 /* | |
6730 +--------------------------------------------------------------------+ | |
6731 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
6732 | STATE : code ROUTINE : nc_set_fb_sb_sync_initial | | |
6733 +--------------------------------------------------------------------+ | |
6734 | |
6735 PURPOSE : Inital setting of status FB_SB_SYNC. Counter for SB | |
6736 confirmation and BCCH re-reading are initialized. | |
6737 | |
6738 */ | |
6739 | |
6740 LOCAL void nc_set_fb_sb_sync_initial (USHORT index) | |
6741 { | |
6742 alr_data->nc_data.cell[index].c_bcch = FIVE_MINUTES; | |
6743 | |
6744 if(!alr_data->nc_data.eotd_avail) | |
6745 { | |
6746 /*round to next confirmation boundary */ | |
6747 if(alr_data->nc_data.c_nc_timer NEQ THIRTY_SECONDS) | |
6748 alr_data->nc_data.cell[index].c_bcch += alr_data->nc_data.c_nc_timer; | |
6749 } | |
6750 | |
6751 nc_set_status (index, FB_SB_SYNC); | |
6752 } | |
6753 | |
6754 /* | |
6755 +--------------------------------------------------------------------+ | |
6756 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
6757 | STATE : code ROUTINE : nc_set_fb_sb_failed | | |
6758 +--------------------------------------------------------------------+ | |
6759 | |
6760 PURPOSE : Set the status to FB_SB_FAILED, update the attempt counter | |
6761 and set time until next attempt is started. | |
6762 | |
6763 */ | |
6764 | |
6765 LOCAL void nc_set_fb_sb_failed (USHORT index, | |
6766 UBYTE c_sync) | |
6767 { | |
6768 alr_data->nc_data.cell[index].c_attempt++; | |
6769 alr_data->nc_data.cell[index].c_sync = c_sync; | |
6770 nc_set_status (index, FB_SB_FAILED); | |
6771 } | |
6772 | |
6773 /* | |
6774 +--------------------------------------------------------------------+ | |
6775 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
6776 | STATE : code ROUTINE : nc_rxlev_sc_req | | |
6777 +--------------------------------------------------------------------+ | |
6778 | |
6779 PURPOSE : A new RXLEV value of the serving cell has been measured. | |
6780 Inform GPL in case it is necessary. | |
6781 | |
6782 */ | |
6783 #ifdef GPRS | |
6784 | |
6785 LOCAL void nc_rxlev_sc_req (UBYTE rxlev) | |
6786 { | |
6787 if(GET_STATE (STATE_NC) EQ NC_IDLE) | |
6788 { | |
6789 PALLOC (rxlev_sc_req, TB_RXLEV_SC_REQ); | |
6790 | |
6791 rxlev_sc_req->sc_rxlev = rxlev; | |
6792 | |
6793 ma_nc_rxlev_sc_req (rxlev_sc_req); | |
6794 } | |
6795 } | |
6796 | |
6797 #endif /* #ifdef GPRS */ | |
6798 | |
6799 #if defined(_SIMULATION_) | |
6800 LOCAL void trace_nc(void) | |
6801 { | |
6802 char buf[80]; | |
6803 int i, o; | |
6804 T_NC* pcell; | |
6805 o = sprintf (buf, "NC: "); | |
6806 | |
6807 for (i=0,pcell = &alr_data->nc_data.cell[0]; i < alr_data->nc_data.c_ba_arfcn; i++,pcell++) | |
6808 { | |
6809 if(pcell->ba_arfcn EQ alr_data->serving_cell) | |
6810 { | |
6811 o += sprintf (buf+o, "%u[SC=%u]%u, ", i, pcell->ba_arfcn, pcell->ba_status); | |
6812 } | |
6813 else | |
6814 { | |
6815 o += sprintf (buf+o, "%u[%u]%u, ", i, pcell->ba_arfcn, pcell->ba_status); | |
6816 } | |
6817 if (o > 60) | |
6818 { | |
6819 TRACE_EVENT (buf); | |
6820 o = sprintf (buf, "NC: "); | |
6821 } | |
6822 } | |
6823 if (o>4) | |
6824 { | |
6825 buf[o-2]=0; | |
6826 TRACE_EVENT (buf); | |
6827 } | |
6828 } | |
6829 #endif /* _SIMULATION_ */ | |
6830 | |
6831 /* | |
6832 +--------------------------------------------------------------------+ | |
6833 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
6834 | STATE : code ROUTINE : nc_check_new_strong_cell | | |
6835 +--------------------------------------------------------------------+ | |
6836 | |
6837 PURPOSE : Checks the New strong cell criteria | |
6838 | |
6839 */ | |
6840 | |
6841 LOCAL void nc_check_new_strong_cell(USHORT index, UBYTE o_1of6, | |
6842 UBYTE rxlev) | |
6843 { | |
6844 T_NC* pcell = &alr_data->nc_data.cell[index]; | |
6845 | |
6846 if((pcell->one_of_six ) AND (!o_1of6)) | |
6847 { | |
6848 /* NCELL confirmation active. New 1of6 cell found */ | |
6849 if((pcell->rxlev_average > rxlev) AND | |
6850 ((pcell->rxlev_average - rxlev ) >= 5)) | |
6851 pcell->new_strong_cell = TRUE; | |
6852 } | |
6853 else if ((pcell->one_of_six ) AND (o_1of6) AND | |
6854 (pcell->status EQ READ_FB_SB) AND | |
6855 (pcell->c_attempt EQ 0 )) | |
6856 { | |
6857 /* NCELL confirmation interrupted the sync of last 1of6 cell | |
6858 * This has to be synchronized again | |
6859 */ | |
6860 pcell->new_strong_cell = TRUE; | |
6861 } | |
6862 | |
6863 if(pcell->new_strong_cell) | |
6864 { | |
6865 alr_data->nc_data.new_strong_cell_detect = TRUE; | |
6866 TRACE_EVENT_P1("[%d]New strong cell",pcell->ba_arfcn); | |
6867 } | |
6868 | |
6869 } | |
6870 | |
6871 /* | |
6872 +--------------------------------------------------------------------+ | |
6873 | PROJECT : GSM-PS (6103) MODULE : ALR_NC | | |
6874 | STATE : code ROUTINE : nc_handle_new_strong_cells | | |
6875 +--------------------------------------------------------------------+ | |
6876 | |
6877 PURPOSE : Processes cell synchronisation. | |
6878 | |
6879 */ | |
6880 | |
6881 LOCAL void nc_handle_new_strong_cells(void) | |
6882 { | |
6883 USHORT i; | |
6884 USHORT index; | |
6885 UBYTE first_sync_req = TRUE; | |
6886 T_NC* pbsic = &alr_data->nc_data.cell[LAST_BSIC_REQ]; | |
6887 | |
6888 alr_data->nc_data.c_sync_intrupted = FALSE; | |
6889 | |
6890 while (alr_data->nc_data.c_sync_req < MAX_L1_SYNC_CNT) | |
6891 { | |
6892 /* | |
6893 * It is possible to send more sync requests to layer 1 | |
6894 */ | |
6895 USHORT c_ba_arfcn = alr_data->nc_data.c_ba_arfcn; | |
6896 index = NOT_PRESENT_16BIT; | |
6897 | |
6898 for (i = 0; i < c_ba_arfcn; i++) | |
6899 { | |
6900 /* | |
6901 * search for "New strong cell" with the highest fieldstrength | |
6902 */ | |
6903 T_NC* pcell = &alr_data->nc_data.cell[i]; | |
6904 | |
6905 if ((pcell->ba_arfcn NEQ pbsic->ba_arfcn) AND | |
6906 (pcell->ba_arfcn NEQ alr_data->serving_cell) AND | |
6907 (pcell->new_strong_cell)) | |
6908 { | |
6909 switch (pcell->status) | |
6910 { | |
6911 case READ_FB_SB: | |
6912 if (index EQ NOT_PRESENT_16BIT) | |
6913 index = i; | |
6914 else | |
6915 { | |
6916 if (pcell->rxlev_average > | |
6917 alr_data->nc_data.cell[index].rxlev_average) | |
6918 index = i; | |
6919 } | |
6920 break; | |
6921 default: | |
6922 break; | |
6923 } | |
6924 } | |
6925 } | |
6926 | |
6927 if (index NEQ NOT_PRESENT_16BIT) | |
6928 { | |
6929 | |
6930 if(first_sync_req EQ TRUE) | |
6931 { | |
6932 first_sync_req = FALSE; | |
6933 | |
6934 if(alr_data->nc_data.c_sync_req > 0) | |
6935 { | |
6936 | |
6937 TRACE_EVENT("RE-SYNC interrupted"); | |
6938 alr_data->nc_data.c_sync_intrupted = TRUE; | |
6939 | |
6940 nc_stop_all(); | |
6941 | |
6942 if(!alr_data->nc_data.c_sync_req) | |
6943 { | |
6944 alr_data->nc_data.tim_state = NC_CONF_PENDING; | |
6945 SET_STATE(STATE_NC_PROC, NC_ACQUIRE); | |
6946 } | |
6947 } | |
6948 } /* first_sync_req */ | |
6949 | |
6950 /* | |
6951 * Request synchronisation for this cell | |
6952 */ | |
6953 nc_build_sync_req(index); | |
6954 alr_data->nc_data.cell[index].new_strong_cell = FALSE; | |
6955 TRACE_EVENT_P1("[%d]N_S_C sync req",alr_data->nc_data.cell[index].ba_arfcn); | |
6956 } | |
6957 else | |
6958 break; /*while loop */ | |
6959 } /* while( c_sync_req < MAX_L1_SYNC_CNT) */ | |
6960 } | |
6961 #endif |