FreeCalypso > hg > freecalypso-citrine
comparison g23m-gsm/alr/alr_cbch.c @ 0:75a11d740a02
initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 09 Jun 2016 00:02:41 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:75a11d740a02 |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : GSM-PS | |
4 | Modul : ALR_CBCH | |
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 CBCH_control. | |
18 +----------------------------------------------------------------------------- | |
19 */ | |
20 | |
21 #ifndef ALR_CBCH_C | |
22 #define ALR_CBCH_C | |
23 | |
24 #include "config.h" | |
25 #include "fixedconf.h" | |
26 #include "condat-features.h" | |
27 | |
28 #define ENTITY_PL | |
29 | |
30 /*==== INCLUDES ===================================================*/ | |
31 #include <string.h> | |
32 #include <stdlib.h> | |
33 #include <ctype.h> | |
34 #include "typedefs.h" | |
35 #include "pconst.cdg" | |
36 #include "mconst.cdg" | |
37 #include "message.h" | |
38 #include "ccdapi.h" | |
39 #include "vsi.h" | |
40 #include "custom.h" | |
41 #include "gsm.h" | |
42 #include "prim.h" | |
43 #include "cnf_alr.h" | |
44 #include "mon_alr.h" | |
45 #include "pei.h" | |
46 #include "tok.h" | |
47 | |
48 #include "pcm.h" | |
49 #ifdef GPRS | |
50 #include "alr_gprs.h" | |
51 #endif | |
52 #include "alr.h" | |
53 #include "alr_em.h" | |
54 | |
55 /*==== EXPORT =====================================================*/ | |
56 /*==== PRIVAT =====================================================*/ | |
57 LOCAL void cb_read_cbch (UBYTE flags); | |
58 LOCAL void cb_check_ci_lai_plmn (void); | |
59 LOCAL void cb_remove_message (USHORT i); | |
60 LOCAL void cb_first_block (UBYTE status); | |
61 LOCAL UBYTE* cb_create_schedule_entries (UBYTE* msg_ptr, BOOL read_old_msg); | |
62 LOCAL void cb_create_schedule_map (UBYTE old_cb_msg); | |
63 LOCAL UBYTE cb_check_old_msg (void); | |
64 LOCAL UBYTE cb_check_data_coding_scheme(UBYTE dcs_id); | |
65 LOCAL UBYTE cb_check_message_id (USHORT msg_id); | |
66 LOCAL void cb_store_cbch_msg (void); | |
67 LOCAL void cb_error_ind (void); | |
68 LOCAL void cb_cbch_message (UBYTE length); | |
69 LOCAL void cb_null_message (void); | |
70 LOCAL void cb_schedule_message (void); | |
71 LOCAL void cb_next_scheduled_msg (void); | |
72 LOCAL UBYTE cb_sat_check_message_id (USHORT msg_id); | |
73 LOCAL void cb_sat_cbch_message (UBYTE length); | |
74 LOCAL void cb_stop_next_blocks (void); | |
75 LOCAL void cb_read_next_3_blocks(void); | |
76 void set_cbch_state( UBYTE extended, UBYTE new_state); | |
77 UBYTE get_cbch_state( UBYTE extended); | |
78 | |
79 #if defined(FF_HOMEZONE) | |
80 LOCAL UBYTE cb_check_homezone (UBYTE length); | |
81 #endif /* FF_HOMEZONE */ | |
82 | |
83 LOCAL void cb_alr_trace_msghead (T_CBMSG_HEADER *ph); | |
84 | |
85 /* | |
86 * support indication of geographical scope change to MMI | |
87 * it is important that these defitions match the GS definition from GSM 03.41 | |
88 * the MMI uses this also to compare with real CBCH messages! | |
89 */ | |
90 #define CB_GEOGR_CHANGE_NONE 0x00 | |
91 #define CB_GEOGR_CHANGE_CELL 0xC0 | |
92 #define CB_GEOGR_CHANGE_LAC 0x80 | |
93 #define CB_GEOGR_CHANGE_PLMN 0x40 | |
94 | |
95 #define CB_GEOGR_SCOPE_CELLI 0x00 | |
96 #define CB_GEOGR_SCOPE_PLMN 0x01 | |
97 #define CB_GEOGR_SCOPE_LAC 0x02 | |
98 #define CB_GEOGR_SCOPE_CELLN 0x03 | |
99 | |
100 #define CBCH_NO_MSG 0 | |
101 #define CBCH_NORM_MSG 1 | |
102 #define CBCH_SCHEDULE_MSG 2 | |
103 #define CBCH_SAT_MSG 3 | |
104 #define CBCH_LAST_BLOCK 0x10 | |
105 | |
106 #define CBCH_BLOCK_0 0 | |
107 #define CBCH_BLOCK_1 1 | |
108 #define CBCH_BLOCK_2 2 | |
109 #define CBCH_BLOCK_3 3 | |
110 #define CBCH_FIRST_SCHED_MSG 8 | |
111 #define CBCH_NULL_MSG 0x0F | |
112 #define CBCH_SCHED 2 | |
113 | |
114 #define MAX_UPDATE_NO 16 | |
115 #define MAX_UPDATE_NO_DIFF 8 | |
116 | |
117 #if 1 || defined (WIN32) | |
118 #define TRACING | |
119 #endif | |
120 | |
121 #define CB_SERIAL_NO(ph) ((USHORT)\ | |
122 ((((T_CBMSG_HEADER*)(ph))->serial_no1)<<8)+\ | |
123 (((T_CBMSG_HEADER*)(ph))->serial_no2)) | |
124 | |
125 #define CB_GS_CODE(ph) (((UBYTE)(((T_CBMSG_HEADER*)(ph))->serial_no1))>>6) | |
126 | |
127 #define CB_MSG_CODE(ph) ((USHORT)\ | |
128 (((((T_CBMSG_HEADER*)(ph))->serial_no1)&0x3f)<<4)+\ | |
129 ((((T_CBMSG_HEADER*)(ph))->serial_no2)>>4)) | |
130 | |
131 #define CB_UPDATE_NO(ph) ((((T_CBMSG_HEADER*)(ph))->serial_no2)&0x0f) | |
132 | |
133 #define CB_MESSAGE_ID(ph) ((USHORT)\ | |
134 ((((T_CBMSG_HEADER*)(ph))->msg_id3)<<8)+\ | |
135 (((T_CBMSG_HEADER*)(ph))->msg_id4)) | |
136 #if 0 | |
137 #define CB_MESSAGE_ID(ph) ((((USHORT)(((T_CBMSG_HEADER*)(ph))->msg_id3))<<8)+\ | |
138 ((USHORT)(((T_CBMSG_HEADER*)(ph))->msg_id4))) | |
139 | |
140 #endif /* 0 */ | |
141 #define CB_DCS(ph) (((T_CBMSG_HEADER*)(ph))->dcs) | |
142 | |
143 #define CB_PAGE(ph) (((T_CBMSG_HEADER*)(ph))->page>>4) | |
144 #define CB_PAGETOTAL(ph) (((T_CBMSG_HEADER*)(ph))->page&0x0f) | |
145 | |
146 | |
147 #if defined (TRACING) | |
148 #define ALR_TRACE_CB(a) TRACE_EVENT("CBCH: " a) | |
149 #define ALR_TRACE_CB_MODUS(m) TRACE_EVENT_P1("CBCH: modus=%d", m) | |
150 #define ALR_TRACE_CB_ERROR(e) TRACE_EVENT_P1("CBCH: error=%d", e) | |
151 #define ALR_TRACE_CB_BLOCK_NO(b) TRACE_EVENT_P2("CBCH: block=%02x no=%u", b, b&0x0f) | |
152 #define ALR_TRACE_CB_MSGHEAD(ph) cb_alr_trace_msghead(ph) | |
153 | |
154 #define ALR_TRACE_CB_MSGID(m) TRACE_EVENT_P1("CBCH: ID=%u", m) | |
155 #define ALR_TRACE_CB_START_READ(f) TRACE_EVENT_P1("CBCH: Start Read %d", f) | |
156 #define ALR_TRACE_CB_SCHEDULE(a1,a2) TRACE_EVENT_P2("CBCH: schedule i=%d result=%d", a1,a2) | |
157 #define ALR_TRACE_CB_HZREQ(a1,a2) TRACE_EVENT_P2("CBCH: Homezone ID=%u, t=%u", a1,a2) | |
158 #define ALR_TRACE_CB_SCOPE_CHANGE(i,s) TRACE_EVENT_P2 ("CBCH: Geogr. scope change %u, deleting msg of scope %u",\ | |
159 i,s); | |
160 #else /* TRACING */ | |
161 #define ALR_TRACE_CB(a) | |
162 #define ALR_TRACE_CB_MODUS(m) | |
163 #define ALR_TRACE_CB_ERROR(e) | |
164 #define ALR_TRACE_CB_BLOCK_NO(b) | |
165 #define ALR_TRACE_CB_MSGID(m) | |
166 #define ALR_TRACE_CB_START_READ(f) | |
167 #define ALR_TRACE_CB_SCHEDULE(a1,a2) | |
168 #define ALR_TRACE_CB_HZREQ(a1,a2) | |
169 #endif /* TRACING */ | |
170 | |
171 /*==== VARIABLES ==================================================*/ | |
172 /*==== FUNCTIONS ==================================================*/ | |
173 | |
174 #if 0 | |
175 #if 0 | |
176 #define TRACE_ALIGN_P(ps,m,t) TRACE_EVENT_P5(" %08x %3u.%u %08x=%u " \ | |
177 "T_" #t " " #m, \ | |
178 (BYTE*)&(m), (BYTE*)&(m)-(BYTE*)ps, \ | |
179 sizeof (m), | |
180 sizeof (m) > 1 ? (USHORT)(m) : (UBYTE)(m), m \ | |
181 ) | |
182 #else | |
183 #define TRACE_ALIGN_P(ps,m,t) TRACE_EVENT_P4 (" %08x %3u.%u %08x " \ | |
184 "T_" #t " " #m, \ | |
185 (BYTE*)&(m), (BYTE*)&(m)-(BYTE*)ps, \ | |
186 sizeof (m), m\ | |
187 ) | |
188 #endif | |
189 int test_alignment (T_CBMSG_HEADER *ph) | |
190 { | |
191 TRACE_ALIGN_P (ph, ph->serial_no1, CBMSG_HEADER); | |
192 TRACE_ALIGN_P (ph, ph->serial_no2, CBMSG_HEADER); | |
193 TRACE_ALIGN_P (ph, ph->msg_id3, CBMSG_HEADER); | |
194 TRACE_ALIGN_P (ph, ph->msg_id4, CBMSG_HEADER); | |
195 TRACE_ALIGN_P (ph, ph->dcs, CBMSG_HEADER); | |
196 TRACE_ALIGN_P (ph, ph->page, CBMSG_HEADER); | |
197 } | |
198 #endif | |
199 | |
200 /* | |
201 +--------------------------------------------------------------------+ | |
202 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
203 | STATE : code ROUTINE : cb_init | | |
204 +--------------------------------------------------------------------+ | |
205 | |
206 PURPOSE : Initialize CBCH Control Process. | |
207 */ | |
208 | |
209 GLOBAL void cb_init (void) | |
210 { | |
211 GET_INSTANCE_DATA; | |
212 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
213 | |
214 ALR_TRACE_CB ("cb_init()"); | |
215 alr_data->state[STATE_NORMAL_CBCH] = CBCH_NULL; | |
216 alr_data->state[STATE_EXT_CBCH] = CBCH_NULL; | |
217 pcbch->modus = NOT_PRESENT_8BIT; | |
218 pcbch->old_cbch_msg.cnt = 0; | |
219 #if defined(FF_HOMEZONE) | |
220 pcbch->homezone = CBCH_HZ_OFF; | |
221 pcbch->hz_timeout = 0; | |
222 #endif /* FF_HOMEZONE */ | |
223 } | |
224 | |
225 /* | |
226 +--------------------------------------------------------------------+ | |
227 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
228 | STATE : code ROUTINE : cb_stop | | |
229 +--------------------------------------------------------------------+ | |
230 | |
231 PURPOSE : Stop CBCH Control Process. | |
232 | |
233 cb_stop will be called in the following three scenarios - | |
234 1. Moving from IDLE to DEDICATED state | |
235 2. ALR has received HomeZone information. | |
236 3. MMI indicates stop reading CBCH. | |
237 | |
238 In all three cases ALR need to forward this to L1. | |
239 Eventhough the homezone request is pending we need to stop | |
240 the CBCH reading. | |
241 */ | |
242 | |
243 GLOBAL void cb_stop (void) | |
244 { | |
245 GET_INSTANCE_DATA; | |
246 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
247 UBYTE normal_cbch, extended_cbch; | |
248 | |
249 normal_cbch = GET_STATE(STATE_NORMAL_CBCH); | |
250 extended_cbch = GET_STATE(STATE_EXT_CBCH); | |
251 | |
252 if ( | |
253 (normal_cbch NEQ CBCH_NULL AND normal_cbch NEQ CBCH_IDLE) | |
254 OR | |
255 (extended_cbch NEQ CBCH_NULL AND extended_cbch NEQ CBCH_IDLE) | |
256 ) | |
257 { | |
258 /* | |
259 * if CBCH process is really active, initialize | |
260 * CBCH process and stop CBCH process in layer 1. | |
261 */ | |
262 pcbch->msg_type = CBCH_NO_MSG; | |
263 | |
264 SET_STATE(STATE_NORMAL_CBCH, CBCH_IDLE); | |
265 SET_STATE(STATE_EXT_CBCH, CBCH_IDLE); | |
266 | |
267 ALR_EM_STOP_CBCH_READING; | |
268 | |
269 ma_cb_stop_cbch_req(); | |
270 } | |
271 } | |
272 | |
273 | |
274 /* | |
275 +--------------------------------------------------------------------+ | |
276 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
277 | STATE : code ROUTINE : cb_start | | |
278 +--------------------------------------------------------------------+ | |
279 | |
280 PURPOSE : Re-configure layer 1 and go back to CBCH reading without | |
281 scheduling information. | |
282 */ | |
283 | |
284 LOCAL void cb_start_no_drx_reading (UBYTE config) | |
285 { | |
286 GET_INSTANCE_DATA; | |
287 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
288 | |
289 if (config) | |
290 { | |
291 /* | |
292 * configure layer 1 | |
293 */ | |
294 PALLOC (config_cbch, MPHC_CONFIG_CBCH_REQ); | |
295 | |
296 /* | |
297 * copy the stored configuration received earlier from RR and send to layer 1. | |
298 */ | |
299 memcpy (config_cbch, &pcbch->mphc_config_cbch, sizeof (T_MPHC_CONFIG_CBCH_REQ)); | |
300 ma_cb_config_cbch(config_cbch); | |
301 } | |
302 | |
303 /* | |
304 * start reading in layer 1 for normal and extended CBCH. | |
305 * The initial mode is no Scheduling information available. | |
306 */ | |
307 cb_read_cbch (CBCH_NO_SCHED | CBCH_READ_NORM); | |
308 cb_read_cbch (CBCH_NO_SCHED | CBCH_READ_EXT); | |
309 | |
310 SET_STATE(STATE_NORMAL_CBCH, CBCH_NO_DRX); | |
311 SET_STATE(STATE_EXT_CBCH, CBCH_NO_DRX); | |
312 | |
313 #if defined(FF_HOMEZONE) | |
314 if (pcbch->homezone EQ CBCH_HZ_IDLE) | |
315 { | |
316 pcbch->homezone = CBCH_HZ_PENDING; | |
317 /* start timer new */ | |
318 if (pcbch->hz_timeout) | |
319 TIMERSTART(TIM_HOMEZONE, pcbch->hz_timeout); | |
320 ALR_TRACE_CB ("HOMEZONE is pending"); | |
321 } | |
322 #endif /* FF_HOMEZONE */ | |
323 } | |
324 | |
325 /* | |
326 +--------------------------------------------------------------------+ | |
327 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
328 | STATE : code ROUTINE : cb_start | | |
329 +--------------------------------------------------------------------+ | |
330 | |
331 PURPOSE : Start CBCH Control Process. | |
332 */ | |
333 | |
334 GLOBAL void cb_start (void) | |
335 { | |
336 GET_INSTANCE_DATA; | |
337 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
338 | |
339 if ( (GET_STATE(STATE_NORMAL_CBCH) EQ CBCH_IDLE) | |
340 AND ( (pcbch->modus NEQ NOT_PRESENT_8BIT) | |
341 OR (pcbch->sat_enabled) | |
342 #if defined(FF_HOMEZONE) | |
343 OR (pcbch->homezone EQ CBCH_HZ_IDLE) | |
344 #endif /* FF_HOMEZONE */ | |
345 ) | |
346 ) | |
347 { | |
348 /* | |
349 * if a definition of needed message identifiers | |
350 * and data coding schemes is available, then configure | |
351 * layer 1 | |
352 */ | |
353 ALR_TRACE_CB ("restart"); | |
354 cb_start_no_drx_reading (TRUE); | |
355 } | |
356 } | |
357 | |
358 /* | |
359 +--------------------------------------------------------------------+ | |
360 | PROJECT : GSM-PS (6103) MODULE : TIL_CBCH | | |
361 | STATE : code ROUTINE : cb_mph_cbch_req | | |
362 +--------------------------------------------------------------------+ | |
363 | |
364 PURPOSE : Configuration of the layer 1 process for CBCH. | |
365 | |
366 The compile-switch is not defined with the standard TI-layer 1. | |
367 | |
368 But there shall be a little modification possible (and it is | |
369 done by some source code customer of layer 1), which does not | |
370 need any storing in ALR. Then the compile switch must be set | |
371 | |
372 REMARK : Setting of compile switch has problems with function cbch_start ??? | |
373 | |
374 */ | |
375 | |
376 GLOBAL void cb_mph_cbch_req (T_cbch * cbch) | |
377 { | |
378 GET_INSTANCE_DATA; | |
379 USHORT i; | |
380 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
381 T_cbch_desc *pcbch_desc = &pcbch->mphc_config_cbch.cbch_desc; | |
382 T_chan_sel *pchan_sel = &pcbch_desc->chan_sel; | |
383 T_cbch_freq_list *pcbch_freq_list = &pcbch->mphc_config_cbch.cbch_freq_list; | |
384 | |
385 ALR_TRACE_CB ("MPH_CBCH_REQ"); | |
386 | |
387 ALR_EM_CONFIGURE_CBCH_CHANNEL; | |
388 | |
389 #if defined(FF_HOMEZONE) | |
390 if (pcbch->homezone NEQ CBCH_HZ_OFF) | |
391 pcbch->homezone = CBCH_HZ_IDLE; /* starts HZ request again */ | |
392 #endif /* FF_HOMEZONE */ | |
393 | |
394 /* check which messages have to be deleted | |
395 * even if the new cell has CBCH disabled! We still need to | |
396 * to delete the corresponding messages and inform the MMI! | |
397 */ | |
398 if (pcbch->modus EQ CBCH_ACCEPT) | |
399 cb_check_ci_lai_plmn (); | |
400 | |
401 if (cbch->stat EQ STAT_ACT) | |
402 { | |
403 /* | |
404 * A CBCH channel is available | |
405 */ | |
406 | |
407 #if !defined (L1_STORES_CBCH_CONFIG) | |
408 /* | |
409 * Layer 1 does not store any CBCH configuration (default) | |
410 * first set the channel configuration | |
411 */ | |
412 if (cbch->h EQ H_FREQ) | |
413 { | |
414 /* | |
415 * with frequency hopping, set hopping flag, maio, hsn and hopping list. | |
416 */ | |
417 pchan_sel->h = HOPPING; | |
418 pchan_sel->rf_channel.maio = cbch->maio; | |
419 pchan_sel->rf_channel.hsn = cbch->hsn; | |
420 | |
421 i=0; | |
422 pcbch_freq_list->rf_chan_cnt=0; | |
423 while ((i < 64) AND (cbch->ma[i] NEQ NOT_PRESENT_16BIT)) | |
424 { | |
425 pcbch_freq_list->rf_chan_no.radio_freq[i] = ARFCN_TO_L1(cbch->ma[i]); | |
426 i++; | |
427 pcbch_freq_list->rf_chan_cnt++; | |
428 } | |
429 } | |
430 else | |
431 { | |
432 /* | |
433 * Layer 1 uses a union definition. This is not applicable for the Condat-SAP model. | |
434 * Therefore the rf channel number is configured by maio and hsn. In general a Avoid the union !!! | |
435 */ | |
436 pchan_sel->h = NO_HOPPING; | |
437 pchan_sel->rf_channel.maio = (UBYTE)(ARFCN_TO_L1(cbch->arfcn) & 0xFF); | |
438 pchan_sel->rf_channel.hsn = (UBYTE)((ARFCN_TO_L1(cbch->arfcn) >> 8) & 0xFF); | |
439 memset (pcbch_freq_list, 0, sizeof (T_cbch_freq_list)); | |
440 } | |
441 | |
442 /* | |
443 * configure the CBCH channel type (SDCCH/8 or SDCCH/4) | |
444 */ | |
445 if (cbch->ch < CH_SDCCH_8_0) | |
446 pcbch_desc->channel_type = CH_SDCCH_4; | |
447 else | |
448 pcbch_desc->channel_type = CH_SDCCH_8; | |
449 | |
450 pcbch_desc->sub_channel = 0; /* not relevant */ | |
451 pcbch_desc->timeslot_no = cbch->tn; | |
452 pcbch_desc->tsc = cbch->tsc; | |
453 | |
454 #else | |
455 /* | |
456 * Compile option set: L1 stores actual CBCH configuration. | |
457 * So it is not necessary to store the configuration in ALR. | |
458 * Just parse the configuration to Layer 1. | |
459 */ | |
460 { | |
461 PALLOC (config_cbch, MPHC_CONFIG_CBCH); | |
462 | |
463 if (cbch->h EQ H_FREQ) | |
464 { | |
465 /* | |
466 * with frequency hopping, set hopping flag, maio, hsn and hopping list. | |
467 */ | |
468 config_cbch->cbch_desc.chan_sel.h = HOPPING; | |
469 config_cbch->cbch_desc.chan_sel.rf_channel.maio = cbch->maio; | |
470 config_cbch->cbch_desc.chan_sel.rf_channel.hsn = cbch->hsn; | |
471 | |
472 i=0; | |
473 config_cbch->cbch_freq_list.rf_chan_cnt=0; | |
474 while (cbch->ma[i] NEQ NOT_PRESENT_16BIT AND i < 64) | |
475 { | |
476 config_cbch->cbch_freq_list.rf_chan_no.hop_chan[i] = ARFCN_TO_L1(cbch->ma[i]); | |
477 i++; config_cbch->cbch_freq_list.rf_chan_cnt++; | |
478 } | |
479 } | |
480 else | |
481 { | |
482 /* | |
483 * Layer 1 uses a union definition. This is not applicable for the Condat-SAP model. | |
484 * Therefore the rf channel number is configured by maio and hsn. In general a Avoid the union !!! | |
485 */ | |
486 config_cbch->cbch_desc.chan_sel.h = NO_HOPPING; | |
487 config_cbch->cbch_desc.chan_sel.rf_channel.maio = ARFCN_TO_L1(cbch->arfcn) & 0xFF; | |
488 config_cbch->cbch_desc.chan_sel.rf_channel.hsn = (ARFCN_TO_L1(cbch->arfcn) >> 8) & 0xFF; | |
489 memset (&config_cbch->cbch_freq_list, 0, sizeof (T_cbch_freq_list)); | |
490 } | |
491 | |
492 /* | |
493 * configure the CBCH channel type (SDCCH/8 or SDCCH/4) | |
494 */ | |
495 if (cbch->ch < CH_SDCCH_8_0) | |
496 config_cbch->cbch_desc.channel_type = CH_SDCCH_4; | |
497 else | |
498 config_cbch->cbch_desc.channel_type = CH_SDCCH_8; | |
499 | |
500 config_cbch->cbch_desc.sub_channel = 0; /* not relevant */ | |
501 config_cbch->cbch_desc.timeslot_no = cbch->tn; | |
502 config_cbch->cbch_desc.tsc = cbch->tsc; | |
503 | |
504 ma_cb_config_cbch(config_cbch); | |
505 } | |
506 #endif | |
507 | |
508 if ( (pcbch->modus NEQ NOT_PRESENT_8BIT) | |
509 OR (pcbch->sat_enabled) | |
510 #if defined(FF_HOMEZONE) | |
511 OR (pcbch->homezone EQ CBCH_HZ_IDLE) | |
512 #endif /* FF_HOMEZONE */ | |
513 ) | |
514 { | |
515 /* | |
516 * MMI has requested data | |
517 * Start with NO_DRX mode | |
518 * Read each first CBCH block | |
519 */ | |
520 #if defined (L1_STORES_CBCH_CONFIG) | |
521 cb_start_no_drx_reading (FALSE); | |
522 #else /* L1_STORES_CBCH_CONFIG */ | |
523 ALR_TRACE_CB ("switch on, send config"); | |
524 cb_start_no_drx_reading (TRUE); | |
525 #endif /* L1_STORES_CBCH_CONFIG */ | |
526 } | |
527 else | |
528 { | |
529 UBYTE *si3 = &alr_data->ma_data.sys_info_3[0]; | |
530 UBYTE *lac = &alr_data->cbch_data.old_cid_plmn_lac[0]; | |
531 | |
532 ALR_TRACE_CB ("switch on, wait for MMI"); | |
533 /* | |
534 * wait for MMI request | |
535 */ | |
536 SET_STATE(STATE_NORMAL_CBCH, CBCH_IDLE); | |
537 SET_STATE(STATE_EXT_CBCH, CBCH_IDLE); | |
538 /* | |
539 * update old_cid_plmn_lac | |
540 */ | |
541 memcpy (lac, &si3[2], 7); | |
542 } | |
543 } | |
544 else | |
545 { | |
546 /* | |
547 * The new configuration indicates no CBCH, so stop the CBCH process in Layer 1 | |
548 */ | |
549 ALR_TRACE_CB ("switch off"); | |
550 | |
551 cb_stop(); | |
552 SET_STATE(STATE_NORMAL_CBCH, CBCH_NULL); | |
553 SET_STATE(STATE_EXT_CBCH, CBCH_NULL); | |
554 } | |
555 } | |
556 | |
557 /* | |
558 +--------------------------------------------------------------------+ | |
559 | PROJECT : GSM-PS (6103) MODULE : AKR_CBCH | | |
560 | STATE : code ROUTINE : cb_mmi_cbch_req | | |
561 +--------------------------------------------------------------------+ | |
562 | |
563 PURPOSE : MMI sends a definition of the expected message identifier | |
564 and data coding schemes for the CBCH messages. | |
565 | |
566 */ | |
567 | |
568 GLOBAL void cb_mmi_cbch_req (T_MMI_CBCH_REQ *cbch) | |
569 { | |
570 GET_INSTANCE_DATA; | |
571 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
572 ALR_TRACE_CB ("MMI req"); | |
573 | |
574 #if defined(FF_HOMEZONE) | |
575 if (cbch->modus NEQ CBCH_HOMEZONE) | |
576 { | |
577 pcbch->modus = cbch->modus; | |
578 TRACE_EVENT_P1 ("CBCH: homezone=%u", pcbch->homezone); | |
579 } | |
580 else if (cbch->msg_id[0] EQ NOT_PRESENT_16BIT) | |
581 { | |
582 /* | |
583 * switch off automatically homezone request | |
584 * - homezone state to off | |
585 * - clear old message | |
586 * - stop timer | |
587 */ | |
588 pcbch->msg_hz_id = NOT_PRESENT_16BIT; | |
589 pcbch->homezone = CBCH_HZ_OFF; | |
590 TIMERSTOP (TIM_HOMEZONE); | |
591 } | |
592 else | |
593 { | |
594 /* | |
595 * switch on automatically homezone request | |
596 * - set homezone state to idle whatever are before | |
597 * - set new homezone id | |
598 * - clear old message | |
599 */ | |
600 pcbch->msg_hz_id = cbch->msg_id[0]; | |
601 pcbch->dcs_hz_id = cbch->dcs_id[0]; | |
602 pcbch->hz_timeout = cbch->dcs_id[1]*1000; | |
603 ALR_TRACE_CB_HZREQ (pcbch->msg_hz_id, | |
604 pcbch->hz_timeout); | |
605 if (pcbch->homezone EQ CBCH_HZ_OFF) | |
606 { | |
607 UBYTE cbch_state = GET_STATE (STATE_NORMAL_CBCH); | |
608 pcbch->homezone = CBCH_HZ_IDLE; | |
609 if (cbch_state NEQ CBCH_NULL) | |
610 {/* CBCH system is prepared */ | |
611 if (cbch_state EQ CBCH_IDLE) | |
612 { /* start timer only if CBCH system is prepared */ | |
613 TIMERSTART (TIM_HOMEZONE, 1000); | |
614 } | |
615 else | |
616 { /* CBCH system is already active -> wait for HZ message */ | |
617 pcbch->homezone = CBCH_HZ_PENDING; | |
618 TIMERSTART (TIM_HOMEZONE, pcbch->hz_timeout); | |
619 ALR_TRACE_CB ("HOMEZONE is pending"); | |
620 } | |
621 } | |
622 } | |
623 return; | |
624 } | |
625 #else /* FF_HOMEZONE */ | |
626 pcbch->modus = cbch->modus; | |
627 #endif /* FF_HOMEZONE */ | |
628 /* | |
629 * Storing of Parameter and clearing of | |
630 * the received CB memory | |
631 */ | |
632 memcpy (&pcbch->msg_id[0], cbch->msg_id, sizeof (pcbch->msg_id)); | |
633 memcpy (&pcbch->dcs_id[0], cbch->dcs_id, sizeof (pcbch->dcs_id)); | |
634 | |
635 #if !defined(NTRACE) | |
636 { | |
637 int i; | |
638 | |
639 ALR_TRACE_CB_MODUS(cbch->modus); | |
640 | |
641 for (i=0; | |
642 (i < MAX_IDENTS) AND (pcbch->msg_id[i] NEQ NOT_PRESENT_16BIT); | |
643 i++) | |
644 { | |
645 TRACE_EVENT_P2 ("CBCH: id[%u]=%u", i, pcbch->msg_id[i]); | |
646 } | |
647 for (i=0; | |
648 (i < MAX_IDENTS) AND (pcbch->dcs_id[i] NEQ NOT_PRESENT_8BIT); | |
649 i++) | |
650 { | |
651 TRACE_EVENT_P2 ("CBCH:dcs[%u]=%u", i, pcbch->dcs_id[i]); | |
652 } | |
653 } | |
654 #endif /* !NTRACE */ | |
655 | |
656 /* old messages should only be erased when MMI turns CBCH off */ | |
657 if (pcbch->modus EQ MMI_CBCH_STOP) | |
658 { | |
659 /* also erases the count of old message */ | |
660 memset (&pcbch->old_cbch_msg, 0, sizeof (T_CB_MSG)); | |
661 memset (&pcbch->msg[0], 0, CBCH_MSG_SIZE); | |
662 } | |
663 | |
664 /* | |
665 TRACE_EVENT_P2 ("CBCH: STATE_MA=%u STATE_CBCH=%u", GET_STATE(STATE_MA), GET_STATE (STATE_CBCH)); | |
666 */ | |
667 | |
668 #ifdef GPRS | |
669 if ((GET_STATE(STATE_MA) EQ MA_IDLE AND !alr_data->gprs_data.pbcch) OR | |
670 (alr_data->gprs_data.pbcch AND alr_data->gprs_data.pim)) | |
671 #else | |
672 if (GET_STATE(STATE_MA) EQ MA_IDLE) | |
673 #endif | |
674 { | |
675 /* | |
676 * layer 1 is only configured, if ALR is in idle state, else the configuration | |
677 * is delayed until the cell is selected. | |
678 */ | |
679 switch (GET_STATE (STATE_NORMAL_CBCH)) | |
680 { | |
681 case CBCH_NULL: | |
682 /* | |
683 * no CBCH channel is available | |
684 */ | |
685 break; | |
686 | |
687 case CBCH_IDLE: | |
688 if (pcbch->modus EQ MMI_CBCH_STOP AND | |
689 !pcbch->sat_enabled) | |
690 { | |
691 /* | |
692 * CBCH download is not enabled and the MMI indicates stop of | |
693 * the CBCH channel, then stop CBCH process in layer 1. | |
694 */ | |
695 cb_stop(); | |
696 } | |
697 else | |
698 { | |
699 /* | |
700 * new definitions of message identifier or data coding schemes | |
701 * then re-configure layer 1 and go back to CBCH reading without | |
702 * scheduling information. | |
703 */ | |
704 cb_start_no_drx_reading (TRUE); | |
705 } | |
706 break; | |
707 | |
708 default: | |
709 /* | |
710 * we already received a MMI CBCH REQ before | |
711 */ | |
712 if (pcbch->modus EQ MMI_CBCH_STOP AND | |
713 !pcbch->sat_enabled) | |
714 { | |
715 /* | |
716 * CBCH download is not enabled and the MMI indicates stop of | |
717 * the CBCH channel, then stop CBCH process in layer 1. | |
718 */ | |
719 cb_stop(); | |
720 SET_STATE(STATE_NORMAL_CBCH, CBCH_IDLE); | |
721 SET_STATE(STATE_EXT_CBCH, CBCH_IDLE); | |
722 } | |
723 break; | |
724 } | |
725 } | |
726 } | |
727 | |
728 /* | |
729 +--------------------------------------------------------------------+ | |
730 | PROJECT : GSM-PS (6103) MODULE : TIL_CBCH | | |
731 | STATE : code ROUTINE : cb_mmi_sat_cbch_req | | |
732 +--------------------------------------------------------------------+ | |
733 | |
734 PURPOSE : Reception of a list of identifiers for SIM TOOLKIT | |
735 CBCH Download. | |
736 | |
737 */ | |
738 | |
739 GLOBAL void cb_mmi_sat_cbch_req (T_MMI_SAT_CBCH_DWNLD_REQ * cbch_req) | |
740 { | |
741 GET_INSTANCE_DATA; | |
742 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
743 unsigned i; | |
744 ALR_TRACE_CB ("MMI SAT req"); | |
745 | |
746 /* | |
747 * clear the list of needed message identifier for CBCH download | |
748 * and fill it with the definiton of MMI. | |
749 */ | |
750 memset (pcbch->msg_id_sat, NOT_PRESENT_16BIT, | |
751 sizeof(pcbch->msg_id_sat)); | |
752 memcpy (pcbch->msg_id_sat, cbch_req->msg_id, | |
753 sizeof(cbch_req->msg_id[0])*(cbch_req->count)); | |
754 | |
755 /* | |
756 * CBCH download is disabled | |
757 */ | |
758 pcbch->sat_enabled = FALSE; | |
759 for (i = 0; i < cbch_req->count; i++) | |
760 { | |
761 if (pcbch->msg_id_sat[i] NEQ NOT_PRESENT_16BIT) | |
762 { | |
763 pcbch->sat_enabled = TRUE; | |
764 break; | |
765 } | |
766 } | |
767 vsi_o_error_ttrace ("HM cb_mmi_sat_cbch_req(), sat_enabled = %d, modus = %d", | |
768 pcbch->sat_enabled, pcbch->modus); | |
769 #ifdef GPRS | |
770 if ((GET_STATE(STATE_MA) EQ MA_IDLE AND !alr_data->gprs_data.pbcch) OR | |
771 (alr_data->gprs_data.pbcch AND alr_data->gprs_data.pim)) | |
772 #else | |
773 if (GET_STATE(STATE_MA) EQ MA_IDLE) | |
774 #endif | |
775 { | |
776 /* | |
777 * Current state is compatible with enabling of CBCH reading, | |
778 * configure L1 to read CBCH. Otherwise configuration is delayed | |
779 * until ALR reaches a compatible state. | |
780 */ | |
781 switch (GET_STATE (STATE_NORMAL_CBCH)) | |
782 { | |
783 case CBCH_NULL: | |
784 /* | |
785 * No CBCH channel is available. | |
786 */ | |
787 break; | |
788 | |
789 default: | |
790 { | |
791 if (pcbch->modus EQ MMI_CBCH_STOP AND !pcbch->sat_enabled) | |
792 { | |
793 /* No CBCH to read. Stop reading CBCH in L1. */ | |
794 cb_stop(); | |
795 } | |
796 else | |
797 { | |
798 | |
799 /* | |
800 * CBCH channel is available. | |
801 * Configure layer 1 for catching the CBCH download messages. | |
802 */ | |
803 PALLOC (config_cbch, MPHC_CONFIG_CBCH_REQ); | |
804 memcpy (config_cbch, &pcbch->mphc_config_cbch, sizeof (T_MPHC_CONFIG_CBCH_REQ)); | |
805 ma_cb_config_cbch(config_cbch); | |
806 cb_read_cbch (CBCH_NO_SCHED | CBCH_READ_NORM); | |
807 cb_read_cbch (CBCH_NO_SCHED | CBCH_READ_EXT); | |
808 SET_STATE(STATE_NORMAL_CBCH, CBCH_NO_DRX); | |
809 SET_STATE(STATE_EXT_CBCH, CBCH_NO_DRX); | |
810 } | |
811 } | |
812 break; | |
813 } /* End of switch (GET_STATE (STATE_NORMAL_CBCH)) */ | |
814 } | |
815 } | |
816 | |
817 /* | |
818 +--------------------------------------------------------------------+ | |
819 | PROJECT : GSM-PS (6103) MODULE : TIL_CBCH | | |
820 | STATE : code ROUTINE : cb_data_ind | | |
821 +--------------------------------------------------------------------+ | |
822 | |
823 PURPOSE : A CBCH message is received. | |
824 | |
825 */ | |
826 | |
827 GLOBAL void cb_data_ind (T_MPHC_DATA_IND *cbch_ind) | |
828 { | |
829 GET_INSTANCE_DATA; | |
830 UBYTE block_no; | |
831 UBYTE block_description; | |
832 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
833 UBYTE * expected_seq_number = &(pcbch->expected_seq_number[0]); | |
834 | |
835 /* | |
836 * check whether the CBCH message has been received on the | |
837 * normal CBCH channel or the extended CBCH channel | |
838 */ | |
839 if (cbch_ind->tc >= 4) | |
840 { | |
841 pcbch->msg_is_extended = CBCH_READ_EXT; | |
842 expected_seq_number = &(pcbch->expected_seq_number[1]); | |
843 } | |
844 else if(cbch_ind->tc < 4) | |
845 pcbch->msg_is_extended = CBCH_READ_NORM; | |
846 | |
847 if (cbch_ind->error_flag EQ VALID_BLOCK) | |
848 { | |
849 /* | |
850 * if the CBCH block is valid, calculate the block number | |
851 */ | |
852 block_description = cbch_ind->l2_frame.content[0]; | |
853 block_no = (UBYTE)(block_description & 0x0F); | |
854 if (block_no < CBCH_NULL_MSG) | |
855 { | |
856 ALR_TRACE_CB_BLOCK_NO (block_description); | |
857 } | |
858 TRACE_EVENT_P2("expected_block_number = %d, schedule_length =%d", (*expected_seq_number), pcbch->schedule_length[0]); | |
859 switch(block_no) | |
860 { | |
861 case CBCH_BLOCK_0: | |
862 memcpy (&pcbch->msg[0], &cbch_ind->l2_frame.content[1], CBCH_BLOCK_SIZE); | |
863 #if defined(FF_HOMEZONE) | |
864 if (!cb_check_homezone ((UBYTE)(CBCH_BLOCK_SIZE*(block_no+1)))) | |
865 #endif /* FF_HOMEZONE */ | |
866 cb_first_block(block_description); | |
867 break; | |
868 | |
869 case CBCH_BLOCK_1: | |
870 case CBCH_BLOCK_2: | |
871 case CBCH_BLOCK_3: | |
872 /* | |
873 * check for sequence number | |
874 */ | |
875 if(*expected_seq_number NEQ block_no) | |
876 { | |
877 ALR_TRACE_CB("Sequence error"); | |
878 cb_error_ind(); | |
879 } | |
880 else | |
881 { | |
882 memcpy (&pcbch->msg[CBCH_BLOCK_SIZE*(block_no & 3)], | |
883 &cbch_ind->l2_frame.content[1], CBCH_BLOCK_SIZE); | |
884 | |
885 (*expected_seq_number)++; | |
886 if( *expected_seq_number > CBCH_BLOCK_3 ) | |
887 *expected_seq_number = CBCH_BLOCK_0; | |
888 | |
889 | |
890 if ( (block_description & CBCH_LAST_BLOCK) OR (block_no EQ CBCH_BLOCK_3) ) | |
891 { | |
892 /* | |
893 * last block of msg | |
894 */ | |
895 if(pcbch->msg_type EQ CBCH_NORM_MSG) | |
896 /* | |
897 * +1, because parameter is length not offset | |
898 */ | |
899 cb_cbch_message((UBYTE)(CBCH_BLOCK_SIZE*(block_no+1))); | |
900 else if(pcbch->msg_type EQ CBCH_SCHEDULE_MSG) | |
901 cb_schedule_message(); | |
902 else if(pcbch->msg_type EQ CBCH_SAT_MSG) | |
903 cb_sat_cbch_message((UBYTE)(CBCH_BLOCK_SIZE*(block_no+1))); | |
904 } | |
905 } | |
906 break; | |
907 | |
908 case CBCH_FIRST_SCHED_MSG: | |
909 /* | |
910 * first SCHEDULE block | |
911 */ | |
912 | |
913 ALR_TRACE_CB ("SCHEDULE"); | |
914 memcpy (&pcbch->msg[0], &cbch_ind->l2_frame.content[1], CBCH_BLOCK_SIZE); | |
915 cb_read_next_3_blocks(); | |
916 | |
917 pcbch->msg_type = CBCH_SCHEDULE_MSG; | |
918 break; | |
919 | |
920 case CBCH_NULL_MSG: | |
921 /* | |
922 * NULL Message | |
923 */ | |
924 | |
925 /* | |
926 ALR_TRACE_CB ("null msg"); | |
927 */ | |
928 cb_null_message (); | |
929 break; | |
930 | |
931 default: | |
932 ALR_TRACE_CB ("unknown"); | |
933 cb_error_ind(); | |
934 break; | |
935 } | |
936 | |
937 ALR_EM_RECEIVE_CBCH_MESSAGE; | |
938 | |
939 } | |
940 else | |
941 { | |
942 /* | |
943 * Invalid block | |
944 */ | |
945 /* | |
946 ALR_TRACE_CB_ERROR(cbch_ind->error_flag); | |
947 */ | |
948 | |
949 pcbch->msg_type = CBCH_NO_MSG; | |
950 cb_error_ind (); | |
951 } | |
952 } | |
953 | |
954 /* | |
955 +--------------------------------------------------------------------+ | |
956 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
957 | STATE : code ROUTINE : cb_first_block | | |
958 +--------------------------------------------------------------------+ | |
959 | |
960 PURPOSE : Reception of the first CBCH block. | |
961 | |
962 */ | |
963 | |
964 LOCAL void cb_first_block (UBYTE status) | |
965 { | |
966 GET_INSTANCE_DATA; | |
967 UBYTE result; | |
968 T_CBMSG_HEADER *p_cbh; | |
969 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
970 | |
971 /* | |
972 * extract message id and data coding scheme from the message | |
973 */ | |
974 p_cbh = (T_CBMSG_HEADER*)(&pcbch->msg[0]); | |
975 | |
976 ALR_TRACE_CB_MSGHEAD (p_cbh); | |
977 | |
978 /* | |
979 * check the incoming message: | |
980 * 1. matches the message identifier | |
981 * 2. matches the data coding scheme | |
982 * 3. is this message not received yet | |
983 */ | |
984 result = cb_check_message_id (CB_MESSAGE_ID(p_cbh)); | |
985 result += cb_check_data_coding_scheme (CB_DCS(p_cbh)); | |
986 result += cb_check_old_msg (); | |
987 | |
988 if (result EQ 3) | |
989 { | |
990 /* | |
991 * all checks are passed | |
992 */ | |
993 if (! pcbch->sat_enabled OR | |
994 ! cb_sat_check_message_id(CB_MESSAGE_ID(p_cbh))) | |
995 { | |
996 /* | |
997 * it is not a CBCH download message or | |
998 * CBCH download is not enabled | |
999 */ | |
1000 if (status & CBCH_LAST_BLOCK) | |
1001 { | |
1002 /* | |
1003 * the first is the only block, then forward it | |
1004 * to MMI. | |
1005 */ | |
1006 cb_cbch_message (CBCH_BLOCK_SIZE*(CBCH_BLOCK_0+1)); | |
1007 } | |
1008 else | |
1009 { | |
1010 /* | |
1011 * store the block and request the three remaining | |
1012 * blocks in layer 1. | |
1013 */ | |
1014 pcbch->msg_type = CBCH_NORM_MSG; | |
1015 cb_read_next_3_blocks(); | |
1016 } | |
1017 } | |
1018 else | |
1019 { | |
1020 /* | |
1021 * It is a CBCH download message and CBCH download is enabled. | |
1022 */ | |
1023 if (status & CBCH_LAST_BLOCK) | |
1024 { | |
1025 /* | |
1026 * the first block is the only block, so forward the | |
1027 * message to MMI. | |
1028 */ | |
1029 cb_sat_cbch_message (CBCH_BLOCK_SIZE*(CBCH_BLOCK_0+1)); | |
1030 } | |
1031 else | |
1032 { | |
1033 /* | |
1034 * store the data and request the three remaining blocks. | |
1035 */ | |
1036 pcbch->msg_type = CBCH_SAT_MSG; | |
1037 cb_read_next_3_blocks(); | |
1038 } | |
1039 } | |
1040 } | |
1041 else | |
1042 { | |
1043 /* | |
1044 * the message has not passed the checks. | |
1045 * So it can be only a CBCH download message. | |
1046 */ | |
1047 if(! pcbch->sat_enabled OR | |
1048 ! cb_sat_check_message_id(CB_MESSAGE_ID(p_cbh))) | |
1049 { | |
1050 /* | |
1051 * SAT is not enabled or it is not a CBCH download | |
1052 * message. So start reading of next scheduled message. | |
1053 */ | |
1054 memset (&pcbch->msg[0], 0, 88); | |
1055 cb_next_scheduled_msg(); | |
1056 | |
1057 } | |
1058 else | |
1059 { | |
1060 /* | |
1061 * it is CBCH download message and SAT is enabled | |
1062 */ | |
1063 if (status & CBCH_LAST_BLOCK) | |
1064 { | |
1065 /* | |
1066 * the first block is the last one, so send the | |
1067 * message to MMI. | |
1068 */ | |
1069 cb_sat_cbch_message (CBCH_BLOCK_SIZE*(CBCH_BLOCK_0+1)); | |
1070 } | |
1071 else | |
1072 { | |
1073 /* | |
1074 * store the first block and request the remaining three. | |
1075 */ | |
1076 pcbch->msg_type = CBCH_SAT_MSG; | |
1077 cb_read_next_3_blocks(); | |
1078 } | |
1079 } | |
1080 } | |
1081 } | |
1082 | |
1083 | |
1084 /* | |
1085 +--------------------------------------------------------------------+ | |
1086 | PROJECT : GSM-PS (6103) MODULE : TIL_CBCH | | |
1087 | STATE : code ROUTINE : cb_sat_cbch_message | | |
1088 +--------------------------------------------------------------------+ | |
1089 | |
1090 PURPOSE : Reception of a complete CBCH message for CBCH download. | |
1091 | |
1092 */ | |
1093 | |
1094 LOCAL void cb_sat_cbch_message (UBYTE length) | |
1095 { | |
1096 GET_INSTANCE_DATA; | |
1097 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1098 PALLOC (mmi_cbch_ind, MMI_SAT_CBCH_DWNLD_IND); | |
1099 | |
1100 ALR_EM_CBCH_MESSAGE_COMPLETE; | |
1101 | |
1102 TRACE_FUNCTION ("cb_sat_cbch_message()"); | |
1103 | |
1104 /* | |
1105 * copy the content of the message into the primitive. | |
1106 */ | |
1107 memcpy (mmi_cbch_ind->cbch_msg, pcbch->msg, 88); | |
1108 mmi_cbch_ind->cbch_len = length; | |
1109 | |
1110 /* | |
1111 * send to MMI | |
1112 */ | |
1113 PSENDX(MMI, mmi_cbch_ind); | |
1114 | |
1115 /* | |
1116 * prepare for next reception | |
1117 */ | |
1118 pcbch->msg_type = CBCH_NO_MSG; | |
1119 pcbch->expected_seq_number[0] = CBCH_BLOCK_0; | |
1120 pcbch->expected_seq_number[1] = CBCH_BLOCK_0; | |
1121 /* | |
1122 * start reading of next scheduled message. | |
1123 */ | |
1124 cb_next_scheduled_msg(); | |
1125 } | |
1126 | |
1127 /* | |
1128 +--------------------------------------------------------------------+ | |
1129 | PROJECT : GSM-PS (6103) MODULE : TIL_CBCH | | |
1130 | STATE : code ROUTINE : cb_schedule_message | | |
1131 +--------------------------------------------------------------------+ | |
1132 | |
1133 PURPOSE : Reception of a SCHEDULE message. | |
1134 | |
1135 */ | |
1136 | |
1137 LOCAL void cb_schedule_message (void) | |
1138 { | |
1139 GET_INSTANCE_DATA; | |
1140 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1141 UBYTE extended = pcbch->msg_is_extended; | |
1142 UBYTE *p_sched_msg = &pcbch->scheduled_sched_msg[extended]; | |
1143 | |
1144 ALR_EM_RECEIVE_SCHEDULE_MESSAGE; | |
1145 | |
1146 switch ( get_cbch_state(extended) ) | |
1147 { | |
1148 case CBCH_NO_DRX: | |
1149 /* | |
1150 * change from NO DRX mode (no knowledge about Scheduling) | |
1151 * to DRX mode. | |
1152 */ | |
1153 | |
1154 set_cbch_state (extended, CBCH_DRX); | |
1155 | |
1156 | |
1157 /* | |
1158 * check whether it is a scheduled schedule message or not. | |
1159 */ | |
1160 if(pcbch->msg[0] EQ 1) | |
1161 *p_sched_msg = 1; | |
1162 else | |
1163 *p_sched_msg = 0; | |
1164 | |
1165 /* | |
1166 * create schedule map with new and old messages | |
1167 */ | |
1168 cb_create_schedule_map (TRUE); | |
1169 | |
1170 /* | |
1171 * forward the schedule map to layer 1. | |
1172 */ | |
1173 cb_read_cbch((UBYTE)(CBCH_SCHED | extended)); | |
1174 | |
1175 break; | |
1176 | |
1177 case CBCH_DRX: | |
1178 if (pcbch->msg[0] EQ 1) | |
1179 { | |
1180 /* | |
1181 * scheduled SCHEDULE message | |
1182 */ | |
1183 if(*p_sched_msg <= 2) | |
1184 (*p_sched_msg)++; | |
1185 | |
1186 if (*p_sched_msg > 1) | |
1187 /* | |
1188 * we have read a full schedule period | |
1189 * so we dont need to read the old messages | |
1190 */ | |
1191 cb_create_schedule_map (FALSE); | |
1192 else | |
1193 cb_create_schedule_map (TRUE); | |
1194 | |
1195 cb_read_cbch((UBYTE)(CBCH_SCHED | extended)); | |
1196 } | |
1197 break; | |
1198 default: | |
1199 break; | |
1200 } | |
1201 /* | |
1202 * prepare for next reception | |
1203 */ | |
1204 pcbch->msg_type = CBCH_NO_MSG; | |
1205 pcbch->expected_seq_number[0] = CBCH_BLOCK_0; | |
1206 pcbch->expected_seq_number[1] = CBCH_BLOCK_0; | |
1207 } | |
1208 | |
1209 /* | |
1210 +--------------------------------------------------------------------+ | |
1211 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1212 | STATE : code ROUTINE : cb_null_message | | |
1213 +--------------------------------------------------------------------+ | |
1214 | |
1215 PURPOSE : Reception of a NULL message. | |
1216 | |
1217 */ | |
1218 LOCAL void cb_null_message (void) | |
1219 { | |
1220 GET_INSTANCE_DATA; | |
1221 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1222 UBYTE extended = pcbch->msg_is_extended; | |
1223 | |
1224 ALR_EM_RECEIVE_NULL_MESSAGE; | |
1225 | |
1226 switch ( get_cbch_state(extended) ) | |
1227 { | |
1228 case CBCH_DRX: | |
1229 if (pcbch->schedule_length[extended] EQ 0) | |
1230 { | |
1231 /* | |
1232 * instead of the scheduled SCHEDULE message | |
1233 * a NULL message has received. | |
1234 * Restarting with NO DRX mode | |
1235 */ | |
1236 set_cbch_state (extended, CBCH_NO_DRX); | |
1237 cb_read_cbch ((UBYTE)(CBCH_NO_SCHED | extended)); | |
1238 } | |
1239 else | |
1240 { | |
1241 cb_next_scheduled_msg(); | |
1242 } | |
1243 break; | |
1244 } | |
1245 } | |
1246 | |
1247 /* | |
1248 +--------------------------------------------------------------------+ | |
1249 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1250 | STATE : code ROUTINE : cb_error_ind | | |
1251 +--------------------------------------------------------------------+ | |
1252 | |
1253 PURPOSE : Indicates an invalid block. | |
1254 1) with error_flag =TRUE | |
1255 2) invalid sequence number | |
1256 3) out of sequence block | |
1257 */ | |
1258 | |
1259 LOCAL void cb_error_ind (void) | |
1260 { | |
1261 GET_INSTANCE_DATA; | |
1262 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1263 UBYTE extended = pcbch->msg_is_extended; | |
1264 | |
1265 if( pcbch->expected_seq_number[extended] NEQ CBCH_BLOCK_0) | |
1266 { | |
1267 /* | |
1268 * stop the next blocks | |
1269 */ | |
1270 cb_stop_next_blocks(); | |
1271 } | |
1272 switch ( get_cbch_state(extended) ) | |
1273 { | |
1274 case CBCH_DRX: | |
1275 if (pcbch->schedule_length[extended] EQ 0) | |
1276 { | |
1277 /* | |
1278 * instead of the scheduled SCHEDULE message | |
1279 * an invalid message has been received. | |
1280 * Restarting with NO DRX mode | |
1281 */ | |
1282 set_cbch_state (extended, CBCH_NO_DRX); | |
1283 cb_read_cbch ((UBYTE)(CBCH_NO_SCHED | extended)); | |
1284 } | |
1285 else | |
1286 /* | |
1287 * Go back to FIRST DRX mode. | |
1288 */ | |
1289 { | |
1290 pcbch->scheduled_sched_msg[extended] = 1; | |
1291 cb_next_scheduled_msg(); | |
1292 } | |
1293 break; | |
1294 default: | |
1295 break; | |
1296 } | |
1297 } | |
1298 | |
1299 /* | |
1300 +--------------------------------------------------------------------+ | |
1301 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1302 | STATE : code ROUTINE : cb_ind | | |
1303 +--------------------------------------------------------------------+ | |
1304 | |
1305 PURPOSE : Indication of the CBCH message. | |
1306 | |
1307 */ | |
1308 | |
1309 LOCAL void cb_ind (UBYTE length) | |
1310 { | |
1311 GET_INSTANCE_DATA; | |
1312 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1313 PALLOC (mmi_cbch_ind, MMI_CBCH_IND); | |
1314 | |
1315 ALR_EM_CBCH_MESSAGE_COMPLETE; | |
1316 | |
1317 /* | |
1318 * copy the message content to the primitive. | |
1319 */ | |
1320 memcpy (mmi_cbch_ind->cbch_msg, pcbch->msg, CBCH_MSG_SIZE); | |
1321 mmi_cbch_ind->cbch_len = length; | |
1322 | |
1323 ma_cb_mmi_cbch_ind(mmi_cbch_ind); | |
1324 | |
1325 { | |
1326 T_CBMSG_HEADER *p_cbh = (T_CBMSG_HEADER*)(&pcbch->msg[0]); | |
1327 ALR_TRACE_CB_MSGHEAD (p_cbh); | |
1328 } | |
1329 } | |
1330 | |
1331 /* | |
1332 +--------------------------------------------------------------------+ | |
1333 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1334 | STATE : code ROUTINE : cb_read_next_3_blocks | | |
1335 +--------------------------------------------------------------------+ | |
1336 | |
1337 PURPOSE : Starts read of next 3 blocks. | |
1338 | |
1339 */ | |
1340 | |
1341 LOCAL void cb_read_next_3_blocks(void) | |
1342 { | |
1343 GET_INSTANCE_DATA; | |
1344 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1345 UBYTE extended = pcbch->msg_is_extended; | |
1346 | |
1347 if( extended EQ CBCH_READ_EXT) | |
1348 ma_cb_info_req (CBCH_EXT_BLOCK234); | |
1349 else | |
1350 ma_cb_info_req (CBCH_NORM_BLOCK234); | |
1351 | |
1352 pcbch->expected_seq_number[extended] = CBCH_BLOCK_1; | |
1353 } | |
1354 | |
1355 /* | |
1356 +--------------------------------------------------------------------+ | |
1357 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1358 | STATE : code ROUTINE : cb_stop_next_blocks | | |
1359 +--------------------------------------------------------------------+ | |
1360 | |
1361 PURPOSE : Stop next blocks. | |
1362 | |
1363 */ | |
1364 | |
1365 LOCAL void cb_stop_next_blocks (void) | |
1366 { | |
1367 GET_INSTANCE_DATA; | |
1368 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1369 /* | |
1370 * stop the next blocks | |
1371 */ | |
1372 | |
1373 /* | |
1374 * Upper layers / L1 Circuit Switched interfaces | |
1375 * S922.doc , Ver 1.9 | |
1376 * Section 11.3 MPHC_CBCH_INFO_REQ | |
1377 * | |
1378 * This message can be used to update on fly L1 | |
1379 * with new tb_bitmap which then replaces the current one. | |
1380 * In such a case, 0 in the bitmap means abort any pending reading of TB1/2/3 or TB5/6/7. | |
1381 * | |
1382 * A previous "schedule_length=0" is used to specify "No schedule present". | |
1383 * In such a case, L1 starts reading continuously TB0 for normal CBCH or TB4 for Extended CBCH. | |
1384 */ | |
1385 ma_cb_info_req (0); | |
1386 | |
1387 pcbch->msg_type = CBCH_NO_MSG; | |
1388 pcbch->expected_seq_number[0] = CBCH_BLOCK_0; | |
1389 pcbch->expected_seq_number[1] = CBCH_BLOCK_0; | |
1390 } | |
1391 | |
1392 #if defined(FF_HOMEZONE) && defined(INDICATE_HZ_ERROR) | |
1393 | |
1394 /* | |
1395 +--------------------------------------------------------------------+ | |
1396 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1397 | STATE : code ROUTINE : cb_ind_hz_err | | |
1398 +--------------------------------------------------------------------+ | |
1399 | |
1400 PURPOSE : Indication of the CBCH message and stop the next blocks. | |
1401 | |
1402 */ | |
1403 | |
1404 LOCAL void cb_ind_hz_err (void) | |
1405 { | |
1406 GET_INSTANCE_DATA; | |
1407 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1408 PALLOC (mmi_cbch_ind, MMI_CBCH_IND); | |
1409 | |
1410 memset (mmi_cbch_ind->cbch_msg, 0xff, CBCH_MSG_SIZE); | |
1411 mmi_cbch_ind->cbch_msg[2] = pcbch->msg_hz_id >> 8; | |
1412 mmi_cbch_ind->cbch_msg[3] = pcbch->msg_hz_id & 0xff; | |
1413 mmi_cbch_ind->cbch_len = 0; /* error indication */ | |
1414 ALR_TRACE_CB ("cb_ind_hz_err()"); | |
1415 | |
1416 ma_cb_mmi_cbch_ind(mmi_cbch_ind); | |
1417 } | |
1418 #endif /* FF_HOMEZONE */ | |
1419 | |
1420 /* | |
1421 +--------------------------------------------------------------------+ | |
1422 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1423 | STATE : code ROUTINE : cb_cbch_message | | |
1424 +--------------------------------------------------------------------+ | |
1425 | |
1426 PURPOSE : Reception of a complete CBCH message. | |
1427 | |
1428 */ | |
1429 | |
1430 LOCAL void cb_cbch_message (UBYTE length) | |
1431 { | |
1432 /* | |
1433 * Indicate the message | |
1434 */ | |
1435 cb_ind (length); | |
1436 /* | |
1437 * stop the next blocks | |
1438 */ | |
1439 cb_stop_next_blocks (); | |
1440 /* | |
1441 * store the cbch message to avoid double reception | |
1442 */ | |
1443 cb_store_cbch_msg (); | |
1444 /* | |
1445 * start reading of the next scheduled message | |
1446 */ | |
1447 cb_next_scheduled_msg(); | |
1448 } | |
1449 | |
1450 /* | |
1451 +--------------------------------------------------------------------+ | |
1452 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1453 | STATE : code ROUTINE : cb_store_cbch_msg | | |
1454 +--------------------------------------------------------------------+ | |
1455 | |
1456 PURPOSE : Store key parameter of a CBCH message to avoid | |
1457 forwarding of a CBCH message twice. | |
1458 | |
1459 */ | |
1460 LOCAL void cb_store_cbch_msg (void) | |
1461 { | |
1462 GET_INSTANCE_DATA; | |
1463 USHORT x; | |
1464 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1465 | |
1466 ALR_TRACE_CB ("Store msg"); | |
1467 | |
1468 /* | |
1469 * It is not permitted to save the cbch message, | |
1470 * if the following pattern are in the | |
1471 * lacation area identification (bcch:sys_info_3) : | |
1472 * [4] 0x00 | |
1473 * [5] 0xF1 | |
1474 * [6] 0x10 | |
1475 * | |
1476 * that means FTA in testhouse | |
1477 */ | |
1478 if (alr_data->ma_data.sys_info_3[4] EQ 0 AND | |
1479 alr_data->ma_data.sys_info_3[5] EQ 0xF1 AND | |
1480 alr_data->ma_data.sys_info_3[6] EQ 0x10) | |
1481 return; | |
1482 | |
1483 /* | |
1484 * If storage is full, remove the first one. | |
1485 */ | |
1486 if (pcbch->old_cbch_msg.cnt EQ MAX_OLD_CB) | |
1487 cb_remove_message (0); | |
1488 | |
1489 /* | |
1490 * store the new one | |
1491 */ | |
1492 x = pcbch->old_cbch_msg.cnt++; | |
1493 memcpy (&pcbch->old_cbch_msg.header[x], | |
1494 &pcbch->msg, sizeof (T_CBMSG_HEADER)); | |
1495 } | |
1496 | |
1497 /* | |
1498 +--------------------------------------------------------------------+ | |
1499 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1500 | STATE : code ROUTINE : cb_check_message_id | | |
1501 +--------------------------------------------------------------------+ | |
1502 | |
1503 PURPOSE : Check Message Identifier of the first CBCH block. | |
1504 | |
1505 */ | |
1506 | |
1507 LOCAL UBYTE cb_check_message_id (USHORT msg_id) | |
1508 { | |
1509 GET_INSTANCE_DATA; | |
1510 USHORT i; | |
1511 UBYTE result = TRUE; | |
1512 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1513 | |
1514 /* | |
1515 * if no message identifier are defined for comparision | |
1516 * make a shortcut and return immediately. | |
1517 * MODUS CBCH_ACCEPT,but no msg_id defined,accept NO messages | |
1518 * MODUS CBCH_IGNORE,but no msg_id define, accept all messages | |
1519 * MODUS CBCH_STOP,but no msg_id defined, accept NO messages | |
1520 * MODUS CBCH_HOMEZONE,but no msg_id defined, accept NO messages/ | |
1521 */ | |
1522 if ( pcbch->msg_id[0] EQ NOT_PRESENT_16BIT ) | |
1523 { | |
1524 if (pcbch->modus EQ CBCH_IGNORE) | |
1525 { | |
1526 return TRUE; | |
1527 } | |
1528 else | |
1529 { | |
1530 return FALSE; | |
1531 } | |
1532 } | |
1533 | |
1534 /* | |
1535 * initialise result | |
1536 * if the msg_id is not found and MMI specified | |
1537 * a positive range(CBCH_ACCEPT) return 0 | |
1538 */ | |
1539 result = (UBYTE)(pcbch->modus EQ CBCH_ACCEPT ? FALSE : TRUE); | |
1540 | |
1541 /* | |
1542 * message identifier are stored as a pair to express a range | |
1543 */ | |
1544 for (i=0; i < MAX_IDENTS-1; i+=2) | |
1545 { | |
1546 /* | |
1547 * end of list reached | |
1548 */ | |
1549 if (pcbch->msg_id[i] EQ NOT_PRESENT_16BIT) | |
1550 break; | |
1551 | |
1552 /* | |
1553 * check whether the message identifier is inside or outside | |
1554 * the range. Result depends on what MMI has requested. | |
1555 */ | |
1556 if ((pcbch->msg_id[i] <= msg_id) AND | |
1557 (pcbch->msg_id[i+1] >= msg_id)) | |
1558 result = (UBYTE)(pcbch->modus EQ CBCH_ACCEPT ? TRUE : FALSE); | |
1559 } | |
1560 | |
1561 return result; | |
1562 } | |
1563 | |
1564 | |
1565 /* | |
1566 +--------------------------------------------------------------------+ | |
1567 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1568 | STATE : code ROUTINE : cb_sat_check_message_id | | |
1569 +--------------------------------------------------------------------+ | |
1570 | |
1571 PURPOSE : Check Message Identifier of the first CBCH block for CBCH | |
1572 download purposes. | |
1573 | |
1574 */ | |
1575 | |
1576 LOCAL UBYTE cb_sat_check_message_id (USHORT msg_id) | |
1577 { | |
1578 GET_INSTANCE_DATA; | |
1579 USHORT i; | |
1580 UBYTE result; | |
1581 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1582 /* | |
1583 * initialize result | |
1584 */ | |
1585 result = FALSE; | |
1586 | |
1587 /* | |
1588 * for all stored message identifier of CBCH download | |
1589 */ | |
1590 for (i = 0; i < MAX_IDENTS_SAT; i++) | |
1591 { | |
1592 /* | |
1593 * end of list reached | |
1594 */ | |
1595 if (pcbch->msg_id_sat[i] EQ NOT_PRESENT_16BIT) | |
1596 break; | |
1597 | |
1598 /* | |
1599 * if message identifier matches | |
1600 */ | |
1601 if (pcbch->msg_id_sat[i] EQ msg_id) | |
1602 { | |
1603 result = TRUE; | |
1604 break; | |
1605 } | |
1606 } | |
1607 | |
1608 return result; | |
1609 } | |
1610 | |
1611 /* | |
1612 +--------------------------------------------------------------------+ | |
1613 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1614 | STATE : code ROUTINE : cb_check_data_coding_scheme| | |
1615 +--------------------------------------------------------------------+ | |
1616 | |
1617 PURPOSE : Check Data Coding Scheme of the first CBCH block. | |
1618 | |
1619 */ | |
1620 LOCAL UBYTE cb_check_data_coding_scheme (UBYTE dcs_id) | |
1621 { | |
1622 GET_INSTANCE_DATA; | |
1623 USHORT i; | |
1624 UBYTE result = TRUE; | |
1625 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1626 | |
1627 /* | |
1628 * if the list is empty, result is positive | |
1629 */ | |
1630 if (pcbch->dcs_id [0] EQ NOT_PRESENT_8BIT) | |
1631 return result; | |
1632 | |
1633 /* | |
1634 * initialise result | |
1635 * if the dcs_id is not found and MMI specified | |
1636 * a positive range(CBCH_ACCEPT) return 0 | |
1637 */ | |
1638 result = (UBYTE)(pcbch->modus EQ CBCH_ACCEPT ? 0 : 1); | |
1639 | |
1640 | |
1641 for (i=0;i<MAX_IDENTS-1;i+=2) | |
1642 { | |
1643 /* | |
1644 * end of list reached | |
1645 */ | |
1646 if (pcbch->dcs_id[i] EQ NOT_PRESENT_8BIT) | |
1647 break; | |
1648 | |
1649 /* | |
1650 * Data Coding Scheme identifier matches | |
1651 */ | |
1652 if (pcbch->dcs_id[i] <= dcs_id AND | |
1653 pcbch->dcs_id[i+1] >= dcs_id) | |
1654 result = (UBYTE)(pcbch->modus EQ CBCH_ACCEPT ? 1 : 0); | |
1655 } | |
1656 | |
1657 return result; | |
1658 } | |
1659 | |
1660 /* | |
1661 +--------------------------------------------------------------------+ | |
1662 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1663 | STATE : code ROUTINE : cb_check_old_msg | | |
1664 +--------------------------------------------------------------------+ | |
1665 | |
1666 PURPOSE : Check against old messages. | |
1667 | |
1668 */ | |
1669 LOCAL UBYTE cb_check_old_msg (void) | |
1670 { | |
1671 GET_INSTANCE_DATA; | |
1672 int i; | |
1673 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1674 T_CBMSG_HEADER *p_cbh = (T_CBMSG_HEADER*)&pcbch->msg[0]; | |
1675 | |
1676 ALR_TRACE_CB ("compare with stored msg"); | |
1677 for (i=0; i < pcbch->old_cbch_msg.cnt; i++) | |
1678 { | |
1679 ALR_TRACE_CB_MSGHEAD (&pcbch->old_cbch_msg.header[i]); | |
1680 | |
1681 if (memcmp (&pcbch->old_cbch_msg.header[i], p_cbh, 6) EQ 0) | |
1682 { | |
1683 return FALSE; /* already stored message */ | |
1684 } | |
1685 else | |
1686 { | |
1687 /* if the difference is only in the update number, | |
1688 * then we need to delete the old version of the message (so that the different | |
1689 * versions do not fill up the storage) and we can even abandon the comparison; | |
1690 * a message that is resent with a different update number should only use | |
1691 * one entry in the list; otherwise it may throw out other messages that should be kept; | |
1692 * think of German network that sends every minute a new update; would use up 15 entries | |
1693 * | |
1694 * some change, now check if it is only the update number that has changed | |
1695 * (memcmp covers 4 header bytes: msg_id3, msg_id4, dcs and page | |
1696 * => ignore lint warning) | |
1697 */ | |
1698 /*lint -e{420} (Warning -- Apparent access beyond array) */ | |
1699 if ((CB_GS_CODE(&pcbch->old_cbch_msg.header[i]) == CB_GS_CODE(p_cbh)) AND | |
1700 (CB_MSG_CODE(&pcbch->old_cbch_msg.header[i]) == CB_MSG_CODE(p_cbh)) AND | |
1701 !memcmp (&(((T_CBMSG_HEADER*)&pcbch->old_cbch_msg.header[i])->msg_id3), | |
1702 &p_cbh->msg_id3, 4)) | |
1703 { /* all these fields match, therefore the change must have been only in the update number */ | |
1704 | |
1705 SHORT old_update_nr, new_update_nr; | |
1706 old_update_nr = CB_UPDATE_NO(&pcbch->old_cbch_msg.header[i]); | |
1707 new_update_nr = CB_UPDATE_NO(p_cbh); | |
1708 /* | |
1709 * 3GPP 03 41 | |
1710 * Any Update Number eight or less higher (modulo 16) than the last received Update Number | |
1711 * will be considered more recent, and shall be treated as a new message | |
1712 */ | |
1713 if((!new_update_nr) OR | |
1714 ((new_update_nr - old_update_nr + MAX_UPDATE_NO) % MAX_UPDATE_NO <= MAX_UPDATE_NO_DIFF)) | |
1715 { | |
1716 ALR_TRACE_CB ("change update num, delete old message"); | |
1717 /* remove the old message so that we do not use up another entry for this new version of the message */ | |
1718 cb_remove_message (i); | |
1719 /* skip out of loop because we found the match */ | |
1720 break; | |
1721 } | |
1722 else | |
1723 return FALSE; | |
1724 } | |
1725 } | |
1726 } | |
1727 | |
1728 return TRUE; /* new message */ | |
1729 } | |
1730 | |
1731 /* | |
1732 +--------------------------------------------------------------------+ | |
1733 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1734 | STATE : code ROUTINE : cb_read_cbch | | |
1735 +--------------------------------------------------------------------+ | |
1736 | |
1737 PURPOSE : Starts reading of the first block of CBCH. | |
1738 The parameter defines if the extended or the normal CBCH | |
1739 should be read and if scheduling should be used. | |
1740 | |
1741 */ | |
1742 | |
1743 LOCAL void cb_read_cbch (UBYTE flags) | |
1744 { | |
1745 GET_INSTANCE_DATA; | |
1746 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1747 UBYTE extended = (UBYTE)(flags & CBCH_READ_EXT); | |
1748 ULONG first_block = pcbch->schedule_map[extended][0]; | |
1749 ULONG second_block = pcbch->schedule_map[extended][1]; | |
1750 | |
1751 PALLOC (sched_req, MPHC_CBCH_SCHEDULE_REQ); | |
1752 | |
1753 ALR_TRACE_CB_START_READ(flags); | |
1754 | |
1755 sched_req->cbch_select = extended; | |
1756 | |
1757 ALR_EM_START_CBCH_READING; | |
1758 | |
1759 if(flags & CBCH_SCHED) | |
1760 { | |
1761 UBYTE n = pcbch->begin_schedule[extended] -1; | |
1762 | |
1763 sched_req->schedule_length = pcbch->end_schedule[extended] - | |
1764 pcbch->begin_schedule[extended] +1; | |
1765 | |
1766 /* | |
1767 * the MPHC SAP uses first_blocks_1 as USHORT although the internal data base | |
1768 * of ALR uses for convinience an array of 2 ULONG for first_blocks_0 and | |
1769 * first_blocks_1; ergo: do a cast for first_blocks_1 here | |
1770 */ | |
1771 | |
1772 if( pcbch->begin_schedule[extended] EQ 1) | |
1773 { | |
1774 sched_req->first_blocks_0 = first_block; | |
1775 sched_req->first_blocks_1 = (USHORT)second_block; | |
1776 } | |
1777 else if(pcbch->begin_schedule[extended] < 32) | |
1778 { | |
1779 sched_req->first_blocks_0 = (first_block >> n) | ((second_block << (32 - n))); | |
1780 sched_req->first_blocks_1 = (USHORT) (second_block >> n); | |
1781 } | |
1782 else | |
1783 { | |
1784 sched_req->first_blocks_0 = (USHORT)(second_block >> (n - 32)); | |
1785 sched_req->first_blocks_1 = 0; | |
1786 } | |
1787 } | |
1788 else | |
1789 { | |
1790 sched_req->schedule_length = 0; | |
1791 } | |
1792 | |
1793 ma_cb_sched_req(sched_req); | |
1794 } | |
1795 | |
1796 /* | |
1797 +--------------------------------------------------------------------+ | |
1798 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1799 | STATE : code ROUTINE : cb_check_ci_lai_plmn | | |
1800 +--------------------------------------------------------------------+ | |
1801 | |
1802 PURPOSE : Checking the Cell Identity and the Location Area Identification | |
1803 to handle the geographical zone parameter. | |
1804 */ | |
1805 | |
1806 LOCAL void cb_check_ci_lai_plmn (void) | |
1807 { | |
1808 GET_INSTANCE_DATA; | |
1809 USHORT i; | |
1810 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1811 UBYTE keep = 0x00; | |
1812 UBYTE *si3 = &alr_data->ma_data.sys_info_3[0]; | |
1813 UBYTE *lac = &pcbch->old_cid_plmn_lac[0]; | |
1814 UCHAR gs_scope_change_ind = CB_GEOGR_CHANGE_NONE; | |
1815 | |
1816 /* | |
1817 * it is not permitted to save the cbch message, | |
1818 * if the following pattern are in the | |
1819 * location area identification (bcch:sys_info_3) : | |
1820 * [4] 0x00 | |
1821 * [5] 0xF1 | |
1822 * [6] 0x10 | |
1823 * | |
1824 * that means FTA in testhouse. | |
1825 */ | |
1826 if ((si3[4] EQ 0x00) AND | |
1827 (si3[5] EQ 0xF1) AND | |
1828 (si3[6] EQ 0x10) | |
1829 ) | |
1830 return; | |
1831 | |
1832 if ((si3[4] NEQ lac[2]) OR | |
1833 (si3[5] NEQ lac[3]) OR | |
1834 (si3[6] NEQ lac[4]) | |
1835 ) | |
1836 { | |
1837 /* | |
1838 * The PLNM has changed | |
1839 */ | |
1840 gs_scope_change_ind = CB_GEOGR_CHANGE_PLMN; | |
1841 pcbch->old_cbch_msg.cnt = 0; /* clear all messages */ | |
1842 } | |
1843 else if ((si3[7] NEQ lac[5]) OR | |
1844 (si3[8] NEQ lac[6]) | |
1845 ) | |
1846 { | |
1847 /* | |
1848 * The location area identification has changed | |
1849 */ | |
1850 keep = CB_GEOGR_SCOPE_PLMN; /* keep PLMN wide messages */ | |
1851 gs_scope_change_ind = CB_GEOGR_CHANGE_LAC; | |
1852 } | |
1853 else if ((si3[2] NEQ lac[0]) OR | |
1854 (si3[3] NEQ lac[1]) | |
1855 ) | |
1856 { | |
1857 /* | |
1858 * The Cell Identity has changed | |
1859 */ | |
1860 | |
1861 /* indicate cell change to MMI only if we have received any CBCH broadcast messages */ | |
1862 if (pcbch->old_cbch_msg.cnt > 0) | |
1863 gs_scope_change_ind = CB_GEOGR_CHANGE_CELL; | |
1864 keep = CB_GEOGR_SCOPE_CELLN; /* keep PLMN and Location Area wide messages */ | |
1865 } | |
1866 | |
1867 | |
1868 /* | |
1869 * update old_cid_plmn_lac | |
1870 */ | |
1871 memcpy (lac, &si3[2], 7); | |
1872 | |
1873 } | |
1874 | |
1875 /* | |
1876 +--------------------------------------------------------------------+ | |
1877 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1878 | STATE : code ROUTINE : cb_remove_message | | |
1879 +--------------------------------------------------------------------+ | |
1880 | |
1881 PURPOSE : Removes the indicated CBCH message from the internal | |
1882 storage. | |
1883 | |
1884 */ | |
1885 LOCAL void cb_remove_message (USHORT i) | |
1886 { | |
1887 GET_INSTANCE_DATA; | |
1888 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1889 | |
1890 if ((pcbch->old_cbch_msg.cnt) AND | |
1891 (i < pcbch->old_cbch_msg.cnt)) | |
1892 { | |
1893 ALR_TRACE_CB ("remove msg"); | |
1894 ALR_TRACE_CB_MSGHEAD (&pcbch->old_cbch_msg.header[i]); | |
1895 | |
1896 /* | |
1897 * decrement number of stored messages. | |
1898 */ | |
1899 pcbch->old_cbch_msg.cnt--; | |
1900 memmove (&pcbch->old_cbch_msg.header[i], | |
1901 &pcbch->old_cbch_msg.header[i+1], | |
1902 (pcbch->old_cbch_msg.cnt-i) * sizeof(T_CBMSG_HEADER)); | |
1903 } | |
1904 } | |
1905 | |
1906 /* | |
1907 +--------------------------------------------------------------------+ | |
1908 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1909 | STATE : code ROUTINE : cb_create_schedule_map | | |
1910 +--------------------------------------------------------------------+ | |
1911 | |
1912 PURPOSE : Creation of a schedule map. | |
1913 | |
1914 */ | |
1915 LOCAL void cb_create_schedule_map (UBYTE old_cb_msg) | |
1916 { | |
1917 GET_INSTANCE_DATA; | |
1918 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1919 UBYTE extended = pcbch->msg_is_extended; | |
1920 UBYTE* msg_ptr; | |
1921 | |
1922 /* | |
1923 * Store begin and end slot number | |
1924 */ | |
1925 pcbch->begin_schedule [extended] = (UBYTE)(pcbch->msg [0] & 0x3F); | |
1926 pcbch->end_schedule [extended] = pcbch->msg [1]; | |
1927 | |
1928 /* | |
1929 * clear schedule bitmap | |
1930 */ | |
1931 pcbch->schedule_length[extended] = 0; | |
1932 memset (&pcbch->schedule_map[extended][0], 0, | |
1933 2*sizeof (pcbch->schedule_map[extended][0])); | |
1934 /* | |
1935 * Check all new entries, | |
1936 * msg_ptr to first message description | |
1937 */ | |
1938 msg_ptr = &pcbch->msg[8]; | |
1939 | |
1940 msg_ptr = cb_create_schedule_entries (msg_ptr, 1); | |
1941 | |
1942 if (old_cb_msg) | |
1943 { | |
1944 cb_create_schedule_entries (msg_ptr, FALSE); | |
1945 } | |
1946 } | |
1947 | |
1948 /* | |
1949 +--------------------------------------------------------------------+ | |
1950 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
1951 | STATE : code ROUTINE : cb_create_schedule_entries | | |
1952 +--------------------------------------------------------------------+ | |
1953 | |
1954 PURPOSE : Creation of schedule entries. | |
1955 | |
1956 */ | |
1957 LOCAL UBYTE* cb_create_schedule_entries (UBYTE* msg_ptr, BOOL flag) | |
1958 { | |
1959 GET_INSTANCE_DATA; | |
1960 unsigned i; | |
1961 BOOL result; | |
1962 UBYTE x; | |
1963 USHORT msg_id; | |
1964 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
1965 UBYTE extended = pcbch->msg_is_extended; | |
1966 | |
1967 pcbch->last_slot_read[extended] = 0; | |
1968 for (i=0; i < pcbch->end_schedule[extended]; i++) | |
1969 { | |
1970 result = (pcbch->msg [2 + ((i+1)>>3)] & (1 <<(8-((i+1)&7)))); | |
1971 | |
1972 ALR_TRACE_CB_SCHEDULE(i+1,result); | |
1973 | |
1974 if ((flag AND result) OR (!flag AND !result)) | |
1975 { | |
1976 /* | |
1977 * result and bit are set, that means the msg: | |
1978 * - was not send during the previous schedule period | |
1979 * - or the msg was sent unscheduled during the last period | |
1980 * - or is free of charge, reading advised | |
1981 * result and bit are both not set , that means the msg: | |
1982 * - the msg doesn't match the above | |
1983 * - these msgs are read only during the first 2 schedule periods | |
1984 */ | |
1985 if (*msg_ptr & 0x80) | |
1986 { | |
1987 /* | |
1988 * First transmission of an SMSCB within the | |
1989 * Schedule Period | |
1990 */ | |
1991 | |
1992 msg_id = (UBYTE)((*msg_ptr) & 0x7F); | |
1993 msg_ptr++; | |
1994 msg_id = (USHORT)(msg_id + *msg_ptr); | |
1995 if (cb_check_message_id (msg_id)) | |
1996 { | |
1997 /* | |
1998 * Message Identifier is expected | |
1999 * then set slot bit in schedule map | |
2000 */ | |
2001 pcbch->schedule_map[extended][i>>5] |= 1 << (i&31); | |
2002 if( (i+1) >= pcbch->begin_schedule[extended] ) | |
2003 { | |
2004 pcbch->schedule_length[extended]++; | |
2005 pcbch->last_slot_read[extended] = (i+1); | |
2006 } | |
2007 } | |
2008 } | |
2009 else | |
2010 { | |
2011 if ((*msg_ptr & 0xC0) EQ 0) | |
2012 { | |
2013 /* | |
2014 * Retransmission indication | |
2015 * Extract original message slot number | |
2016 */ | |
2017 x = (UBYTE)(*msg_ptr & 0x3F); | |
2018 if (x) | |
2019 { | |
2020 x--; | |
2021 if (pcbch->schedule_map[extended][x>>5] & (1 << (x&31)) ) | |
2022 { | |
2023 /* | |
2024 * original message will be read, then set also | |
2025 * repetition of message in schedule map | |
2026 */ | |
2027 pcbch->schedule_map[extended][i>>5] |= 1 << (i&31); | |
2028 if( (i+1) >= pcbch->begin_schedule[extended] ) | |
2029 { | |
2030 pcbch->schedule_length[extended]++; | |
2031 pcbch->last_slot_read[extended] = (i+1); | |
2032 } | |
2033 } | |
2034 } | |
2035 } | |
2036 else | |
2037 { | |
2038 if (*msg_ptr EQ 0x41) | |
2039 { | |
2040 /* | |
2041 * Free Message Slot, reading advised | |
2042 * Set bit in schedule map | |
2043 */ | |
2044 pcbch->schedule_map[extended][i>>5] |= 1 << (i&31); | |
2045 if( (i+1) >= pcbch->begin_schedule[extended] ) | |
2046 { | |
2047 pcbch->schedule_length[extended]++; | |
2048 pcbch->last_slot_read[extended] = (i+1); | |
2049 } | |
2050 } | |
2051 } | |
2052 } | |
2053 /* | |
2054 * increment message description pointer | |
2055 */ | |
2056 msg_ptr++; | |
2057 } | |
2058 } | |
2059 return msg_ptr; | |
2060 } | |
2061 | |
2062 | |
2063 /* | |
2064 +--------------------------------------------------------------------+ | |
2065 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
2066 | STATE : code ROUTINE : cb_next_scheduled_msg | | |
2067 +--------------------------------------------------------------------+ | |
2068 | |
2069 PURPOSE : Looks for end of scheduling period. | |
2070 | |
2071 */ | |
2072 LOCAL void cb_next_scheduled_msg(void) | |
2073 { | |
2074 GET_INSTANCE_DATA; | |
2075 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
2076 UBYTE extended = pcbch->msg_is_extended; | |
2077 | |
2078 if ((get_cbch_state(extended)) EQ CBCH_DRX ) | |
2079 { | |
2080 if( pcbch->schedule_length[extended] EQ 0 ) | |
2081 { | |
2082 /* | |
2083 * instead of the scheduled SCHEDULE message | |
2084 * an invalid message has been received. | |
2085 * Restarting with NO DRX mode | |
2086 */ | |
2087 set_cbch_state (extended, CBCH_NO_DRX); | |
2088 cb_read_cbch ((UBYTE)(CBCH_NO_SCHED | extended)); | |
2089 return; | |
2090 } | |
2091 pcbch->schedule_length[extended]--; | |
2092 | |
2093 if(pcbch->schedule_length[extended] EQ 0) | |
2094 { | |
2095 /* | |
2096 * clear schedule map | |
2097 * all message slots have been read | |
2098 * | |
2099 * NO need to reconfigure L1 to re-read schedule message | |
2100 * that follows slot 48 | |
2101 */ | |
2102 memset (&pcbch->schedule_map[extended][0], 0, | |
2103 2*sizeof (pcbch->schedule_map[extended][0])); | |
2104 TRACE_EVENT("Scheduled Schedule message expected"); | |
2105 | |
2106 } | |
2107 } | |
2108 } | |
2109 | |
2110 /* | |
2111 +--------------------------------------------------------------------+ | |
2112 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
2113 | STATE : code ROUTINE : get_cbch_state | | |
2114 +--------------------------------------------------------------------+ | |
2115 | |
2116 PURPOSE : Returns the state of STATE_EXT_CBCH or STATE_NORMAL_CBCH | |
2117 depending upon the input parameter "extended" | |
2118 | |
2119 */ | |
2120 | |
2121 UBYTE get_cbch_state( UBYTE extended) | |
2122 { | |
2123 GET_INSTANCE_DATA; | |
2124 if( extended) | |
2125 return GET_STATE(STATE_EXT_CBCH); | |
2126 else | |
2127 return GET_STATE(STATE_NORMAL_CBCH); | |
2128 } | |
2129 | |
2130 /* | |
2131 +--------------------------------------------------------------------+ | |
2132 | PROJECT : GSM-PS (6103) MODULE : ALR_CBCH | | |
2133 | STATE : code ROUTINE : set_cbch_state | | |
2134 +--------------------------------------------------------------------+ | |
2135 | |
2136 PURPOSE : Sets the state of STATE_EXT_CBCH or STATE_NORMAL_CBCH | |
2137 depending upon the input parameter "extended" | |
2138 | |
2139 */ | |
2140 | |
2141 void set_cbch_state( UBYTE extended, UBYTE new_state) | |
2142 { | |
2143 GET_INSTANCE_DATA; | |
2144 if(extended) | |
2145 { | |
2146 SET_STATE(STATE_EXT_CBCH,new_state); | |
2147 } | |
2148 else | |
2149 SET_STATE(STATE_NORMAL_CBCH,new_state); | |
2150 } | |
2151 | |
2152 | |
2153 #if defined(FF_HOMEZONE) | |
2154 GLOBAL void cb_tim_homezone (void) | |
2155 { | |
2156 GET_INSTANCE_DATA; | |
2157 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
2158 | |
2159 if (pcbch->homezone EQ CBCH_HZ_IDLE) | |
2160 { | |
2161 if (GET_STATE(STATE_MA) EQ MA_IDLE) | |
2162 { | |
2163 ALR_TRACE_CB ("call cb_start()"); | |
2164 cb_start (); | |
2165 } | |
2166 else | |
2167 { | |
2168 TIMERSTART (TIM_HOMEZONE, 1000); | |
2169 } | |
2170 } | |
2171 else if (pcbch->homezone EQ CBCH_HZ_PENDING) | |
2172 { | |
2173 /* | |
2174 * mark as received, indicate error, stop CBCH reading | |
2175 */ | |
2176 ALR_TRACE_CB ("cb_ind_hz_err()"); | |
2177 pcbch->homezone = CBCH_HZ_RECEIVED; | |
2178 #if defined(INDICATE_HZ_ERROR) | |
2179 cb_ind_hz_err (); | |
2180 #endif /* INDICATE_HZ_ERROR */ | |
2181 if ( (pcbch->modus EQ NOT_PRESENT_8BIT) | |
2182 AND (!pcbch->sat_enabled)) | |
2183 cb_stop (); | |
2184 } | |
2185 } | |
2186 | |
2187 LOCAL UBYTE cb_check_homezone (UBYTE length) | |
2188 { | |
2189 GET_INSTANCE_DATA; | |
2190 UBYTE result = FALSE;/* no special handling of homezone CBCH message */ | |
2191 T_CBCH_DATA *pcbch = &alr_data->cbch_data; | |
2192 | |
2193 if (pcbch->homezone EQ CBCH_HZ_PENDING) | |
2194 { | |
2195 T_CBMSG_HEADER *p_cbh; | |
2196 p_cbh = (T_CBMSG_HEADER*)(&pcbch->msg[0]); | |
2197 | |
2198 if ( (CB_MESSAGE_ID (p_cbh) EQ pcbch->msg_hz_id) | |
2199 AND (CB_DCS (p_cbh) EQ pcbch->dcs_hz_id) | |
2200 ) | |
2201 { | |
2202 /* one-time request of homezone CBCH message after cell reselection */ | |
2203 TIMERSTOP (TIM_HOMEZONE); | |
2204 pcbch->homezone = CBCH_HZ_RECEIVED; | |
2205 ALR_TRACE_CB_MSGHEAD (p_cbh); | |
2206 ALR_TRACE_CB ("homezone msg received"); | |
2207 cb_ind (length); | |
2208 result = TRUE; | |
2209 | |
2210 if ( (pcbch->modus EQ NOT_PRESENT_8BIT) | |
2211 AND (!pcbch->sat_enabled)) | |
2212 { | |
2213 ALR_TRACE_CB ("no other msg req."); | |
2214 cb_stop (); | |
2215 } | |
2216 else | |
2217 cb_stop_next_blocks (); | |
2218 } | |
2219 } | |
2220 | |
2221 return result; | |
2222 } | |
2223 #endif /* FF_HOMEZONE */ | |
2224 | |
2225 /* | |
2226 +--------------------------------------------------------------------+ | |
2227 | PROJECT : MODULE : ALR_CBCH | | |
2228 | STATE : code ROUTINE : cb_alr_trace_msghead | | |
2229 +--------------------------------------------------------------------+ | |
2230 | |
2231 PURPOSE : Function to replace the ALR_TRACE_CB_MSGHEAD macro. | |
2232 | |
2233 */ | |
2234 | |
2235 /* Implements measures 2,3,4 */ | |
2236 LOCAL void cb_alr_trace_msghead (T_CBMSG_HEADER *ph) | |
2237 { | |
2238 ALR_TRACE_CB ("cb_alr_trace_msghead()"); | |
2239 if (CB_MSG_CODE(ph) < 1000) | |
2240 { | |
2241 TRACE_EVENT_P7("CBCH ID=%3u, gs=%u, msg=%4u, upd=%u, dcs=%02x, p=%u/%u", | |
2242 CB_MESSAGE_ID(ph), CB_GS_CODE(ph), | |
2243 CB_MSG_CODE(ph), CB_UPDATE_NO(ph), | |
2244 CB_DCS(ph), CB_PAGE(ph), CB_PAGETOTAL(ph)); | |
2245 } | |
2246 else | |
2247 { | |
2248 TRACE_EVENT_P7("CBCH ID=%3u, gs=%u, msg=%04x, upd=%u, dcs=%02x, p=%u/%u", | |
2249 CB_MESSAGE_ID(ph), CB_GS_CODE(ph), | |
2250 CB_MSG_CODE(ph), CB_UPDATE_NO(ph), | |
2251 CB_DCS(ph), CB_PAGE(ph), CB_PAGETOTAL(ph)); | |
2252 } | |
2253 } | |
2254 #endif |