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