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