FreeCalypso > hg > freecalypso-citrine
comparison g23m-gsm/rr/rr_dats.c @ 0:75a11d740a02
initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 09 Jun 2016 00:02:41 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:75a11d740a02 |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : | |
4 | Modul : | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2002 Texas Instruments Berlin, AG | |
7 | All rights reserved. | |
8 | | |
9 | This file is confidential and a trade secret of Texas | |
10 | Instruments Berlin, AG | |
11 | The receipt of or possession of this file does not convey | |
12 | any rights to reproduce or disclose its contents or to | |
13 | manufacture, use, or sell anything it may describe, in | |
14 | whole, or in part, without the specific written consent of | |
15 | Texas Instruments Berlin, AG. | |
16 +----------------------------------------------------------------------------- | |
17 | Purpose : This Modul defines the functions for the data transfer | |
18 | capability of the module Radio Resource. | |
19 +----------------------------------------------------------------------------- | |
20 */ | |
21 | |
22 #ifndef RR_DATS_C | |
23 #define RR_DATS_C | |
24 | |
25 #include "config.h" | |
26 #include "fixedconf.h" | |
27 #include "condat-features.h" | |
28 | |
29 #define ENTITY_RR | |
30 | |
31 /*==== INCLUDES ===================================================*/ | |
32 | |
33 #include <string.h> | |
34 #include <stdlib.h> | |
35 #include <stddef.h> /* offsetof */ | |
36 #include "typedefs.h" | |
37 #include "pcm.h" | |
38 #include "pconst.cdg" | |
39 #include "mconst.cdg" | |
40 #include "message.h" | |
41 #include "ccdapi.h" | |
42 #include "vsi.h" | |
43 #include "custom.h" | |
44 #include "gsm.h" | |
45 #include "prim.h" | |
46 #include "cnf_rr.h" | |
47 #include "tok.h" | |
48 #include "rr.h" | |
49 #include "em.h" | |
50 #include "rr_em.h" | |
51 | |
52 /*==== EXPORT =====================================================*/ | |
53 | |
54 /*==== PRIVAT =====================================================*/ | |
55 | |
56 #define TDMA_FRAMES_PER_HYPERFRAME 2715648 | |
57 #define QUARTER_BITS_PER_FRAME 5000 | |
58 | |
59 /*==== VARIABLES ==================================================*/ | |
60 | |
61 /*==== FUNCTIONS ==================================================*/ | |
62 | |
63 LOCAL BOOL dat_for_handover_mob_alloc(UBYTE *mob_alloc, | |
64 T_LIST *hop_list_handover, | |
65 T_VOID_STRUCT *mob_alloc_handover, | |
66 T_DL_DATA_IND *dl_data_ind); | |
67 | |
68 LOCAL void dat_cr_data_multirate_conf(U8 v_multirate_conf, T_multirate_conf *multirate_conf); | |
69 | |
70 LOCAL void dat_dedicated_req_ch_type2(T_ch_type2 *ch_type2, T_chan_desc_before *chan_desc_before, | |
71 T_LIST *hop_list_before); | |
72 /* | |
73 * ------------------------------------------------------------------- | |
74 * SIGNAL Processing functions | |
75 * ------------------------------------------------------------------- | |
76 */ | |
77 | |
78 /* | |
79 +--------------------------------------------------------------------+ | |
80 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
81 | STATE : code ROUTINE : dat_att_cell_selected | | |
82 +--------------------------------------------------------------------+ | |
83 | |
84 PURPOSE : Attachment process indicates that it has camped on a cell. | |
85 Data transfer process changes the state and connections | |
86 are possible. | |
87 | |
88 */ | |
89 | |
90 GLOBAL void dat_att_cell_selected (void) | |
91 { | |
92 GET_INSTANCE_DATA; | |
93 TRACE_FUNCTION ("dat_att_cell_selected()"); | |
94 | |
95 SET_STATE (STATE_DAT, DAT_IDLE); | |
96 } | |
97 | |
98 /* | |
99 +--------------------------------------------------------------------+ | |
100 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
101 | STATE : code ROUTINE : dat_att_null | | |
102 +--------------------------------------------------------------------+ | |
103 | |
104 PURPOSE : Attachment process indicates loss of coverage and connections | |
105 are not longer possible. | |
106 | |
107 */ | |
108 | |
109 GLOBAL void dat_att_null (void) | |
110 { | |
111 GET_INSTANCE_DATA; | |
112 | |
113 TRACE_FUNCTION ("dat_att_null()"); | |
114 | |
115 SET_STATE (STATE_DAT, DAT_NULL); | |
116 } | |
117 | |
118 /* | |
119 +--------------------------------------------------------------------+ | |
120 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
121 | STATE : code ROUTINE : dat_for_assign_cmd | | |
122 +--------------------------------------------------------------------+ | |
123 | |
124 PURPOSE : The function handles the reception of a channel | |
125 assignment message. | |
126 | |
127 */ | |
128 | |
129 GLOBAL void dat_for_assign_cmd (T_DL_DATA_IND *dl_data_ind, | |
130 T_D_ASSIGN_CMD *assign_cmd, | |
131 T_LIST *hop_list_after, | |
132 T_LIST *hop_list_before, | |
133 T_LIST *cell_chan_desc) | |
134 { | |
135 GET_INSTANCE_DATA; | |
136 UBYTE mob_alloc[65]; | |
137 | |
138 PALLOC (dedicated_req, MPH_DEDICATED_REQ); | |
139 | |
140 TRACE_FUNCTION ("dat_for_assign_cmd()"); | |
141 | |
142 switch (GET_STATE (STATE_DAT)) | |
143 { | |
144 case DAT_DEDICATED: | |
145 if (rr_data->ms_data.error.cs) | |
146 { | |
147 TRACE_EVENT_P1 ("RRC cause = %02x", rr_data->ms_data.error.cs); | |
148 } | |
149 /* | |
150 * dynamic configuration command : IHO | |
151 * Lock the DUT to the cell it is already camping - | |
152 * Ignore the Channel Assignment command message and send an | |
153 * Assignment failure message to the network. | |
154 */ | |
155 | |
156 if(rr_data->dyn_config.iho AND (rr_data->sc_data.ch_mode EQ CM_AMR)) | |
157 { | |
158 TRACE_EVENT("D_ASSIGN_CMD : IHO"); | |
159 for_set_content_error (RRC_CHANNEL_MODE); | |
160 } | |
161 | |
162 switch (rr_data->ms_data.error.cs) | |
163 { | |
164 /* case RRC_INVALID_MAN_INFO: this value is currently never set */ | |
165 case RRC_COND_IE_ERROR: /* 0x64 */ | |
166 { | |
167 /* | |
168 * If an mandatory info element error or a | |
169 * conditional info element error has been detected, | |
170 * a RR STATUS message is returned on the existing | |
171 * connection before l2 is suspended | |
172 */ | |
173 dat_send_rr_status_msg(rr_data->ms_data.error.cs); | |
174 PFREE (dedicated_req); | |
175 PFREE (dl_data_ind); | |
176 break ; | |
177 } | |
178 | |
179 case RRC_INCORRECT_MSG: /* 0x5f */ | |
180 { | |
181 /* | |
182 * If a structurally correct message has been detected, | |
183 * containing erroneous data, an Assignment Failure message | |
184 * is sent back. | |
185 */ | |
186 | |
187 /* | |
188 * If the ASSIGNMENT COMMAND is erroneous, then the | |
189 * ASSIGNMENT FAILURE command is sent via a priority | |
190 * DL_RECONNECT_REQ. This ensures DL will halt processing | |
191 * anything in its buffer until it has sent this message | |
192 * onto the nw. | |
193 * | |
194 */ | |
195 for_suspend_layer_2 (); | |
196 dat_send_assign_fail_msg(rr_data->ms_data.error.val); | |
197 | |
198 RR_EM_SET_ASSIGN_FAIL_CAUSE(rr_data->ms_data.error.val); | |
199 | |
200 PFREE (dedicated_req); | |
201 PFREE (dl_data_ind); | |
202 break; | |
203 } | |
204 | |
205 default: | |
206 /* | |
207 * the initial check was successful and the | |
208 * message is processed. | |
209 * | |
210 */ | |
211 for_suspend_layer_2 (); | |
212 | |
213 /* | |
214 * use data of the old cell if no new data | |
215 * are inserted in the message | |
216 */ | |
217 rr_data->cr_data.ch_mode = rr_data->sc_data.ch_mode; | |
218 rr_data->cr_data.ciph_on = rr_data->sc_data.ciph_on; | |
219 rr_data->cr_data.algo = rr_data->sc_data.algo; | |
220 rr_data->cr_data.cd.v_cell_chan_desc = | |
221 rr_data->sc_data.cd.v_cell_chan_desc; | |
222 memcpy (&rr_data->cr_data.cd.cell_chan_desc, | |
223 &rr_data->sc_data.cd.cell_chan_desc, | |
224 sizeof (T_LIST)); | |
225 | |
226 /* | |
227 * if AMR is supported set the default values | |
228 * to the current serving cell values. | |
229 */ | |
230 if(rr_data->sc_data.ch_mode EQ CM_AMR) | |
231 { | |
232 memcpy(&rr_data->cr_data.amr_conf, | |
233 &rr_data->sc_data.amr_conf, | |
234 sizeof (T_multirate_conf)); | |
235 } | |
236 else { | |
237 /* | |
238 * AMR is not supported, therefore set some dummy values. This is necessary because | |
239 * the later Layer1 configuration must include an AMR configuration!! | |
240 */ | |
241 memset(&rr_data->cr_data.amr_conf, 0, sizeof (T_multirate_conf)); | |
242 } | |
243 | |
244 if (assign_cmd->v_cell_chan_desc) | |
245 { | |
246 /* | |
247 * If the message contains a cell channel description | |
248 * use the new one. | |
249 */ | |
250 memcpy (&rr_data->cr_data.cd.cell_chan_desc, | |
251 cell_chan_desc, | |
252 sizeof (T_LIST)); | |
253 rr_data->cr_data.cd.v_cell_chan_desc = WITH_CHANGED_CONTENT; | |
254 } | |
255 | |
256 if (assign_cmd->v_chan_mode) | |
257 /* | |
258 * if the message contains a channel mode, use the new one. | |
259 */ | |
260 rr_data->cr_data.ch_mode = assign_cmd->chan_mode; | |
261 | |
262 /* | |
263 * If AMR is signalled check if new multi-rate speech codec is part of the assignment cmd | |
264 * otherwise use default values set earlier. | |
265 */ | |
266 | |
267 /* Implements RR Clone findings #9 */ | |
268 dat_cr_data_multirate_conf(assign_cmd->v_multirate_conf,&assign_cmd->multirate_conf); | |
269 | |
270 | |
271 if (assign_cmd->v_ciph_mode_set) | |
272 { | |
273 /* | |
274 * If ciphering is defined in the message, handle it. | |
275 */ | |
276 rr_data->cr_data.ciph_on = assign_cmd->ciph_mode_set.sc; | |
277 rr_data->cr_data.algo = assign_cmd->ciph_mode_set.algo_ident; | |
278 | |
279 if (rr_data->cr_data.ciph_on EQ CIPH_ON AND | |
280 rr_data->sc_data.ciph_received EQ FALSE) | |
281 { | |
282 /* | |
283 * if ciphering is not active, but set in the message | |
284 * this is a failure and the configuration is aborted. | |
285 * Instead the reconnection on the old channel is started. | |
286 */ | |
287 dat_send_assign_fail_msg(RRC_PROT_UNSPECIFIED); | |
288 | |
289 RR_EM_SET_ASSIGN_FAIL_CAUSE(RRC_PROT_UNSPECIFIED); | |
290 | |
291 PFREE (dedicated_req); | |
292 PFREE (dl_data_ind); | |
293 | |
294 return; | |
295 } | |
296 } | |
297 | |
298 if (assign_cmd->chan_desc.hop EQ 1 AND | |
299 assign_cmd->v_mob_alloc_after) | |
300 { | |
301 if (rr_data->cr_data.cd.v_cell_chan_desc EQ NO_CONTENT) | |
302 { | |
303 /* | |
304 * If the new channel needs hopping, but there is no | |
305 * cell channel description available, the configuration | |
306 * is aborted due to a conditional error. | |
307 * Instead the reconnection on the old channel is started. | |
308 */ | |
309 dat_send_assign_fail_msg(RRC_NO_CELL_ALLOC); | |
310 | |
311 RR_EM_SET_ASSIGN_FAIL_CAUSE(RRC_NO_CELL_ALLOC); | |
312 | |
313 PFREE (dedicated_req); | |
314 PFREE (dl_data_ind); | |
315 return; | |
316 } | |
317 | |
318 /* | |
319 * if the message contains a mobile allocation, | |
320 * build a list of 1-bits from the bitmap. | |
321 */ | |
322 att_bits_to_byte (mob_alloc, | |
323 assign_cmd->mob_alloc_after.c_mac, | |
324 assign_cmd->mob_alloc_after.mac); | |
325 | |
326 /* | |
327 * create a hopping list from mobile allocation and cell channel | |
328 * description | |
329 */ | |
330 if(!srv_create_chan_mob_alloc (&rr_data->cr_data.cd.cell_chan_desc, | |
331 hop_list_after, | |
332 mob_alloc)) | |
333 { | |
334 dat_send_assign_fail_msg(RRC_FREQ_NOT_IMPL); | |
335 | |
336 RR_EM_SET_ASSIGN_FAIL_CAUSE(RRC_FREQ_NOT_IMPL); | |
337 | |
338 PFREE (dedicated_req); | |
339 PFREE (dl_data_ind); | |
340 return; | |
341 } | |
342 } | |
343 | |
344 /* | |
345 * clean primitive to layer 1 | |
346 */ | |
347 memset (dedicated_req, 0, sizeof (T_MPH_DEDICATED_REQ)); | |
348 | |
349 dedicated_req->mod = MODE_CHAN_ASSIGN; | |
350 | |
351 rr_data->cr_data.chan_desc = assign_cmd->chan_desc; | |
352 | |
353 /* | |
354 * Set Channel Type | |
355 */ | |
356 dedicated_req->ch_type.ch = assign_cmd->chan_desc.chan_type; | |
357 dedicated_req->ch_type.tn = assign_cmd->chan_desc.tn; | |
358 dedicated_req->ch_type.tsc = assign_cmd->chan_desc.tsc; | |
359 dedicated_req->ch_type.h = assign_cmd->chan_desc.hop; | |
360 if (assign_cmd->chan_desc.hop EQ H_NO) | |
361 { | |
362 dedicated_req->ch_type.arfcn = assign_cmd->chan_desc.arfcn; | |
363 } | |
364 else | |
365 { | |
366 dedicated_req->ch_type.maio = assign_cmd->chan_desc.maio; | |
367 dedicated_req->ch_type.hsn = assign_cmd->chan_desc.hsn; | |
368 | |
369 /* CSI-LLD section:4.1.1.11 | |
370 * This function Updates the black list with the MA list received | |
371 * inthe assignment command | |
372 */ | |
373 cs_remove_BA_MA_from_black_list(rr_data->cs_data.region,hop_list_after); | |
374 | |
375 srv_create_list (hop_list_after, dedicated_req->ch_type.ma, | |
376 MAX_MA_CHANNELS, TRUE, 0); | |
377 } | |
378 | |
379 /* | |
380 * set initial power | |
381 */ | |
382 dedicated_req->tr_para.power = assign_cmd->pow_cmd.pow; | |
383 | |
384 /* | |
385 * set starting time if available. | |
386 */ | |
387 if (assign_cmd->v_start_time) | |
388 { | |
389 dedicated_req->start.v_start = TRUE; | |
390 dedicated_req->start.t1 = assign_cmd->start_time.t1; | |
391 dedicated_req->start.t2 = assign_cmd->start_time.t2; | |
392 dedicated_req->start.t3 = assign_cmd->start_time.t3; | |
393 } | |
394 | |
395 /* | |
396 * Setting of before starting time elements ! | |
397 */ | |
398 if (assign_cmd->v_chan_desc_before EQ FALSE) | |
399 dedicated_req->ch_type2.ch = NOT_PRESENT_8BIT; | |
400 else | |
401 { | |
402 if (assign_cmd->v_mob_alloc_before) | |
403 { | |
404 att_bits_to_byte (mob_alloc, | |
405 assign_cmd->mob_alloc_before.c_mac, | |
406 assign_cmd->mob_alloc_before.mac); | |
407 if(!srv_create_chan_mob_alloc (&rr_data->cr_data.cd.cell_chan_desc, | |
408 hop_list_before, | |
409 mob_alloc)) | |
410 { | |
411 dat_send_assign_fail_msg(RRC_FREQ_NOT_IMPL); | |
412 | |
413 RR_EM_SET_ASSIGN_FAIL_CAUSE( RRC_FREQ_NOT_IMPL); | |
414 | |
415 PFREE (dedicated_req); | |
416 PFREE (dl_data_ind); | |
417 return; | |
418 } | |
419 } | |
420 | |
421 dat_dedicated_req_ch_type2(&dedicated_req->ch_type2, &assign_cmd->chan_desc_before, | |
422 hop_list_before ); | |
423 | |
424 } | |
425 | |
426 | |
427 /* | |
428 * set dtx depending on the channel type (halfrate or fullrate) | |
429 */ | |
430 | |
431 if (dedicated_req->ch_type.ch EQ 2 OR | |
432 dedicated_req->ch_type.ch EQ 3) | |
433 dedicated_req->tr_para.dtx = | |
434 rr_data->sc_data.cd.dtx = rr_data->sc_data.cd.dtx_half; | |
435 else | |
436 dedicated_req->tr_para.dtx = | |
437 rr_data->sc_data.cd.dtx = rr_data->sc_data.cd.dtx_full; | |
438 | |
439 dedicated_req->arfcn = rr_data->nc_data[SC_INDEX].arfcn; | |
440 dedicated_req->tr_para.rlt = rr_data->sc_data.cd.cell_options.rlt; | |
441 dedicated_req->tr_para.pwrc = rr_data->sc_data.cd.cell_options.pow_ctrl; | |
442 dedicated_req->tr_para.mode = rr_data->cr_data.ch_mode; | |
443 | |
444 /* | |
445 * Set multi-rate speech codec | |
446 */ | |
447 dedicated_req->amr_conf.nscb = rr_data->cr_data.amr_conf.nscb; | |
448 dedicated_req->amr_conf.icmi = rr_data->cr_data.amr_conf.icmi; | |
449 dedicated_req->amr_conf.st_mode = rr_data->cr_data.amr_conf.st_mode; | |
450 dedicated_req->amr_conf.acs = rr_data->cr_data.amr_conf.set_amr; | |
451 | |
452 /* | |
453 * valid flag for the threshold and hystersis values. amr_conf.c_cod_prop | |
454 * defines the number of threshold and hystersis values. | |
455 */ | |
456 dedicated_req->amr_conf.v_cod_prop = rr_data->cr_data.amr_conf.v_cod_prop; | |
457 | |
458 if(dedicated_req->amr_conf.v_cod_prop) | |
459 { | |
460 int i; | |
461 dedicated_req->amr_conf.c_cod_prop = rr_data->cr_data.amr_conf.c_cod_prop; | |
462 for(i=0; i<dedicated_req->amr_conf.c_cod_prop; i++) | |
463 memcpy(&dedicated_req->amr_conf.cod_prop[i], | |
464 &rr_data->cr_data.amr_conf.cod_prop[i], | |
465 sizeof(T_cod_prop)); | |
466 } | |
467 | |
468 if (rr_data->cr_data.ciph_on) | |
469 { | |
470 /* | |
471 * set cipher parameter if available. | |
472 */ | |
473 dedicated_req->ciph.stat = rr_data->cr_data.ciph_on; | |
474 dedicated_req->ciph.algo = rr_data->cr_data.algo; | |
475 memcpy (dedicated_req->ciph.kc, rr_data->ms_data.kc, KC_STRING_SIZE); | |
476 } | |
477 | |
478 RR_EM_GET_HOPPING_CHANNEL (dedicated_req->ch_type.ma, dedicated_req->ch_type2.ma, | |
479 dedicated_req->start.v_start,dedicated_req->ch_type2.maio); | |
480 | |
481 EM_ASSIGNMENT_RECEIVED; | |
482 | |
483 /* | |
484 * configure layer 1 | |
485 */ | |
486 SET_STATE (STATE_DAT, DAT_CHAN_ASS); | |
487 PSENDX (PL, dedicated_req); | |
488 PFREE (dl_data_ind); | |
489 return; | |
490 } | |
491 break; | |
492 | |
493 default: | |
494 PFREE (dedicated_req); | |
495 PFREE (dl_data_ind); | |
496 break; | |
497 } | |
498 } | |
499 | |
500 /* | |
501 +--------------------------------------------------------------------+ | |
502 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
503 | STATE : code ROUTINE : dat_for_chan_mod | | |
504 +--------------------------------------------------------------------+ | |
505 | |
506 PURPOSE : The function handles a received channel mode modify message. | |
507 | |
508 */ | |
509 | |
510 GLOBAL void dat_for_chan_mod (T_DL_DATA_IND *dl_data_ind, | |
511 T_D_CHAN_MOD *chan_mod) | |
512 { | |
513 GET_INSTANCE_DATA; | |
514 MCAST (chan_mod_ack, U_CHAN_MOD_ACK); | |
515 | |
516 TRACE_FUNCTION ("dat_for_chan_mod()"); | |
517 | |
518 if (rr_data->ms_data.error.cs EQ 0) | |
519 { | |
520 /* | |
521 * the check in the formatter indicates no problems | |
522 * store new channel mode. | |
523 */ | |
524 rr_data->sc_data.ch_mode = chan_mod->chan_mode; | |
525 | |
526 /* | |
527 * the channel mode modify message contains a multi-rate configuration IEI | |
528 */ | |
529 if( chan_mod->v_multirate_conf AND (chan_mod->chan_mode EQ CM_AMR) ) | |
530 { | |
531 int i; | |
532 rr_data->sc_data.amr_conf.mr_vers = chan_mod->multirate_conf.mr_vers; | |
533 rr_data->sc_data.amr_conf.nscb = chan_mod->multirate_conf.nscb; | |
534 rr_data->sc_data.amr_conf.icmi = chan_mod->multirate_conf.icmi; | |
535 rr_data->sc_data.amr_conf.st_mode = chan_mod->multirate_conf.st_mode; | |
536 rr_data->sc_data.amr_conf.set_amr = chan_mod->multirate_conf.set_amr; | |
537 | |
538 rr_data->sc_data.amr_conf.v_cod_prop = chan_mod->multirate_conf.v_cod_prop; | |
539 if(rr_data->sc_data.amr_conf.v_cod_prop) | |
540 { | |
541 rr_data->sc_data.amr_conf.c_cod_prop = chan_mod->multirate_conf.c_cod_prop; | |
542 for (i=0; i< rr_data->sc_data.amr_conf.c_cod_prop; i++) | |
543 memcpy(&rr_data->sc_data.amr_conf.cod_prop[i], &chan_mod->multirate_conf.cod_prop[i], sizeof(T_cod_prop)); | |
544 } | |
545 } | |
546 | |
547 /* | |
548 * configure layer 1 | |
549 */ | |
550 dat_code_mph_chan_mode_req (chan_mod); | |
551 | |
552 EM_CHANNEL_MODE_MODIFY; | |
553 | |
554 /* | |
555 * indicate new channel mode to MM | |
556 */ | |
557 dat_code_channel_mode_to_mm (); | |
558 } | |
559 | |
560 { | |
561 /* | |
562 * build the answer to the network | |
563 * (channel mode modify acknowledge message) | |
564 */ | |
565 PALLOC_MSG (dl_data_req, DL_DATA_REQ, U_CHAN_MOD_ACK); | |
566 | |
567 /* | |
568 * set channel type and SAPI | |
569 */ | |
570 dat_code_prr_channel (&dl_data_req->ch_type, | |
571 &dl_data_req->sapi, | |
572 rr_data->sc_data.chan_desc.chan_type); | |
573 | |
574 chan_mod_ack->msg_type = U_CHAN_MOD_ACK; | |
575 memcpy (&chan_mod_ack->chan_desc, | |
576 &rr_data->sc_data.chan_desc, | |
577 sizeof (T_chan_desc)); | |
578 | |
579 /* | |
580 * set the current channel mode. if the new | |
581 * channel mode is supported by the MS, the new | |
582 * one is returned, else it is the previous one | |
583 * and layer 1 was not re-configured. | |
584 */ | |
585 chan_mod_ack->chan_mode = rr_data->sc_data.ch_mode; | |
586 | |
587 for_dat_data_req (dl_data_req); | |
588 | |
589 EM_CHANNEL_MODE_MODIFY_ACK; | |
590 } | |
591 | |
592 PFREE(dl_data_ind); | |
593 } | |
594 | |
595 /* | |
596 +--------------------------------------------------------------------+ | |
597 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
598 | STATE : code ROUTINE : dat_for_chan_rel | | |
599 +--------------------------------------------------------------------+ | |
600 | |
601 PURPOSE : Reception of a channel release message. | |
602 | |
603 */ | |
604 | |
605 GLOBAL void dat_for_chan_rel (T_DL_DATA_IND *dl_data_ind, | |
606 T_D_CHAN_REL *chan_rel) | |
607 { | |
608 GET_INSTANCE_DATA; | |
609 TRACE_FUNCTION ("dat_for_chan_rel()"); | |
610 | |
611 if (GET_STATE (STATE_DAT) NEQ DAT_NULL) | |
612 { | |
613 /* | |
614 * disconnect layer 2 link | |
615 */ | |
616 dat_disconnect_link (CAUSE_MAKE (DEFBY_STD, | |
617 ORIGSIDE_NET, | |
618 RR_ORIGINATING_ENTITY, | |
619 chan_rel->rr_cause)); | |
620 | |
621 #ifdef GPRS | |
622 if (chan_rel->v_gprs_resum) | |
623 { | |
624 rr_data->gprs_data.gprs_resump = chan_rel->gprs_resum.res_ack; | |
625 } | |
626 /* | |
627 o if the element is not available but we have send a susp_req | |
628 a resumption failure has occured (gprs_resump was already set | |
629 on tx of the suspension request) | |
630 o if the element is not present and we have not send a suspension | |
631 request there is no resumption failure. | |
632 o For Ericsson we have to do a RAU after every CS call even if the | |
633 call started on a GSM-only cell and we did not send a suspension request */ | |
634 else | |
635 if(att_gprs_is_avail()) | |
636 rr_data->gprs_data.gprs_resump = GPRS_RESUMPTION_NOT_ACK; | |
637 #endif | |
638 | |
639 if (chan_rel->v_ba_range) | |
640 { | |
641 /* | |
642 * convert RR_BA_RANGE to BCCH-LIST and | |
643 * send it with RR SYNC IND to MM | |
644 */ | |
645 dat_code_prr_bcch_info (chan_rel->v_ba_range, | |
646 &chan_rel->ba_range); | |
647 } | |
648 | |
649 EM_CHANNEL_RELEASE; | |
650 } | |
651 PFREE (dl_data_ind); | |
652 } | |
653 | |
654 /* | |
655 +--------------------------------------------------------------------+ | |
656 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
657 | STATE : code ROUTINE : dat_for_class_enq | | |
658 +--------------------------------------------------------------------+ | |
659 | |
660 PURPOSE : Reception of a classmark enquiry message. | |
661 | |
662 */ | |
663 | |
664 #ifdef REL99 | |
665 GLOBAL void dat_for_class_enq (T_DL_DATA_IND *dl_data_ind, | |
666 T_D_CLASS_ENQ *class_enq) | |
667 #else | |
668 GLOBAL void dat_for_class_enq (T_DL_DATA_IND *dl_data_ind) | |
669 #endif | |
670 { | |
671 TRACE_FUNCTION ("dat_for_class_enq()"); | |
672 | |
673 if (dat_check_error_flag (SEND_RR_STATUS)) | |
674 { | |
675 /* | |
676 * The syntax check indicates no problems, then | |
677 * process the message. | |
678 * | |
679 * The MS returns a classmark change message. | |
680 */ | |
681 /* Implements RR Clone findings #15 */ | |
682 #ifdef REL99 | |
683 /*Perform checks on classmark enquiry mask IE, if present*/ | |
684 if ((class_enq->v_class_enq_mask EQ FALSE) OR | |
685 ((class_enq->v_class_enq_mask EQ TRUE) AND | |
686 (class_enq->class_enq_mask.class_req EQ CLASS_CHANGE_REQ) ) ) | |
687 #endif | |
688 dat_class_chng_data_req(); | |
689 } | |
690 | |
691 EM_CLASSMARK_ENQUIRY; | |
692 | |
693 PFREE (dl_data_ind); | |
694 } | |
695 | |
696 /* | |
697 +--------------------------------------------------------------------+ | |
698 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
699 | STATE : code ROUTINE : send_mph_tch_loop_req | | |
700 +--------------------------------------------------------------------+ | |
701 | |
702 PURPOSE : Send the L1 primitive for close TCH loop. | |
703 | |
704 */ | |
705 | |
706 static void send_mph_tch_loop_req(T_DL_DATA_IND * dl_data_ind, | |
707 UBYTE loop_command) | |
708 { | |
709 /* | |
710 * configure layer 1 | |
711 */ | |
712 PREUSE (dl_data_ind, loop_req, MPH_TCH_LOOP_REQ);/* T_MPH_TCH_LOOP_REQ */ | |
713 loop_req->tch_loop = loop_command; | |
714 PSENDX (PL, loop_req); | |
715 } | |
716 | |
717 /* | |
718 +-----------------------------------------------------------------------+ | |
719 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
720 | STATE : code ROUTINE : send_close_tch_loop_ack_to_nw | | |
721 +-----------------------------------------------------------------------+ | |
722 | |
723 PURPOSE : Send the CLOSE TCH LOOP ACK message to the network. | |
724 | |
725 */ | |
726 static void send_close_tch_loop_ack_to_nw(void) | |
727 { | |
728 GET_INSTANCE_DATA; | |
729 /* | |
730 * if the TCH loop is open and a TCH is assigned | |
731 */ | |
732 | |
733 PALLOC_SDU (data_req, DL_DATA_REQ, 2*BITS_PER_BYTE); | |
734 /* | |
735 * set channel type and sapi for the response to the network | |
736 */ | |
737 dat_code_prr_channel (&data_req->ch_type, | |
738 &data_req->sapi, | |
739 rr_data->sc_data.chan_desc.chan_type); | |
740 | |
741 /* | |
742 * code the message without CCD | |
743 */ | |
744 data_req->sdu.l_buf = 16; | |
745 data_req->sdu.o_buf = ENCODE_OFFSET; | |
746 data_req->sdu.buf [0] = 0; | |
747 /*lint -e415 -e416 Likely access of out-of-bounds pointer*/ | |
748 data_req->sdu.buf [1] = 0; | |
749 data_req->sdu.buf [2] = 0; | |
750 data_req->sdu.buf [3] = 0x0F; /* TI=0, PD = TST */ | |
751 data_req->sdu.buf [4] = 0x01; /* MT = Close TCH Ack */ | |
752 /*lint +e415 +e416 Likely access of out-of-bounds pointer*/ | |
753 TRACE_EVENT ("DL_DATA_REQ (RR message)"); | |
754 | |
755 EM_TCH_LOOP_CLOSED; | |
756 | |
757 PSENDX (DL, data_req); | |
758 } | |
759 | |
760 | |
761 /* | |
762 +--------------------------------------------------------------------+ | |
763 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
764 | STATE : code ROUTINE : dat_for_close_loop_cmd | | |
765 +--------------------------------------------------------------------+ | |
766 | |
767 PURPOSE : Reception of a TCH Close Loop Command message. | |
768 | |
769 */ | |
770 | |
771 static const UBYTE LOOP_TYPE [32] = | |
772 { /* C B A Z Y */ | |
773 0x00, /* 0 0 0 0 0 -> Type A */ | |
774 0x01, /* 0 0 0 0 1 -> Type B */ | |
775 0x02, /* 0 0 0 1 0 -> Type C */ | |
776 0x02, /* 0 0 0 1 1 -> Type C */ | |
777 0x03, /* 0 0 1 0 0 -> Type D */ | |
778 0x03, /* 0 0 1 0 1 -> Type D */ | |
779 0x03, /* 0 0 1 1 0 -> Type D */ | |
780 0x03, /* 0 0 1 1 1 -> Type D */ | |
781 0x04, /* 0 1 0 0 0 -> Type E */ | |
782 0x04, /* 0 1 0 0 1 -> Type E */ | |
783 0x04, /* 0 1 0 1 0 -> Type E */ | |
784 0x04, /* 0 1 0 1 1 -> Type E */ | |
785 0x05, /* 0 1 1 0 0 -> Type F */ | |
786 0x05, /* 0 1 1 0 1 -> Type F */ | |
787 0x05, /* 0 1 1 1 0 -> Type F */ | |
788 0x05, /* 0 1 1 1 1 -> Type F */ | |
789 0xFF, /* 1 0 0 0 0 -> Not valid */ | |
790 0xFF, /* 1 0 0 0 1 -> Not valid */ | |
791 0xFF, /* 1 0 0 1 0 -> Not valid */ | |
792 0xFF, /* 1 0 0 1 1 -> Not valid */ | |
793 0xFF, /* 1 0 1 0 0 -> Not valid */ | |
794 0xFF, /* 1 0 1 0 1 -> Not valid */ | |
795 0xFF, /* 1 0 1 1 0 -> Not valid */ | |
796 0xFF, /* 1 0 1 1 1 -> Not valid */ | |
797 0xFF, /* 1 1 0 0 0 -> Not valid */ | |
798 0xFF, /* 1 1 0 0 1 -> Not valid */ | |
799 0xFF, /* 1 1 0 1 0 -> Not valid */ | |
800 0xFF, /* 1 1 0 1 1 -> Not valid */ | |
801 0x06, /* 1 1 1 0 0 -> Type I */ | |
802 0x06, /* 1 1 1 0 1 -> Type I */ | |
803 0x06, /* 1 1 1 1 0 -> Type I */ | |
804 0x06 /* 1 1 1 1 1 -> Type I */ | |
805 }; | |
806 | |
807 | |
808 GLOBAL void dat_for_close_loop_cmd (T_DL_DATA_IND * dl_data_ind, | |
809 UBYTE subchannel) | |
810 { | |
811 GET_INSTANCE_DATA; | |
812 UBYTE loop_command = NOT_PRESENT_8BIT; | |
813 | |
814 TRACE_FUNCTION ("dat_for_close_loop_cmd()"); | |
815 | |
816 if (dat_test_sim_available () OR !dat_check_sim_available () ) | |
817 { | |
818 /* | |
819 * only if a test SIM card is inserted | |
820 */ | |
821 if ((rr_data->tch_loop_subch EQ NOT_PRESENT_8BIT) AND | |
822 rr_data->sc_data.chan_desc.chan_type < CH_SDCCH_4_0) | |
823 { | |
824 switch ((loop_command = LOOP_TYPE [(subchannel>>1) & 0x1F])) | |
825 { | |
826 case TCH_LOOP_C: /* Loop C */ | |
827 /* first send ACK msg, then activate L1 */ | |
828 send_close_tch_loop_ack_to_nw(); | |
829 /* | |
830 * Delay to allow L1/HW to switch | |
831 */ | |
832 vsi_t_sleep (VSI_CALLER DELAY_CLOSE_TCH_LOOP_ACK); | |
833 send_mph_tch_loop_req(dl_data_ind, loop_command); | |
834 /* will be needed when TCH Open Loop Command will be received */ | |
835 rr_data->tch_loop_subch = loop_command; | |
836 break; | |
837 case TCH_LOOP_I: /* Loop I */ | |
838 if (rr_data->sc_data.ch_mode NEQ CM_AMR) | |
839 { | |
840 PFREE (dl_data_ind); | |
841 break; | |
842 } | |
843 case TCH_LOOP_A: | |
844 case TCH_LOOP_B: | |
845 case TCH_LOOP_D: | |
846 case TCH_LOOP_E: | |
847 case TCH_LOOP_F: | |
848 /* Loop A, B, D, E, F, I */ | |
849 send_mph_tch_loop_req(dl_data_ind, loop_command); | |
850 /* | |
851 * Delay to allow L1/HW to switch | |
852 */ | |
853 vsi_t_sleep (VSI_CALLER DELAY_CLOSE_TCH_LOOP_ACK); | |
854 send_close_tch_loop_ack_to_nw(); | |
855 /* will be needed when TCH Open Loop Command will be received */ | |
856 rr_data->tch_loop_subch = loop_command; | |
857 break; | |
858 default : | |
859 TRACE_EVENT_P1("TCH_LOOP_CLOSE_CMD : wrong subchannel (%x)", subchannel); | |
860 PFREE (dl_data_ind); | |
861 break; | |
862 } | |
863 } | |
864 else | |
865 { | |
866 PFREE (dl_data_ind); | |
867 } | |
868 } | |
869 else | |
870 { | |
871 PFREE (dl_data_ind); | |
872 } | |
873 } | |
874 | |
875 /* | |
876 +--------------------------------------------------------------------+ | |
877 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
878 | STATE : code ROUTINE : dat_for_test_interface | | |
879 +--------------------------------------------------------------------+ | |
880 | |
881 PURPOSE : Reception of a Test-Interface message. | |
882 | |
883 */ | |
884 | |
885 GLOBAL void dat_for_test_interface (T_DL_DATA_IND * dl_data_ind, | |
886 UBYTE tested_device) | |
887 { | |
888 TRACE_FUNCTION ("dat_for_test_interface()"); | |
889 | |
890 if (dat_test_sim_available ()) | |
891 { | |
892 /* | |
893 * Only if a test SIM card is inserted | |
894 * | |
895 * then configure layer 1 | |
896 */ | |
897 PREUSE (dl_data_ind, dai_req, MPH_DAI_REQ); /* T_MPH_DAI_REQ */ | |
898 | |
899 dai_req->device = tested_device; | |
900 | |
901 EM_TEST_INTERFACE; | |
902 | |
903 PSENDX (PL, dai_req); | |
904 } | |
905 else | |
906 { | |
907 /* | |
908 * else ignore the message | |
909 */ | |
910 PFREE (dl_data_ind); | |
911 } | |
912 } | |
913 | |
914 /* | |
915 +--------------------------------------------------------------------+ | |
916 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
917 | STATE : code ROUTINE : dat_for_ciph_cmd | | |
918 +--------------------------------------------------------------------+ | |
919 | |
920 PURPOSE : Reception of a cipher mode command message. | |
921 | |
922 */ | |
923 | |
924 GLOBAL void dat_for_ciph_cmd (T_DL_DATA_IND *dl_data_ind, | |
925 T_D_CIPH_CMD *ciph_cmd) | |
926 { | |
927 GET_INSTANCE_DATA; | |
928 TRACE_FUNCTION ("dat_for_cyph_cmd()"); | |
929 | |
930 if (dat_check_error_flag (SEND_RR_STATUS)) | |
931 { | |
932 /* | |
933 * the check in the formatter was successful | |
934 */ | |
935 if ( | |
936 ((rr_data->sc_data.ciph_on EQ CIPH_ON) AND | |
937 (ciph_cmd->ciph_mode_set.sc EQ START_CIPH_YES)) | |
938 OR | |
939 ((ciph_cmd->ciph_mode_set.sc EQ START_CIPH_YES) AND | |
940 (rr_data->dyn_config.nkc EQ 0 AND rr_data->ms_data.cksn > 6)) | |
941 ) | |
942 { | |
943 /* | |
944 * Respond with RR Status in 2 cases | |
945 * | |
946 * 1: if NW re-enables ciphering | |
947 * 2: if network has enabled ciphering "and" no valid ciphering key | |
948 * is available (and user specific handling of cksn is | |
949 * disabled (nck==0)). | |
950 * If network has not enabled ciphering, then ciphering key | |
951 * value is not checked | |
952 */ | |
953 dat_send_rr_status_msg(RRC_PROT_UNSPECIFIED); | |
954 } | |
955 else | |
956 { | |
957 MCAST (ciph_comp, U_CIPH_COMP); | |
958 PALLOC_MSG (dl_data_req, DL_DATA_REQ, U_CIPH_COMP); | |
959 | |
960 /* | |
961 * set channel type and SAPI for response to the network | |
962 */ | |
963 dat_code_prr_channel (&dl_data_req->ch_type, | |
964 &dl_data_req->sapi, | |
965 rr_data->sc_data.chan_desc.chan_type); | |
966 | |
967 /* | |
968 * store cipher parameter | |
969 */ | |
970 rr_data->sc_data.ciph_on = ciph_cmd->ciph_mode_set.sc; | |
971 | |
972 rr_data->sc_data.algo = ciph_cmd->ciph_mode_set.algo_ident; | |
973 rr_data->sc_data.ciph_received = TRUE; | |
974 memcpy (rr_data->ms_data.kc, rr_data->ms_data.new_kc, KC_STRING_SIZE); | |
975 | |
976 /* | |
977 * configure layer 1 | |
978 */ | |
979 | |
980 if ( rr_data->ms_data.cksn <= 6 ) | |
981 { | |
982 dat_code_mph_ciphering_req (rr_data->sc_data.ciph_on, | |
983 rr_data->sc_data.algo, | |
984 rr_data->ms_data.kc); | |
985 } | |
986 else | |
987 { | |
988 dat_code_mph_ciphering_req (CIPH_OFF, 0, NULL); | |
989 } | |
990 | |
991 if (ciph_cmd->ciph_res.cr EQ INC_IMEISV_YES) | |
992 { | |
993 /* | |
994 * if the response shall contain the IMEI, fill it in. | |
995 */ | |
996 ciph_comp->v_mob_ident = TRUE; | |
997 memcpy (&ciph_comp->mob_ident, &rr_data->ms_data.imei, | |
998 sizeof (T_mob_ident)); | |
999 } | |
1000 else | |
1001 { | |
1002 ciph_comp->v_mob_ident = FALSE; | |
1003 } | |
1004 | |
1005 ciph_comp->msg_type = U_CIPH_COMP; | |
1006 | |
1007 /* | |
1008 * send response to the network | |
1009 */ | |
1010 for_dat_data_req (dl_data_req); | |
1011 | |
1012 /* | |
1013 * Indicate changed ciphering mode to MM. | |
1014 * Any supression of ciphering information to MMI/ACI will | |
1015 * be done by the upper layers. | |
1016 */ | |
1017 dat_code_ciphering_to_mm (rr_data->sc_data.ciph_on); | |
1018 | |
1019 EM_CIPHERING_CMD; | |
1020 } | |
1021 } | |
1022 | |
1023 PFREE (dl_data_ind); | |
1024 } | |
1025 | |
1026 /* | |
1027 +--------------------------------------------------------------------+ | |
1028 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
1029 | STATE : code ROUTINE : dat_for_freq_redef | | |
1030 +--------------------------------------------------------------------+ | |
1031 | |
1032 PURPOSE : Reception of a frequency redefinition message. | |
1033 | |
1034 */ | |
1035 | |
1036 GLOBAL void dat_for_freq_redef (T_DL_DATA_IND *dl_data_ind, | |
1037 T_D_FREQ_REDEF *freq_redef, | |
1038 T_LIST *cell_chan_desc) | |
1039 { | |
1040 GET_INSTANCE_DATA; | |
1041 T_start start; | |
1042 T_LIST hop_list; | |
1043 UBYTE mob_alloc[65]; | |
1044 | |
1045 TRACE_FUNCTION ("dat_for_freq_redef()"); | |
1046 | |
1047 if (dat_check_error_flag (SEND_RR_STATUS)) | |
1048 { | |
1049 /* | |
1050 * the check in the formatter has passed | |
1051 */ | |
1052 memcpy (&rr_data->sc_data.chan_desc, | |
1053 &freq_redef->chan_desc, | |
1054 sizeof (T_chan_desc)); | |
1055 | |
1056 /* | |
1057 * convert the mobile allocation from the message format | |
1058 * to a list of 1-bit positions to build the hopping list. | |
1059 */ | |
1060 att_bits_to_byte (mob_alloc, | |
1061 freq_redef->mob_alloc.c_mac, | |
1062 freq_redef->mob_alloc.mac); | |
1063 | |
1064 dat_set_last_used_channel (&rr_data->sc_data.chan_desc); | |
1065 | |
1066 if (freq_redef->v_cell_chan_desc) | |
1067 { | |
1068 /* | |
1069 * if the message contains a new cell channel description | |
1070 * copy the new one, else use the old one. | |
1071 */ | |
1072 srv_copy_list (&rr_data->sc_data.cd.cell_chan_desc, | |
1073 cell_chan_desc, | |
1074 sizeof (T_LIST)); | |
1075 rr_data->sc_data.cd.v_cell_chan_desc = WITH_CONTENT; | |
1076 } | |
1077 | |
1078 if (rr_data->sc_data.cd.v_cell_chan_desc NEQ NO_CONTENT) | |
1079 { | |
1080 /* | |
1081 * create the hopping list from cell channel description and | |
1082 * mobile allocation. | |
1083 */ | |
1084 if(! srv_create_chan_mob_alloc (&rr_data->sc_data.cd.cell_chan_desc, | |
1085 &hop_list, | |
1086 mob_alloc)) | |
1087 { | |
1088 | |
1089 U32 st = 51*((26 + freq_redef->start_time.t3 - freq_redef->start_time.t2 )%26) | |
1090 + freq_redef->start_time.t3 + 1326*freq_redef->start_time.t1; | |
1091 U32 ct = dl_data_ind->fn%STARTING_TIME_INTERVAL; | |
1092 | |
1093 #if defined(_SIMULATION_) | |
1094 TRACE_EVENT_WIN_P5 ("D_FREQ_REDEF: t1=%u t2=%u t3=%u, st=%u, ct=%u", | |
1095 freq_redef->start_time.t1, freq_redef->start_time.t2, | |
1096 freq_redef->start_time.t3, st, ct); | |
1097 TRACE_EVENT_WIN_P2 ("D_FREQ_REDEF: (st-ct) %u <= %u ?", | |
1098 ((STARTING_TIME_INTERVAL + st - ct)%STARTING_TIME_INTERVAL), STARTING_TIME_INTERVAL1); | |
1099 #endif | |
1100 | |
1101 if(((STARTING_TIME_INTERVAL + st - ct)%STARTING_TIME_INTERVAL) <= STARTING_TIME_INTERVAL1) | |
1102 { | |
1103 /*XXX this should only be done if the starting time has not yet expired */ | |
1104 dat_send_rr_status_msg(RRC_FREQ_NOT_IMPL); | |
1105 } | |
1106 else | |
1107 { | |
1108 /* | |
1109 * 3GPP TS 04.18, section 3.4.5.1 | |
1110 * Frequency redefinition procedure, abnormal cases: | |
1111 * If the mobile station receives a FREQUENCY REDEFINITION message | |
1112 * with a Mobile Allocation IE indexing frequencies that are not all | |
1113 * in one band and a Starting Time IE indicating a time that has | |
1114 * elapsed, then the mobile station shall locally abort the radio | |
1115 * connection and, if permitted, attempt Call Re-establishment. | |
1116 * | |
1117 * Inform MM about a radio link failure and start cell reselection. | |
1118 * It would be possible to create a new cause but RLF does exactly | |
1119 * what is needed and this is really 'some kind of' RLF. | |
1120 */ | |
1121 rr_data->net_lost = TRUE; | |
1122 att_code_rr_abort_ind (RRCS_ABORT_RAD_LNK_FAIL); | |
1123 att_stop_dedicated(); | |
1124 } | |
1125 } | |
1126 else | |
1127 { | |
1128 /* | |
1129 * copy start time for the new hopping list | |
1130 */ | |
1131 start.v_start = TRUE; | |
1132 start.t1 = freq_redef->start_time.t1; | |
1133 start.t2 = freq_redef->start_time.t2; | |
1134 start.t3 = freq_redef->start_time.t3; | |
1135 | |
1136 /* | |
1137 * configure layer 1 with the new hopping list | |
1138 */ | |
1139 dat_code_mph_freq_redef_req (&start, | |
1140 &hop_list); | |
1141 } | |
1142 } | |
1143 } | |
1144 | |
1145 PFREE (dl_data_ind); | |
1146 } | |
1147 | |
1148 /* | |
1149 +--------------------------------------------------------------------+ | |
1150 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
1151 | STATE : code ROUTINE : dat_for_handov_cmd | | |
1152 +--------------------------------------------------------------------+ | |
1153 | |
1154 PURPOSE : Reception of a handover command message. | |
1155 | |
1156 */ | |
1157 | |
1158 GLOBAL void dat_for_handov_cmd (T_DL_DATA_IND *dl_data_ind, | |
1159 T_D_HANDOV_CMD *handov_cmd, | |
1160 T_LIST *cell_chan_desc, | |
1161 T_LIST *hop_list_after, | |
1162 T_LIST *hop_list_before) | |
1163 { | |
1164 GET_INSTANCE_DATA; | |
1165 UBYTE mob_alloc [65]; | |
1166 | |
1167 TRACE_FUNCTION ("dat_for_handov_cmd()"); | |
1168 | |
1169 rr_data->dyn_config.fho = 0; | |
1170 | |
1171 /* | |
1172 * dynamic configuration command : IHO | |
1173 * Lock the DUT to the cell it is already camping - | |
1174 * Ignore the Handover command message and send an | |
1175 * Handover failure message to the network. | |
1176 */ | |
1177 | |
1178 if(rr_data->dyn_config.iho AND (rr_data->sc_data.ch_mode EQ CM_AMR)) | |
1179 { | |
1180 TRACE_EVENT("D_HANDOV_CMD : IHO"); | |
1181 for_set_content_error (RRC_CHANNEL_MODE); | |
1182 } | |
1183 | |
1184 switch (rr_data->ms_data.error.cs) | |
1185 { | |
1186 /* | |
1187 * in case of mandatory info element error, | |
1188 * the message is returned immediately. | |
1189 */ | |
1190 /* case RRC_INVALID_MAN_INFO: this value is currently never set */ | |
1191 case RRC_COND_IE_ERROR: | |
1192 { | |
1193 /* | |
1194 * build a RR status message. | |
1195 */ | |
1196 dat_send_rr_status_msg(rr_data->ms_data.error.cs); | |
1197 PFREE (dl_data_ind); | |
1198 break; | |
1199 } | |
1200 | |
1201 case RRC_INCORRECT_MSG: | |
1202 { | |
1203 /* | |
1204 * If a structurally correct message has been detected, | |
1205 * containing erroneous data, an Assignment Failure message | |
1206 * is sent back. | |
1207 */ | |
1208 | |
1209 /* | |
1210 * Even though it's not possible to go onto the new channel | |
1211 * we still need to suspend the current link and send the | |
1212 * HANDOVER FAILURE command via a priority DL_RECONNECT_REQ. | |
1213 * This ensures DL will halt processing anything in its | |
1214 * buffer until it has sent this message onto the nw | |
1215 */ | |
1216 for_suspend_layer_2 (); | |
1217 dat_send_handov_fail_msg(rr_data->ms_data.error.val); | |
1218 | |
1219 RR_EM_SET_HANDOVER_FAIL_CAUSE(rr_data->ms_data.error.val); | |
1220 | |
1221 PFREE (dl_data_ind); | |
1222 break; | |
1223 } | |
1224 | |
1225 default: | |
1226 /* | |
1227 * the message check has passed. | |
1228 * first of all suspend current layer 2 link | |
1229 */ | |
1230 | |
1231 TRACE_EVENT_P1 ("HO:default (%02x)", rr_data->ms_data.error.cs); | |
1232 | |
1233 for_suspend_layer_2 (); | |
1234 | |
1235 /* | |
1236 * set for the optional information elements | |
1237 * of the handover message the default value | |
1238 * to the current serving cell value. | |
1239 */ | |
1240 rr_data->cr_data.ch_mode = rr_data->sc_data.ch_mode; | |
1241 rr_data->cr_data.ciph_on = rr_data->sc_data.ciph_on; | |
1242 rr_data->cr_data.algo = rr_data->sc_data.algo; | |
1243 rr_data->cr_data.cd.v_cell_chan_desc = | |
1244 rr_data->sc_data.cd.v_cell_chan_desc; | |
1245 memcpy (&rr_data->cr_data.cd.cell_chan_desc, | |
1246 &rr_data->sc_data.cd.cell_chan_desc, | |
1247 sizeof (T_LIST)); | |
1248 | |
1249 /* | |
1250 * if AMR is supported set the default values | |
1251 * to the current serving cell values. | |
1252 */ | |
1253 if(rr_data->sc_data.ch_mode EQ CM_AMR) | |
1254 { | |
1255 memcpy(&rr_data->cr_data.amr_conf, | |
1256 &rr_data->sc_data.amr_conf, | |
1257 sizeof (T_multirate_conf)); | |
1258 } | |
1259 else { | |
1260 /* | |
1261 * AMR is not supported, therefore set some dummy values. This is necessary because | |
1262 * the later Layer1 configuration must include an AMR configuration!! | |
1263 */ | |
1264 memset(&rr_data->cr_data.amr_conf, 0, sizeof (T_multirate_conf)); | |
1265 } | |
1266 | |
1267 /* | |
1268 * set BSIC, BCCH channel number and channel description from | |
1269 * the handover command. | |
1270 */ | |
1271 rr_data->nc_data[CR_INDEX].bsic = (handov_cmd->cell_desc.ncc << 3) + | |
1272 handov_cmd->cell_desc.bcc; | |
1273 rr_data->nc_data[CR_INDEX].arfcn = handov_cmd->cell_desc.bcch_arfcn_lo + | |
1274 (handov_cmd->cell_desc.bcch_arfcn_hi << 8); | |
1275 memcpy (&rr_data->cr_data.chan_desc, | |
1276 &handov_cmd->chan_desc_after, | |
1277 sizeof (T_chan_desc)); | |
1278 | |
1279 if (handov_cmd->v_synch_ind) | |
1280 { | |
1281 /* | |
1282 * store the Handover synchronisation information if available. | |
1283 */ | |
1284 memcpy (&rr_data->ms_data.ho_type, &handov_cmd->synch_ind, | |
1285 sizeof (T_synch_ind)); | |
1286 } | |
1287 else | |
1288 { | |
1289 /* | |
1290 * else set the values to the default values. | |
1291 */ | |
1292 rr_data->ms_data.ho_type.rot = TIME_DIFF_NO; | |
1293 rr_data->ms_data.ho_type.nci = TRUE; | |
1294 rr_data->ms_data.ho_type.si = SYI_NON_SYNCH; | |
1295 } | |
1296 | |
1297 if (rr_data->ms_data.ho_type.si EQ SYI_PSEUDO_SYNCH AND | |
1298 ! rr_data->ms_data.classmark2.ps) | |
1299 { | |
1300 /* | |
1301 * if the handover requests a pseudo synchronized handover | |
1302 * and the mobile does not support this, a handover failure | |
1303 * message is send and the procedure is aborted with | |
1304 * reconnection to the old channel. | |
1305 */ | |
1306 dat_send_handov_fail_msg(RRC_INCORRECT_MSG); | |
1307 | |
1308 RR_EM_SET_HANDOVER_FAIL_CAUSE(RRC_INCORRECT_MSG); | |
1309 | |
1310 PFREE (dl_data_ind); | |
1311 return; | |
1312 } | |
1313 else | |
1314 { | |
1315 if (handov_cmd->v_cell_chan_desc) | |
1316 { | |
1317 /* | |
1318 * if the handover command contains a new cell channel description | |
1319 * copy the new list. | |
1320 */ | |
1321 srv_copy_list (&rr_data->cr_data.cd.cell_chan_desc, | |
1322 cell_chan_desc, | |
1323 sizeof (T_LIST)); | |
1324 rr_data->cr_data.cd.v_cell_chan_desc = WITH_CHANGED_CONTENT; | |
1325 } | |
1326 | |
1327 if (handov_cmd->v_chan_mode) | |
1328 { | |
1329 /* | |
1330 * store a new channel mode if available. | |
1331 */ | |
1332 rr_data->cr_data.ch_mode = handov_cmd->chan_mode; | |
1333 } | |
1334 | |
1335 | |
1336 /* | |
1337 * If AMR is signalled check if new multi-rate speech codec is part of the handover cmd | |
1338 * otherwise use default values set earlier. If AMR is not signalled use the dummy values | |
1339 * instead either set earlier. | |
1340 */ | |
1341 | |
1342 /* Implements RR Clone findings #9 */ | |
1343 dat_cr_data_multirate_conf(handov_cmd->v_multirate_conf, &handov_cmd->multirate_conf); | |
1344 | |
1345 | |
1346 if (handov_cmd->v_ciph_mode_set) | |
1347 { | |
1348 /* | |
1349 * if the message contains cipher mode parameter | |
1350 * copy the parameters | |
1351 */ | |
1352 rr_data->cr_data.ciph_on = handov_cmd->ciph_mode_set.sc; | |
1353 rr_data->cr_data.algo = handov_cmd->ciph_mode_set.algo_ident; | |
1354 | |
1355 /* | |
1356 * if ciphering is already enabled and the handover command | |
1357 * requests ciphering again, the procedure is aborted with | |
1358 * a handover failure message. | |
1359 */ | |
1360 if (rr_data->cr_data.ciph_on EQ CIPH_ON AND | |
1361 rr_data->sc_data.ciph_received EQ FALSE) | |
1362 { | |
1363 dat_send_handov_fail_msg(RRC_PROT_UNSPECIFIED); | |
1364 | |
1365 RR_EM_SET_HANDOVER_FAIL_CAUSE(RRC_PROT_UNSPECIFIED); | |
1366 | |
1367 PFREE (dl_data_ind); | |
1368 return; | |
1369 } | |
1370 } | |
1371 | |
1372 if(handov_cmd->v_mob_alloc_after) | |
1373 { | |
1374 if(dat_for_handover_mob_alloc(mob_alloc, hop_list_after, (T_VOID_STRUCT *) &handov_cmd->mob_alloc_after,dl_data_ind)) | |
1375 return; | |
1376 } | |
1377 | |
1378 if(handov_cmd->v_mob_alloc_before) | |
1379 { | |
1380 if(dat_for_handover_mob_alloc(mob_alloc, hop_list_before, (T_VOID_STRUCT *) &handov_cmd->mob_alloc_before,dl_data_ind)) | |
1381 return; | |
1382 } | |
1383 | |
1384 /* | |
1385 * Handover resets a SAPI 3 connection for SMS | |
1386 */ | |
1387 SET_STATE (STATE_SAPI_3, SMS_IDLE); | |
1388 PFREE (dl_data_ind); | |
1389 { | |
1390 /* | |
1391 * All Parameters are checked | |
1392 * Now the handover is started | |
1393 */ | |
1394 PALLOC (dedicated_req, MPH_DEDICATED_REQ); | |
1395 | |
1396 memset (dedicated_req, 0, sizeof (T_MPH_DEDICATED_REQ)); | |
1397 | |
1398 if (handov_cmd->v_start_time) | |
1399 { | |
1400 /* | |
1401 * copy starting time if available. | |
1402 */ | |
1403 dedicated_req->start.v_start = TRUE; | |
1404 dedicated_req->start.t1 = handov_cmd->start_time.t1; | |
1405 dedicated_req->start.t2 = handov_cmd->start_time.t2; | |
1406 dedicated_req->start.t3 = handov_cmd->start_time.t3; | |
1407 } | |
1408 | |
1409 /* | |
1410 * Calculate observed time difference | |
1411 */ | |
1412 { | |
1413 UBYTE i1; | |
1414 ULONG fn_offset; | |
1415 | |
1416 rr_data->sc_data.observed_ta = 0; | |
1417 for (i1 = 0; i1< rr_data->ms_data.measurement_report.ncells.no_of_ncells; i1++) | |
1418 { | |
1419 /* | |
1420 * find the handover cell inn the neighbourcells of the last measurement report | |
1421 */ | |
1422 if (rr_data->nc_data[CR_INDEX].arfcn EQ | |
1423 rr_data->ms_data.measurement_report.ncells.arfcn[i1]) | |
1424 { | |
1425 /* | |
1426 * According to 05.10 OTD is defined as the timing difference | |
1427 * between BTS0 and BTS1 ( system time in BTS 0 minus that of | |
1428 * BTS 1..), with BTS1 as the new cell (neighbour cell, HO | |
1429 * Target cell) and BTS0 and the current cell (serving cell) | |
1430 */ | |
1431 fn_offset = (HYPERFRAME - | |
1432 rr_data->ms_data.measurement_report.ncells.frame_offset[i1]) | |
1433 % HYPERFRAME; | |
1434 | |
1435 /* | |
1436 * calculate the observed time difference from the relative | |
1437 * time difference of neighbourcell and serving cell | |
1438 * (given by time_alignment and frame offset) and the observed | |
1439 * time difference of the serving cell (coming from timing | |
1440 * advance in layer 1 header of the downlink SACCH messages). | |
1441 */ | |
1442 /* | |
1443 * A.1.3 of 3GPP TS 05.10 | |
1444 * after successful handover, either synchronized, | |
1445 * non-synchronized or pseudo-synchronized, the MS shall | |
1446 * provide to BTS 1 the value of OTD + t0 in the | |
1447 * "HANDOVER COMPLETE" message. | |
1448 * | |
1449 * NOTE : measurement_report.otd is the TA sent by the | |
1450 * network in downlink SACCH. TA is roundtrip propogation | |
1451 * delay in bit periods. | |
1452 * t0 denotes the "one way" line of sight propagation delay | |
1453 * between the MS and BTS 0, in "half bits". | |
1454 * t0 = measurement_report.otd * 2 / 2. | |
1455 */ | |
1456 rr_data->sc_data.observed_ta = | |
1457 ( (rr_data->ms_data.measurement_report.ncells.time_alignmt[i1] | |
1458 + fn_offset* QUARTER_BITS_PER_FRAME)/2 | |
1459 + rr_data->ms_data.measurement_report.otd ) % 2097152; | |
1460 } | |
1461 } | |
1462 } | |
1463 | |
1464 dedicated_req->ho_param.ho_nci = rr_data->ms_data.ho_type.nci; | |
1465 | |
1466 /* | |
1467 * Set the handover mode | |
1468 */ | |
1469 switch (rr_data->ms_data.ho_type.si) | |
1470 { | |
1471 case SYI_NON_SYNCH: | |
1472 /* | |
1473 * asynchronous handover | |
1474 */ | |
1475 dedicated_req->mod = MODE_ASYNC_HANDOVER; | |
1476 break; | |
1477 | |
1478 case SYI_NORM_SYNCH: | |
1479 /* | |
1480 * synchronous handover | |
1481 */ | |
1482 rr_data->sc_data.new_ta = rr_data->ms_data.measurement_report.otd/2; | |
1483 att_set_tim_advance_info(); | |
1484 dedicated_req->mod = MODE_SYNC_HANDOVER; | |
1485 break; | |
1486 | |
1487 case SYI_PRE_SYNCH: | |
1488 /* | |
1489 * pre-synchronized handover | |
1490 */ | |
1491 dedicated_req->mod = MODE_PRE_SYNC_HANDOVER; | |
1492 | |
1493 if (handov_cmd->v_time_advance) | |
1494 /* | |
1495 * if the handover command contains a new timing advance | |
1496 */ | |
1497 dedicated_req->tr_para.tav = handov_cmd->time_advance.ta; | |
1498 else | |
1499 /* | |
1500 * else set the default value 1 | |
1501 */ | |
1502 dedicated_req->tr_para.tav = 1; | |
1503 | |
1504 rr_data->sc_data.new_ta = dedicated_req->tr_para.tav * 2; | |
1505 att_set_tim_advance_info(); | |
1506 break; | |
1507 | |
1508 case SYI_PSEUDO_SYNCH: | |
1509 /* | |
1510 * pseudo-synchronized handover | |
1511 */ | |
1512 dedicated_req->mod = MODE_PSEUDO_SYNC_HANDOVER; | |
1513 dedicated_req->tr_para.tav = handov_cmd->time_diff; | |
1514 rr_data->sc_data.new_ta = dedicated_req->tr_para.tav; | |
1515 att_set_tim_advance_info(); | |
1516 break; | |
1517 } | |
1518 | |
1519 /* | |
1520 * Set Channel Type | |
1521 */ | |
1522 dedicated_req->ch_type.ch = handov_cmd->chan_desc_after.chan_type; | |
1523 dedicated_req->ch_type.tn = handov_cmd->chan_desc_after.tn; | |
1524 dedicated_req->ch_type.tsc = handov_cmd->chan_desc_after.tsc; | |
1525 dedicated_req->ch_type.h = handov_cmd->chan_desc_after.hop; | |
1526 | |
1527 if (handov_cmd->chan_desc_after.hop EQ H_NO) | |
1528 dedicated_req->ch_type.arfcn = handov_cmd->chan_desc_after.arfcn; | |
1529 else | |
1530 { | |
1531 dedicated_req->ch_type.maio = handov_cmd->chan_desc_after.maio; | |
1532 dedicated_req->ch_type.hsn = handov_cmd->chan_desc_after.hsn; | |
1533 | |
1534 /* CSI-LLD section:4.1.1.11 | |
1535 * This function Updates the black list with the MA list received | |
1536 * in the handover command | |
1537 */ | |
1538 cs_remove_BA_MA_from_black_list(rr_data->cs_data.region , hop_list_after); | |
1539 | |
1540 srv_create_list (hop_list_after, dedicated_req->ch_type.ma, | |
1541 MAX_MA_CHANNELS, TRUE, 0); | |
1542 } | |
1543 | |
1544 dedicated_req->bsic = rr_data->nc_data[CR_INDEX].bsic & 0x3F; | |
1545 dedicated_req->arfcn = rr_data->nc_data[CR_INDEX].arfcn; | |
1546 dedicated_req->ho_param.ho_ref = handov_cmd->handov_ref; | |
1547 dedicated_req->ho_param.ho_pow = handov_cmd->pow_cmd_access.pow; | |
1548 dedicated_req->ho_param.ho_acc_type = handov_cmd->pow_cmd_access.atc; | |
1549 dedicated_req->tr_para.mode = rr_data->cr_data.ch_mode; | |
1550 | |
1551 /* | |
1552 * Set multi-rate speech codec | |
1553 */ | |
1554 dedicated_req->amr_conf.nscb = rr_data->cr_data.amr_conf.nscb; | |
1555 dedicated_req->amr_conf.icmi = rr_data->cr_data.amr_conf.icmi; | |
1556 dedicated_req->amr_conf.st_mode = rr_data->cr_data.amr_conf.st_mode; | |
1557 dedicated_req->amr_conf.acs = rr_data->cr_data.amr_conf.set_amr; | |
1558 | |
1559 /* | |
1560 * valid flag for the threshold and hystersis values. amr_conf.c_cod_prop | |
1561 * defines the number of threshold and hystersis values. | |
1562 */ | |
1563 dedicated_req->amr_conf.v_cod_prop = rr_data->cr_data.amr_conf.v_cod_prop; | |
1564 if(dedicated_req->amr_conf.v_cod_prop) | |
1565 { | |
1566 int i; | |
1567 dedicated_req->amr_conf.c_cod_prop = rr_data->cr_data.amr_conf.c_cod_prop; | |
1568 for(i=0; i<dedicated_req->amr_conf.c_cod_prop; i++) | |
1569 memcpy(&dedicated_req->amr_conf.cod_prop[i], &rr_data->cr_data.amr_conf.cod_prop[i], sizeof(T_cod_prop)); | |
1570 } | |
1571 | |
1572 /* | |
1573 * Set Channel Type before starting time | |
1574 */ | |
1575 | |
1576 if (handov_cmd->v_chan_desc_before EQ FALSE) | |
1577 dedicated_req->ch_type2.ch = NOT_PRESENT_8BIT; | |
1578 else | |
1579 { | |
1580 | |
1581 /* Implements RR Clone findings #22 */ | |
1582 dat_dedicated_req_ch_type2(&dedicated_req->ch_type2, &handov_cmd->chan_desc_before, | |
1583 hop_list_before); | |
1584 } | |
1585 | |
1586 if (rr_data->cr_data.ciph_on) | |
1587 { | |
1588 /* | |
1589 * set cipher parameter | |
1590 */ | |
1591 dedicated_req->ciph.stat = rr_data->cr_data.ciph_on; | |
1592 dedicated_req->ciph.algo = rr_data->cr_data.algo; | |
1593 memcpy (dedicated_req->ciph.kc, rr_data->ms_data.kc, KC_STRING_SIZE); | |
1594 } | |
1595 | |
1596 /* | |
1597 * clear neighbourcell lists for the new cell. | |
1598 */ | |
1599 srv_clear_list (&rr_data->sc_data.cd.ncell_list); | |
1600 srv_clear_list (&rr_data->sc_data.five_ter_list); | |
1601 | |
1602 att_clean_buf (IND_ALL_DEDI_SI); | |
1603 | |
1604 rr_data->sc_data.cd.sys_info_read &= ~ALL_DEDI_SYS_INFOS; | |
1605 | |
1606 SET_STATE (STATE_DAT, DAT_HANDOVER); | |
1607 | |
1608 #if defined (REL99) && defined (TI_PS_FF_EMR) | |
1609 /*clear EMR parameters also, if present*/ | |
1610 if (rr_data->sc_data.enh_para_status EQ ENH_PARA_DEDICATED ) | |
1611 { | |
1612 /*discard the enhanced para that were related to BA(SACCH) before HO*/ | |
1613 rr_data->sc_data.enh_para_status = ENH_PARA_INVALID_STATE; | |
1614 memset (rr_data->sc_data.rep_count, NOT_PRESENT_8BIT, MAX_NEIGHBOURCELLS); | |
1615 for_set_default_emr_data(&rr_data->sc_data.emr_data_current); | |
1616 /*Indicate to ALR that enhanced para are invalid*/ | |
1617 attf_send_enh_para_to_alr(rr_data->sc_data.emr_data_current.rep_type, | |
1618 &rr_data->sc_data.emr_data_current.enh_para); | |
1619 } | |
1620 #endif | |
1621 | |
1622 RR_EM_GET_HOPPING_CHANNEL (dedicated_req->ch_type.ma, dedicated_req->ch_type2.ma, | |
1623 dedicated_req->start.v_start,dedicated_req->ch_type2.maio); | |
1624 | |
1625 EM_HANDOVER_CMD; | |
1626 | |
1627 #if defined FF_EOTD | |
1628 if ( rr_data->eotd_req_id NEQ NOT_PRESENT_16BIT ) | |
1629 { | |
1630 PALLOC (rrlc_error_ind, RRLC_ERROR_IND); | |
1631 rrlc_error_ind->cause = LCS_HANDOVER; | |
1632 | |
1633 rr_data->eotd_req_id = NOT_PRESENT_16BIT; | |
1634 | |
1635 PSENDX (LC, rrlc_error_ind); | |
1636 } | |
1637 #endif /* FF_EOTD */ | |
1638 | |
1639 /* | |
1640 * configure layer 1. | |
1641 */ | |
1642 PSENDX (PL, dedicated_req); | |
1643 } | |
1644 } /* else */ | |
1645 } /* switch */ | |
1646 } | |
1647 | |
1648 /* | |
1649 +--------------------------------------------------------------------+ | |
1650 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
1651 | STATE : code ROUTINE : stop_rach_and_enter_idle | | |
1652 +--------------------------------------------------------------------+ | |
1653 | |
1654 PURPOSE : Invalid frequency list received during Immediate Assignment | |
1655 procedure. The sending of Channel Request messages is | |
1656 stopped and Idle Mode entered. | |
1657 */ | |
1658 | |
1659 LOCAL void stop_rach_and_enter_idle(void) | |
1660 { | |
1661 PALLOC (mph_random_access_req, MPH_RANDOM_ACCESS_REQ); | |
1662 | |
1663 TRACE_ERROR ("invalid frequencies (Frequency Hopping)"); | |
1664 | |
1665 TIMERSTOP (T3122); | |
1666 TIMERSTOP (T3126); | |
1667 | |
1668 /* | |
1669 * Stop sending Random Burst | |
1670 */ | |
1671 memset (&mph_random_access_req->send_mode, 0, sizeof (T_send_mode)); | |
1672 PSENDX (PL, mph_random_access_req); | |
1673 | |
1674 dat_send_release_ind (RRCS_INVALID_HOP_FREQ); | |
1675 | |
1676 /*SET_STATE (STATE_DAT, DAT_IDLE); | |
1677 att_build_idle_req (SC_INDEX, MODE_CELL_SELECTION);*/ | |
1678 | |
1679 #ifdef GPRS | |
1680 att_start_cell_reselection_gprs (CELL_RESELECTION_RACH); | |
1681 #else | |
1682 att_start_cell_reselection (CELL_RESELECTION_RACH); | |
1683 #endif | |
1684 } | |
1685 | |
1686 /* | |
1687 +--------------------------------------------------------------------+ | |
1688 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
1689 | STATE : code ROUTINE : dat_for_imm_assign | | |
1690 +--------------------------------------------------------------------+ | |
1691 | |
1692 PURPOSE : Reception of an immediate assignment message. | |
1693 | |
1694 */ | |
1695 | |
1696 GLOBAL void dat_for_imm_assign (T_MPH_UNITDATA_IND *mph_unitdata_ind, | |
1697 T_D_IMM_ASSIGN *imm_assign) | |
1698 { | |
1699 GET_INSTANCE_DATA; | |
1700 T_SC_DATA *rrd = &rr_data->sc_data; | |
1701 T_start start; | |
1702 UBYTE mob_alloc [65]; | |
1703 T_LIST hop_list_bef; | |
1704 T_LIST hop_list_after; | |
1705 UBYTE maio; | |
1706 T_IA_REST ia_rest; | |
1707 UBYTE index = 0; | |
1708 | |
1709 TRACE_FUNCTION ("dat_for_imm_assign()"); | |
1710 | |
1711 switch (GET_STATE (STATE_DAT)) | |
1712 { | |
1713 #ifdef GPRS | |
1714 case DAT_IDLE: | |
1715 TRACE_EVENT("check dl idle"); | |
1716 dat_check_imm_assign_pch (mph_unitdata_ind, imm_assign); | |
1717 break; | |
1718 #endif | |
1719 | |
1720 case DAT_IMM_ASS: | |
1721 if (dat_check_error_flag (SEND_NO_RR_STATUS)) | |
1722 { | |
1723 #ifdef GPRS | |
1724 TRACE_EVENT("check dl pa"); | |
1725 if(GET_STATE(STATE_GPRS) EQ GPRS_PAM_BCCH AND | |
1726 dat_check_imm_assign_pch(mph_unitdata_ind, imm_assign)) | |
1727 return; | |
1728 #endif | |
1729 if (dat_compare_request_ref (&imm_assign->req_ref, &index)) | |
1730 { | |
1731 /* | |
1732 * the request reference in the immediate assignment | |
1733 * message matches to one of the last three channel | |
1734 * request messages. | |
1735 */ | |
1736 TRACE_EVENT("matched"); | |
1737 /* | |
1738 * check the channel description | |
1739 */ | |
1740 if(imm_assign->v_chan_desc) | |
1741 for_check_channel_descr (&imm_assign->chan_desc); | |
1742 | |
1743 /* was channel description ok? */ | |
1744 if(!dat_check_error_flag (SEND_NO_RR_STATUS)) | |
1745 return; | |
1746 #ifdef GPRS | |
1747 if(dat_check_gprs_imm_ass (mph_unitdata_ind, | |
1748 imm_assign, | |
1749 index)) | |
1750 return; | |
1751 #endif | |
1752 if (imm_assign->v_chan_desc) | |
1753 { | |
1754 if (imm_assign->chan_desc.hop AND | |
1755 imm_assign->mob_alloc.c_mac) | |
1756 { | |
1757 TRACE_EVENT ("create mob alloc (after st)"); | |
1758 /* | |
1759 * if the message contains a mobile allocation | |
1760 * build a hopping list together with the cell | |
1761 * channel description of system information | |
1762 * type 1 message. | |
1763 */ | |
1764 att_bits_to_byte (mob_alloc, | |
1765 imm_assign->mob_alloc.c_mac, | |
1766 imm_assign->mob_alloc.mac); | |
1767 if( rrd->cd.v_cell_chan_desc EQ NO_CONTENT OR | |
1768 !srv_create_chan_mob_alloc (&rrd->cd.cell_chan_desc, | |
1769 &hop_list_after, | |
1770 mob_alloc)) | |
1771 { | |
1772 stop_rach_and_enter_idle(); | |
1773 return; | |
1774 } | |
1775 } | |
1776 else | |
1777 { | |
1778 /* | |
1779 * else clear the hopping list | |
1780 */ | |
1781 srv_clear_list (&hop_list_after); | |
1782 } | |
1783 } | |
1784 else | |
1785 { | |
1786 TRACE_EVENT("IMM ASS discarded: neither sent to GRR nor channel description found"); | |
1787 return; /* for non-packet access we need a channel description */ | |
1788 } | |
1789 | |
1790 TRACE_EVENT("now get started"); | |
1791 if (imm_assign->v_start_time) | |
1792 { | |
1793 /* | |
1794 * if the message contains a starting time, | |
1795 * store the starting time. | |
1796 */ | |
1797 start.v_start = TRUE; | |
1798 start.t1 = imm_assign->start_time.t1; | |
1799 start.t2 = imm_assign->start_time.t2; | |
1800 start.t3 = imm_assign->start_time.t3; | |
1801 } | |
1802 else | |
1803 { | |
1804 /* | |
1805 * clear the starting time. | |
1806 */ | |
1807 memset (&start, 0, sizeof (T_start)); | |
1808 } | |
1809 | |
1810 /* | |
1811 * decode IA Rest Octet | |
1812 */ | |
1813 memset (&ia_rest, 0, sizeof (T_IA_REST)); | |
1814 | |
1815 ia_rest.ia_p = imm_assign->ia_rest_oct.flag_2bit; | |
1816 ia_rest.ia_maio = imm_assign->ia_rest_oct.ia_freq_par.maio; | |
1817 ia_rest.c_ia_mac = imm_assign->ia_rest_oct.ia_freq_par.c_mac; | |
1818 if (ia_rest.c_ia_mac > 9) | |
1819 ia_rest.c_ia_mac = 9; | |
1820 | |
1821 memcpy (ia_rest.ia_mac, | |
1822 &imm_assign->ia_rest_oct.ia_freq_par.mac, | |
1823 ia_rest.c_ia_mac); | |
1824 | |
1825 if (imm_assign->v_start_time AND | |
1826 imm_assign->chan_desc.hop AND | |
1827 ia_rest.ia_p EQ 2) | |
1828 { | |
1829 /* | |
1830 * calculate frequency list before starting time | |
1831 */ | |
1832 TRACE_EVENT("create mob alloc (before st)"); | |
1833 maio = ia_rest.ia_maio; | |
1834 | |
1835 att_bits_to_byte (mob_alloc, | |
1836 ia_rest.c_ia_mac, | |
1837 ia_rest.ia_mac); | |
1838 if(rrd->cd.v_cell_chan_desc EQ NO_CONTENT OR | |
1839 !srv_create_chan_mob_alloc (&rrd->cd.cell_chan_desc, | |
1840 &hop_list_bef, | |
1841 mob_alloc)) | |
1842 { | |
1843 stop_rach_and_enter_idle(); | |
1844 return; | |
1845 } | |
1846 } | |
1847 else | |
1848 { | |
1849 maio = 0; | |
1850 srv_clear_list (&hop_list_bef); | |
1851 } | |
1852 | |
1853 | |
1854 /* | |
1855 * stop T3122 and T3126 if they are running. | |
1856 */ | |
1857 TIMERSTOP (T3122); | |
1858 TIMERSTOP (T3126); | |
1859 SET_STATE (STATE_DAT, DAT_IMM_ASS_1); | |
1860 | |
1861 /* | |
1862 * store channel description | |
1863 */ | |
1864 memcpy (&rrd->chan_desc, &imm_assign->chan_desc, | |
1865 sizeof (T_chan_desc)); | |
1866 | |
1867 /* | |
1868 * the initial channel mode is always signalling only | |
1869 */ | |
1870 rrd->ch_mode = MODE_SIG_ONLY; | |
1871 | |
1872 /* | |
1873 * set the timing advance | |
1874 */ | |
1875 rrd->new_ta = imm_assign->time_advance.ta; | |
1876 att_set_tim_advance_info(); | |
1877 dat_set_last_used_channel (&rrd->chan_desc); | |
1878 | |
1879 | |
1880 /* | |
1881 * configure layer 1 | |
1882 */ | |
1883 dat_code_mph_imm_assign_req (&start, | |
1884 rr_data->nc_data[SC_INDEX].select_para.ms_txpwr_max_cch, | |
1885 maio, | |
1886 &hop_list_after, | |
1887 &hop_list_bef); | |
1888 } | |
1889 EM_IMMEDIATE_ASSIGNMENT; | |
1890 } | |
1891 break; | |
1892 | |
1893 default: | |
1894 break; | |
1895 } | |
1896 } | |
1897 | |
1898 /* | |
1899 +--------------------------------------------------------------------+ | |
1900 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
1901 | STATE : code ROUTINE : dat_for_imm_assign_ext | | |
1902 +--------------------------------------------------------------------+ | |
1903 | |
1904 PURPOSE : Reception of the immediate assignment extended message. | |
1905 | |
1906 */ | |
1907 | |
1908 | |
1909 GLOBAL void dat_for_imm_assign_ext (T_MPH_UNITDATA_IND *mph_unitdata_ind, | |
1910 T_D_IMM_ASSIGN_EXT *imm_assign_ext) | |
1911 { | |
1912 GET_INSTANCE_DATA; | |
1913 USHORT i; | |
1914 T_start start; | |
1915 UBYTE mob_alloc [65]; | |
1916 T_SC_DATA *rrd = &rr_data->sc_data; | |
1917 T_LIST hop_list_after; | |
1918 T_LIST hop_list_bef; | |
1919 UBYTE index; | |
1920 T_chan_desc *p_chan_desc; | |
1921 | |
1922 TRACE_FUNCTION ("dat_for_imm_assign_ext()"); | |
1923 | |
1924 switch (GET_STATE (STATE_DAT)) | |
1925 { | |
1926 case DAT_IMM_ASS: | |
1927 if (dat_check_error_flag (SEND_NO_RR_STATUS)) | |
1928 { | |
1929 /* | |
1930 * the message check in the formatter has passed | |
1931 */ | |
1932 for (i=0; i<2; i++) | |
1933 { | |
1934 /* | |
1935 * the immediate assignment extended message contains | |
1936 * two request references. | |
1937 */ | |
1938 if (dat_compare_request_ref ((i EQ 0) | |
1939 ? &imm_assign_ext->req_ref | |
1940 : (T_req_ref *)&imm_assign_ext->req_ref_2, | |
1941 &index)) | |
1942 { | |
1943 #ifdef GPRS | |
1944 dat_check_imm_ass_ext (mph_unitdata_ind,(UBYTE)(i+1)); | |
1945 #endif | |
1946 /* | |
1947 * check channel description | |
1948 */ | |
1949 if(i EQ 0) | |
1950 p_chan_desc = &imm_assign_ext->chan_desc; | |
1951 else | |
1952 p_chan_desc = (T_chan_desc *)&imm_assign_ext->chan_desc_2; | |
1953 for_check_channel_descr (p_chan_desc); | |
1954 | |
1955 if (!dat_check_error_flag (SEND_NO_RR_STATUS)) | |
1956 return; | |
1957 /* | |
1958 * the request reference in the immediate assignment | |
1959 * extended message matches to one of the last three | |
1960 * channel request messages. | |
1961 */ | |
1962 if (imm_assign_ext->mob_alloc.c_mac AND p_chan_desc->hop) | |
1963 { | |
1964 /* | |
1965 * if the message contains a mobile allocation and | |
1966 * the mobile shall hop | |
1967 * build a frequency hopping list together with | |
1968 * the cell channel description of system information | |
1969 * type 1 message. | |
1970 */ | |
1971 att_bits_to_byte (mob_alloc, | |
1972 imm_assign_ext->mob_alloc.c_mac, | |
1973 imm_assign_ext->mob_alloc.mac); | |
1974 if(rrd->cd.v_cell_chan_desc EQ NO_CONTENT OR | |
1975 ! srv_create_chan_mob_alloc (&rr_data->sc_data.cd.cell_chan_desc, | |
1976 &hop_list_after, | |
1977 mob_alloc)) | |
1978 { | |
1979 stop_rach_and_enter_idle(); | |
1980 return; | |
1981 } | |
1982 } | |
1983 else | |
1984 { | |
1985 /* | |
1986 * else clear frequency hopping list | |
1987 */ | |
1988 srv_clear_list (&hop_list_after); | |
1989 } | |
1990 | |
1991 /* | |
1992 * stop T3122 and T3126 if they are running. | |
1993 */ | |
1994 TIMERSTOP (T3122); | |
1995 TIMERSTOP (T3126); | |
1996 /* | |
1997 * store channel description | |
1998 */ | |
1999 memcpy (&rrd->chan_desc, | |
2000 p_chan_desc, | |
2001 sizeof (T_chan_desc)); | |
2002 | |
2003 /* | |
2004 * the initial channel mode is ever signalling only | |
2005 */ | |
2006 rrd->ch_mode = MODE_SIG_ONLY; | |
2007 | |
2008 /* | |
2009 * store the new timing advance | |
2010 */ | |
2011 rrd->new_ta = (i EQ 0) | |
2012 ? imm_assign_ext->time_advance.ta | |
2013 : imm_assign_ext->time_advance_2.ta; | |
2014 att_set_tim_advance_info(); | |
2015 dat_set_last_used_channel (&rrd->chan_desc); | |
2016 | |
2017 | |
2018 if (imm_assign_ext->v_start_time) | |
2019 { | |
2020 /* | |
2021 * copy starting time if available | |
2022 */ | |
2023 start.v_start = TRUE; | |
2024 start.t1 = imm_assign_ext->start_time.t1; | |
2025 start.t2 = imm_assign_ext->start_time.t2; | |
2026 start.t3 = imm_assign_ext->start_time.t3; | |
2027 } | |
2028 else | |
2029 memset (&start, 0, sizeof (T_start)); | |
2030 | |
2031 srv_clear_list (&hop_list_bef); | |
2032 SET_STATE (STATE_DAT, DAT_IMM_ASS_1); | |
2033 | |
2034 /* | |
2035 * configure layer 1. | |
2036 */ | |
2037 dat_code_mph_imm_assign_req (&start, | |
2038 rr_data->nc_data[SC_INDEX].select_para.ms_txpwr_max_cch, | |
2039 0, | |
2040 &hop_list_after, | |
2041 &hop_list_bef); | |
2042 | |
2043 EM_IMMEDIATE_ASSIGNMENT_EXT; | |
2044 return; | |
2045 } | |
2046 } | |
2047 } | |
2048 break; | |
2049 | |
2050 default: | |
2051 break; | |
2052 } | |
2053 } | |
2054 | |
2055 /* | |
2056 +--------------------------------------------------------------------+ | |
2057 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
2058 | STATE : code ROUTINE : dat_for_imm_assign_rej | | |
2059 +--------------------------------------------------------------------+ | |
2060 | |
2061 PURPOSE : Reception of an immediate assignment reject message. | |
2062 | |
2063 */ | |
2064 | |
2065 GLOBAL void dat_for_imm_assign_rej (T_D_IMM_ASSIGN_REJ *imm_assign_rej) | |
2066 { | |
2067 GET_INSTANCE_DATA; | |
2068 UBYTE index; | |
2069 | |
2070 TRACE_FUNCTION ("dat_for_imm_assign_rej()"); | |
2071 | |
2072 switch (GET_STATE (STATE_DAT)) | |
2073 { | |
2074 case DAT_IMM_ASS: | |
2075 if (dat_check_error_flag (SEND_NO_RR_STATUS)) | |
2076 { | |
2077 /* | |
2078 * the message has passed the checks in the formatter. | |
2079 */ | |
2080 | |
2081 if (! IS_TIMER_ACTIVE(T3122)) | |
2082 { | |
2083 /* | |
2084 * Only if T3122 is not running, that means there is no | |
2085 * immediate assignment reject message taken in account | |
2086 * before. | |
2087 */ | |
2088 BOOL result = FALSE; | |
2089 UBYTE t3122 = 0; | |
2090 | |
2091 if (dat_compare_request_ref (&imm_assign_rej->req_ref, &index)) | |
2092 { | |
2093 /* | |
2094 * if the request reference matches to one of the last | |
2095 * three channel requests, set the result of TRUE and | |
2096 * store the timer value. This is checked for the up to | |
2097 * four request references in the message. | |
2098 */ | |
2099 result = TRUE; | |
2100 t3122 = imm_assign_rej->t3122; | |
2101 } | |
2102 | |
2103 else if (dat_compare_request_ref ((T_req_ref *)&imm_assign_rej->req_ref_2, &index)) | |
2104 { | |
2105 result = TRUE; | |
2106 t3122 = imm_assign_rej->t3122_2; | |
2107 } | |
2108 | |
2109 else if (dat_compare_request_ref ((T_req_ref *)&imm_assign_rej->req_ref_3, &index)) | |
2110 { | |
2111 result = TRUE; | |
2112 t3122 = imm_assign_rej->t3122_3; | |
2113 } | |
2114 | |
2115 else if (dat_compare_request_ref ((T_req_ref *)&imm_assign_rej->req_ref_4, &index)) | |
2116 { | |
2117 result = TRUE; | |
2118 t3122 = imm_assign_rej->t3122_4; | |
2119 } | |
2120 | |
2121 if (result) | |
2122 { | |
2123 /* | |
2124 * a request reference has matched | |
2125 */ | |
2126 #ifdef GPRS | |
2127 if (dat_check_imm_ass_rej (t3122) EQ FALSE) | |
2128 #endif | |
2129 if (t3122 NEQ 0) | |
2130 { | |
2131 /* | |
2132 * start T3122 if a value is defined | |
2133 */ | |
2134 TIMERSTART (T3122, T3122_VALUE(t3122)); | |
2135 } | |
2136 TRACE_EVENT("set rej_rec"); | |
2137 rr_data->imm_ass_rej_rec = TRUE; | |
2138 rr_data->ms_data.all_conf_received = TRUE; | |
2139 | |
2140 /* | |
2141 * Start T3126 if the timer is not running yet. | |
2142 */ | |
2143 /* Implements Measure#32: Row 217,218 */ | |
2144 (IS_TIMER_ACTIVE(T3126)) ? | |
2145 TRACE_TIMER ( "T3126 re-start") : TRACE_TIMER ( "T3126 start"); | |
2146 | |
2147 | |
2148 if (! IS_TIMER_ACTIVE(T3126)) | |
2149 { | |
2150 TIMERSTART (T3126, T3126_VALUE); | |
2151 /* | |
2152 * Stop sending Random Burst | |
2153 */ | |
2154 { | |
2155 PALLOC (mph_random_access_req, MPH_RANDOM_ACCESS_REQ); | |
2156 | |
2157 memset (&mph_random_access_req->send_mode, 0, sizeof (T_send_mode)); | |
2158 PSENDX (PL, mph_random_access_req); | |
2159 } | |
2160 } | |
2161 } | |
2162 EM_IMMEDIATE_ASSIGNMENT_REJECT; | |
2163 } | |
2164 } | |
2165 break; | |
2166 | |
2167 default: | |
2168 break; | |
2169 } | |
2170 } | |
2171 | |
2172 /* | |
2173 +--------------------------------------------------------------------+ | |
2174 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
2175 | STATE : code ROUTINE : dat_for_ext_meas_order | | |
2176 +--------------------------------------------------------------------+ | |
2177 | |
2178 PURPOSE : Reception of an extended measurement order message. | |
2179 | |
2180 */ | |
2181 | |
2182 GLOBAL void dat_for_ext_meas_order (T_D_EXT_MEAS_ORDER *ext_meas_order) | |
2183 { | |
2184 GET_INSTANCE_DATA; | |
2185 UBYTE new_seq; | |
2186 T_LIST *chan_list; | |
2187 | |
2188 PALLOC (mph_emo_req, MPH_EMO_REQ); | |
2189 | |
2190 TRACE_FUNCTION ("dat_for_ext_meas_order()"); | |
2191 | |
2192 /* | |
2193 * Decode EMO: new_seq | |
2194 */ | |
2195 | |
2196 ccd_decodeByte (ext_meas_order->ext_meas_freq.b_ext_meas_freq, | |
2197 (USHORT)(ext_meas_order->ext_meas_freq.o_ext_meas_freq+3), | |
2198 1, &new_seq); | |
2199 | |
2200 /* | |
2201 * Ignore EMO if EMO proc already running and new SEQ EQ current SEQ. | |
2202 */ | |
2203 | |
2204 if ( rr_data->emo_arfcn NEQ NULL AND rr_data->emo_seq EQ new_seq ) | |
2205 { | |
2206 PFREE ( mph_emo_req ); | |
2207 return; | |
2208 } | |
2209 | |
2210 /* | |
2211 * Decode and store EMO frequency list | |
2212 */ | |
2213 | |
2214 if ( rr_data->emo_arfcn EQ NULL ) | |
2215 { | |
2216 MALLOC ( rr_data->emo_arfcn, MAX_EMO_CHANNELS * sizeof (rr_data->emo_arfcn[0]) ); | |
2217 } | |
2218 rr_data->emo_seq = new_seq; | |
2219 MALLOC ( chan_list, sizeof ( T_LIST ) ); | |
2220 for_create_channel_list ( (T_f_range*) &ext_meas_order->ext_meas_freq, chan_list); | |
2221 | |
2222 /* | |
2223 * Function srv_create_list_dedicated ensures that the frequencies are sorted | |
2224 * and the number of frequencies are limited to 21 frequencies | |
2225 */ | |
2226 | |
2227 rr_data->c_emo_arfcn = srv_create_list (chan_list, | |
2228 rr_data->emo_arfcn, | |
2229 MAX_EMO_CHANNELS, | |
2230 FALSE, | |
2231 0); | |
2232 MFREE ( chan_list ); | |
2233 | |
2234 memcpy ( &mph_emo_req->arfcn[0], | |
2235 &rr_data->emo_arfcn[0], | |
2236 rr_data->c_emo_arfcn * sizeof (rr_data->emo_arfcn[0]) ); | |
2237 | |
2238 mph_emo_req->c_arfcn = | |
2239 srv_remove_frequencies_in_array_gen ( &mph_emo_req->arfcn[0], rr_data->c_emo_arfcn ); | |
2240 | |
2241 /* | |
2242 * Create newBA_ID, save as currentBA_ID. | |
2243 */ | |
2244 | |
2245 rr_data->ba_id = RR_ALLOCATE_NEW_BA ( rr_data->ba_id ); | |
2246 mph_emo_req->ba_id = rr_data->ba_id; | |
2247 | |
2248 /* | |
2249 * EMOtime = 10 seconds and request PL to perform extended measurement. | |
2250 */ | |
2251 | |
2252 TIMERSTART (TIM_EXT_MEAS, 10000); | |
2253 | |
2254 PSENDX (PL, mph_emo_req); | |
2255 } | |
2256 | |
2257 /* | |
2258 +--------------------------------------------------------------------+ | |
2259 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
2260 | STATE : code ROUTINE : dat_mph_emo_meas_ind | | |
2261 +--------------------------------------------------------------------+ | |
2262 | |
2263 PURPOSE : Measurement report for the Extended Measurment procedure | |
2264 has been received. | |
2265 | |
2266 */ | |
2267 | |
2268 GLOBAL void dat_mph_emo_meas_ind (T_MPH_EMO_MEAS_IND *mph_emo_meas_ind) | |
2269 { | |
2270 GET_INSTANCE_DATA; | |
2271 TRACE_FUNCTION ("att_mph_emo_meas_ind()"); | |
2272 | |
2273 switch (GET_STATE (STATE_DAT)) | |
2274 { | |
2275 case DAT_DEDICATED: | |
2276 if ( rr_data->emo_arfcn NEQ NULL AND mph_emo_meas_ind->ba_id EQ rr_data->ba_id ) | |
2277 { | |
2278 dat_code_ext_meas_report (mph_emo_meas_ind); | |
2279 dat_emo_stop ( TRUE ); | |
2280 } | |
2281 else | |
2282 { | |
2283 /* | |
2284 * Build an invalid measurement reports | |
2285 */ | |
2286 MCAST (meas, U_MEAS_REP); | |
2287 PALLOC_MSG (dl_unitdata_req, DL_UNITDATA_REQ, U_MEAS_REP); | |
2288 memset (&dl_unitdata_req->sdu.buf[0], 0, dl_unitdata_req->sdu.o_buf / BITS_PER_BYTE); | |
2289 | |
2290 memset (meas, 0, sizeof (T_U_MEAS_REP)); | |
2291 meas->msg_type = U_MEAS_REP; | |
2292 meas->meas_result.meas_valid = 1; | |
2293 for_dat_unitdata_req (dl_unitdata_req); | |
2294 } | |
2295 break; | |
2296 | |
2297 default: | |
2298 break; | |
2299 } | |
2300 PFREE (mph_emo_meas_ind); | |
2301 } | |
2302 | |
2303 | |
2304 /* | |
2305 +--------------------------------------------------------------------+ | |
2306 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
2307 | STATE : code ROUTINE : dat_emo_stop | | |
2308 +--------------------------------------------------------------------+ | |
2309 | |
2310 PURPOSE : Stop the Extended Measurement Order procedure. | |
2311 | |
2312 */ | |
2313 | |
2314 GLOBAL void dat_emo_stop (BOOL send_ncell_req ) | |
2315 { | |
2316 GET_INSTANCE_DATA; | |
2317 if ( rr_data->emo_arfcn NEQ NULL ) | |
2318 { | |
2319 MFREE (rr_data->emo_arfcn); | |
2320 rr_data->emo_arfcn = NULL; | |
2321 | |
2322 /* restore the neighbour cell description which was used prior EMO */ | |
2323 if ( send_ncell_req AND | |
2324 (rr_data->sc_data.cd.sys_info_read & (SYS_INFO_5_READ | SYS_INFO_5BIS_READ | SYS_INFO_5TER_READ) ) ) | |
2325 | |
2326 att_code_mph_ncell_req_dedicated(); | |
2327 } | |
2328 } | |
2329 | |
2330 /* | |
2331 +--------------------------------------------------------------------+ | |
2332 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
2333 | STATE : code ROUTINE : dat_for_l3_data_ind | | |
2334 +--------------------------------------------------------------------+ | |
2335 | |
2336 PURPOSE : Reception of a layer 3 message for upper layers. | |
2337 | |
2338 */ | |
2339 | |
2340 GLOBAL void dat_for_l3_data_ind (T_DL_DATA_IND *dl_data_ind) | |
2341 { | |
2342 GET_INSTANCE_DATA; | |
2343 /* RR_DATA_IND is not the same as DL_DATA_IND anymore because of the new | |
2344 * member fn (frame number) of T_DL_DATA_IND which is not contained in | |
2345 * T_RR_DATA_IND. | |
2346 */ | |
2347 PALLOC_SDU(rr_data_ind, RR_DATA_IND, (USHORT)(dl_data_ind->sdu.l_buf+dl_data_ind->sdu.o_buf)); | |
2348 | |
2349 TRACE_FUNCTION ("dat_for_l3_data_ind()"); | |
2350 | |
2351 if (dl_data_ind->sapi EQ SAPI_3) | |
2352 { | |
2353 /* | |
2354 * if it is a SMS message, this is implicitly an | |
2355 * indication for an established SAPI 3 link | |
2356 */ | |
2357 SET_STATE (STATE_SAPI_3, SMS_ESTABLISHED); | |
2358 } | |
2359 | |
2360 rr_data_ind->sdu.l_buf = dl_data_ind->sdu.l_buf; | |
2361 rr_data_ind->sdu.o_buf = dl_data_ind->sdu.o_buf; | |
2362 memcpy(rr_data_ind->sdu.buf, dl_data_ind->sdu.buf, | |
2363 (dl_data_ind->sdu.l_buf+dl_data_ind->sdu.o_buf)>>3); | |
2364 PFREE (dl_data_ind); | |
2365 /* | |
2366 * forward the message to MM for distribution | |
2367 */ | |
2368 PSENDX (MM, rr_data_ind); | |
2369 } | |
2370 | |
2371 /* | |
2372 +--------------------------------------------------------------------+ | |
2373 | PROJECT : GSM-PS (6147) MODULE : RR_FOR | | |
2374 | STATE : code ROUTINE : dat_for_open_loop_cmd | | |
2375 +--------------------------------------------------------------------+ | |
2376 | |
2377 PURPOSE : Reception of a TCH OPEN LOOP COMMAND message. | |
2378 | |
2379 */ | |
2380 | |
2381 GLOBAL void dat_for_open_loop_cmd (T_DL_DATA_IND *dl_data_ind) | |
2382 { | |
2383 GET_INSTANCE_DATA; | |
2384 TRACE_FUNCTION ("dat_for_open_loop_cmd()"); | |
2385 | |
2386 if (dat_test_sim_available () OR !dat_check_sim_available () ) | |
2387 { | |
2388 /* | |
2389 * only if a test SIM card is inserted | |
2390 */ | |
2391 if (rr_data->tch_loop_subch NEQ NOT_PRESENT_8BIT) | |
2392 { | |
2393 /* | |
2394 * A TCH Loop must be closed before, then | |
2395 * open in layer 1. | |
2396 */ | |
2397 PREUSE (dl_data_ind, loop_req, MPH_TCH_LOOP_REQ); | |
2398 loop_req->tch_loop = NOT_PRESENT_8BIT; | |
2399 PSENDX (PL, loop_req); | |
2400 | |
2401 if(rr_data->tch_loop_subch EQ TCH_LOOP_C) | |
2402 { | |
2403 /* only TCH_LOOP_C is acknowledged */ | |
2404 PALLOC_SDU (data_req, DL_DATA_REQ, 3*BITS_PER_BYTE); | |
2405 | |
2406 /* | |
2407 * set channel type and SAPI for answer | |
2408 */ | |
2409 dat_code_prr_channel (&data_req->ch_type, | |
2410 &data_req->sapi, | |
2411 rr_data->sc_data.chan_desc.chan_type); | |
2412 | |
2413 TRACE_EVENT_P1 ( "Value of tch_loop_subch %x", rr_data->tch_loop_subch); | |
2414 | |
2415 /* | |
2416 * do not use CCD for the response | |
2417 */ | |
2418 data_req->sdu.l_buf = 24; | |
2419 data_req->sdu.o_buf = ENCODE_OFFSET; | |
2420 /*lint -e415 -e416 Likely access of out-of-bounds pointer*/ | |
2421 data_req->sdu.buf [0] = 0; | |
2422 data_req->sdu.buf [1] = 0; | |
2423 data_req->sdu.buf [2] = 0; | |
2424 data_req->sdu.buf [3] = 0x0F; /* TI=0, PD = TST */ | |
2425 data_req->sdu.buf [4] = 0x06; /* MT = Open Loop Cmd */ | |
2426 data_req->sdu.buf [5] = 0x81; /* IE acknowledge */ | |
2427 /*lint +e415 +e416 Likely access of out-of-bounds pointer*/ | |
2428 TRACE_EVENT ("DL_DATA_REQ (RR message)"); | |
2429 | |
2430 EM_TCH_LOOP_OPEN; | |
2431 | |
2432 PSENDX (DL, data_req); | |
2433 } | |
2434 /* tch loop "open" */ | |
2435 rr_data->tch_loop_subch = NOT_PRESENT_8BIT; | |
2436 } | |
2437 else | |
2438 { | |
2439 PFREE (dl_data_ind); | |
2440 } | |
2441 } | |
2442 else | |
2443 { | |
2444 PFREE (dl_data_ind); | |
2445 } | |
2446 } | |
2447 | |
2448 #if defined FF_EOTD | |
2449 /* | |
2450 +------------------------------------------------------------------------------ | |
2451 | Function : rr_applic_rx_init | |
2452 +------------------------------------------------------------------------------ | |
2453 | Description : Initialize the data structures related to | |
2454 | Application Information Transfer | |
2455 | Reference: 3GPP TS 04.18, 3.4.21.3 | |
2456 | | |
2457 | Parameters : The downlink (RX) part of the APDU structure. | |
2458 | | |
2459 +------------------------------------------------------------------------------ | |
2460 */ | |
2461 GLOBAL void rr_applic_rx_init ( T_APPLIC_RX *applic_rx) | |
2462 { | |
2463 applic_rx->state = SAI_NULL; | |
2464 if ( applic_rx->rrrrlp_data_ind NEQ NULL ) | |
2465 { | |
2466 PFREE ( applic_rx->rrrrlp_data_ind ) | |
2467 } | |
2468 applic_rx->rrrrlp_data_ind = NULL; | |
2469 #ifdef REL99 | |
2470 /* Send RRLP procedure stop indication to MM*/ | |
2471 { | |
2472 PALLOC (rr_rrlp_stop_ind, RR_RRLP_STOP_IND); | |
2473 PSENDX (MM, rr_rrlp_stop_ind); | |
2474 } | |
2475 #endif | |
2476 | |
2477 TIMERSTOP ( TAPDU ); | |
2478 } | |
2479 | |
2480 /* | |
2481 +------------------------------------------------------------------------------ | |
2482 | Function : rr_applic_rx_msg_store | |
2483 +------------------------------------------------------------------------------ | |
2484 | Description : Store the first segment of an APDU. | |
2485 | Reference: 3GPP TS 04.18, 3.4.21.3.2 | |
2486 | | |
2487 | Parameters : The first part of the APDU. | |
2488 | | |
2489 +------------------------------------------------------------------------------ | |
2490 */ | |
2491 LOCAL void rr_applic_rx_msg_store ( T_B_APPLIC_INFO *b_applic_info ) | |
2492 { | |
2493 GET_INSTANCE_DATA; | |
2494 T_APPLIC_RX *applic_rx = &rr_data->applic_rx; | |
2495 T_apdu_data *apdu_data = &b_applic_info->apdu_data; | |
2496 UBYTE size = apdu_data->c_apdu_info; | |
2497 T_sdu *sdu; | |
2498 PALLOC_SDU ( rrrrlp_data_ind, RRRRLP_DATA_IND, (USHORT)(size * BITS_PER_BYTE) ); | |
2499 | |
2500 if ( applic_rx->rrrrlp_data_ind NEQ NULL ) | |
2501 { | |
2502 TRACE_EVENT_P1 ( "APPLIC: non empty store message found", 0 ); | |
2503 PFREE ( applic_rx->rrrrlp_data_ind ); | |
2504 } | |
2505 | |
2506 applic_rx->rrrrlp_data_ind = rrrrlp_data_ind; | |
2507 sdu = &applic_rx->rrrrlp_data_ind->sdu; | |
2508 | |
2509 memcpy ( &sdu->buf[0], apdu_data->apdu_info, size ); | |
2510 sdu->l_buf = size * BITS_PER_BYTE; | |
2511 sdu->o_buf = 0; | |
2512 } | |
2513 | |
2514 /* | |
2515 +------------------------------------------------------------------------------ | |
2516 | Function : rr_applic_rx_msg_append | |
2517 +------------------------------------------------------------------------------ | |
2518 | Description : Append segments to the APDU. | |
2519 | Reference: 3GPP TS 04.18, 3.4.21.3.2 | |
2520 | | |
2521 | Parameters : APDU segment to be appended. | |
2522 | | |
2523 +------------------------------------------------------------------------------ | |
2524 */ | |
2525 | |
2526 LOCAL int rr_applic_rx_msg_append ( T_B_APPLIC_INFO *b_applic_info ) | |
2527 { | |
2528 GET_INSTANCE_DATA; | |
2529 T_APPLIC_RX *applic_rx = &rr_data->applic_rx; | |
2530 T_apdu_data *apdu_data = &b_applic_info->apdu_data; | |
2531 T_sdu *sdu = &applic_rx->rrrrlp_data_ind->sdu; /* current APDU */ | |
2532 T_sdu *sdu2; /* new APDU */ | |
2533 USHORT size_cur = (USHORT)(sdu->l_buf/BITS_PER_BYTE); /* Current size of stored APDU */ | |
2534 USHORT size_inf = (USHORT)apdu_data->c_apdu_info; /* size of new APDU INFOrmation */ | |
2535 USHORT size_tot = (USHORT)(size_cur + size_inf); /* total APDU size after append */ | |
2536 | |
2537 if ( size_tot <= MAX_APDU_SIZE*BITS_PER_BYTE ) /*lint !e648 !e650/ Overflow caused by alternative defines, not applicable to target*/ | |
2538 { | |
2539 PALLOC_SDU ( rrrrlp_data_ind, RRRRLP_DATA_IND, (USHORT)(size_tot * BITS_PER_BYTE) ); | |
2540 | |
2541 sdu2 = &rrrrlp_data_ind->sdu; | |
2542 | |
2543 memcpy ( &sdu2->buf[ 0 ], &sdu->buf [0], size_cur ); | |
2544 memcpy ( &sdu2->buf[size_cur], &apdu_data->apdu_info[0], size_inf ); | |
2545 | |
2546 sdu2->l_buf = (USHORT)(size_tot * BITS_PER_BYTE); | |
2547 sdu2->o_buf = 0; | |
2548 | |
2549 PFREE ( applic_rx->rrrrlp_data_ind ); | |
2550 applic_rx->rrrrlp_data_ind = rrrrlp_data_ind; | |
2551 | |
2552 return TRUE; | |
2553 } | |
2554 else | |
2555 { | |
2556 return FALSE; | |
2557 } | |
2558 } | |
2559 | |
2560 /* | |
2561 +------------------------------------------------------------------------------ | |
2562 | Function : rr_applic_rx_msg_send | |
2563 +------------------------------------------------------------------------------ | |
2564 | Description : Send the re-segmented APDU to RRRRLP. | |
2565 | Reference: 3GPP TS 04.18, 3.4.21.3.2 | |
2566 | | |
2567 | Parameters : The C/R bit of the last APDU segment received. | |
2568 | | |
2569 +------------------------------------------------------------------------------ | |
2570 */ | |
2571 LOCAL void rr_applic_rx_msg_send ( UBYTE cr ) | |
2572 { | |
2573 GET_INSTANCE_DATA; | |
2574 T_APPLIC_RX *applic_rx = &rr_data->applic_rx; | |
2575 T_RRRRLP_DATA_IND *rrrrlp_data_ind = applic_rx->rrrrlp_data_ind; | |
2576 | |
2577 rrrrlp_data_ind->cr = cr; | |
2578 PSENDX ( RRLP, rrrrlp_data_ind ); | |
2579 applic_rx->rrrrlp_data_ind = NULL; | |
2580 applic_rx->state = SAI_NULL; | |
2581 TIMERSTOP ( TAPDU ); | |
2582 } | |
2583 | |
2584 /* | |
2585 +------------------------------------------------------------------------------ | |
2586 | Function : dat_for_applic_info_rrlp_rx_null | |
2587 +------------------------------------------------------------------------------ | |
2588 | Description : Received the first segment of an APDU. | |
2589 | Reference: 3GPP TS 04.18, 3.4.21.3.2 | |
2590 | | |
2591 | Parameters : b_applic_info: The first segment of an APDU. | |
2592 | seg: the combinbed APDU control flags | |
2593 | | |
2594 +------------------------------------------------------------------------------ | |
2595 */ | |
2596 LOCAL void dat_for_applic_info_rrlp_rx_null ( T_B_APPLIC_INFO * b_applic_info, UBYTE seg ) | |
2597 { | |
2598 GET_INSTANCE_DATA; | |
2599 T_APPLIC_RX *applic_rx = &rr_data->applic_rx; | |
2600 | |
2601 TRACE_ASSERT ( applic_rx->rrrrlp_data_ind EQ NULL ); | |
2602 | |
2603 switch ( seg ) | |
2604 { | |
2605 case FIRST_SEG | LAST_SEG : | |
2606 /* Allowed, simple case. Forward segment and stay in state SAI_NULL */ | |
2607 rr_applic_rx_msg_store ( b_applic_info ); | |
2608 #ifdef REL99 | |
2609 /* Send RRLP procedure start indication to MM*/ | |
2610 { | |
2611 PALLOC (rr_rrlp_start_ind, RR_RRLP_START_IND); | |
2612 PSENDX (MM, rr_rrlp_start_ind); | |
2613 } | |
2614 #endif | |
2615 rr_applic_rx_msg_send ( b_applic_info->apdu_flags.c_r ); | |
2616 break; | |
2617 | |
2618 case FIRST_SEG | NOT_LAST_SEG: | |
2619 /* Allowed, standard case of APDU segmentation. */ | |
2620 /* Check length of this segment -> L2 frame must be 251 bytes, | |
2621 otherwise protocol error as described in 3GPP 04.18, section 3.4.21.3.3 a) */ | |
2622 | |
2623 if ( b_applic_info->apdu_data.c_apdu_info EQ APDU_FULL_L2_FRAME ) | |
2624 { | |
2625 /* store this segment, start de-segmentation */ | |
2626 rr_applic_rx_msg_store ( b_applic_info ); | |
2627 TIMERSTART ( TAPDU, 2500 /* milli seconds */ ); /* 3GPP TS 04.18, 3.4.21.3.2 */ | |
2628 applic_rx->state = SAI_SEGM; | |
2629 #ifdef REL99 | |
2630 /* Send RRLP procedure start indication to MM*/ | |
2631 { | |
2632 PALLOC (rr_rrlp_start_ind, RR_RRLP_START_IND); | |
2633 PSENDX (MM, rr_rrlp_start_ind); | |
2634 } | |
2635 #endif | |
2636 } | |
2637 else | |
2638 { | |
2639 /* Protocol error occured, remain in state SAI_NULL, | |
2640 discard segment (cf 3.4.21.3.3, last clause). */ | |
2641 } | |
2642 break; | |
2643 | |
2644 case NOT_FIRST_SEG | LAST_SEG : | |
2645 case NOT_FIRST_SEG | NOT_LAST_SEG: | |
2646 /* Not allowed. Protocol error as described in 3GPP 04.18, section 3.4.21.3.3 c), | |
2647 discard segment as described in last sentence of 3.4.21.3.3 */ | |
2648 break; | |
2649 | |
2650 default: | |
2651 TRACE_EVENT_P1 ("unexpected 'default:' seg=%d", seg ); | |
2652 break; | |
2653 } | |
2654 } | |
2655 | |
2656 /* | |
2657 +------------------------------------------------------------------------------ | |
2658 | Function : dat_for_applic_info_rrlp_rx_segm | |
2659 +------------------------------------------------------------------------------ | |
2660 | Description : Received second and subsequent segments of an APDU. | |
2661 | Reference: 3GPP TS 04.18, 3.4.21.3.2 | |
2662 | | |
2663 | Parameters : b_applic_info: A segment of an APDU. | |
2664 | seg: the combinbed APDU control flags | |
2665 | | |
2666 +------------------------------------------------------------------------------ | |
2667 */ | |
2668 LOCAL void dat_for_applic_info_rrlp_rx_segm ( T_B_APPLIC_INFO * b_applic_info, UBYTE seg ) | |
2669 { | |
2670 GET_INSTANCE_DATA; | |
2671 T_APPLIC_RX *applic_rx = &rr_data->applic_rx; | |
2672 | |
2673 TRACE_ASSERT ( applic_rx->rrrrlp_data_ind NEQ NULL ); | |
2674 | |
2675 switch ( seg ) | |
2676 { | |
2677 case FIRST_SEG | LAST_SEG : | |
2678 case FIRST_SEG | NOT_LAST_SEG: | |
2679 | |
2680 /* Abnormal case, refer to 3GPP TS 04.18, 3.4.21.3.3 b), clause 2 */ | |
2681 /* Discard any partially reassembed APDU, enter state SAI_NULL */ | |
2682 | |
2683 rr_applic_rx_init ( applic_rx ); | |
2684 | |
2685 /* Now (re-)use the current segment, refer to 3GPP TS 04.18, 3.4.21.3.3: | |
2686 "...reprocess any received APDU or APDU segment that caused the error... " */ | |
2687 | |
2688 dat_for_applic_info_rrlp_rx_null ( b_applic_info, seg ); | |
2689 break; | |
2690 | |
2691 case NOT_FIRST_SEG | LAST_SEG : | |
2692 | |
2693 /* Normal case, end of re-segmentation, TAPDU stop, | |
2694 send the message to the application entity. | |
2695 Enter state SAI_NULL. */ | |
2696 | |
2697 if ( rr_applic_rx_msg_append ( b_applic_info ) EQ FALSE ) | |
2698 rr_applic_rx_init ( applic_rx ); | |
2699 else | |
2700 rr_applic_rx_msg_send ( b_applic_info->apdu_flags.c_r ); | |
2701 break; | |
2702 | |
2703 case NOT_FIRST_SEG | NOT_LAST_SEG: | |
2704 | |
2705 /* Normal case, re-segmetation is still ongoing. | |
2706 If 'append' operation fails, then return to state SAI_NULL. */ | |
2707 | |
2708 if ( rr_applic_rx_msg_append ( b_applic_info ) EQ FALSE ) | |
2709 rr_applic_rx_init ( applic_rx ); | |
2710 break; | |
2711 | |
2712 default: | |
2713 break; | |
2714 } | |
2715 } | |
2716 | |
2717 | |
2718 /* | |
2719 +------------------------------------------------------------------------------ | |
2720 | Function : dat_for_applic_info_rrlp | |
2721 +------------------------------------------------------------------------------ | |
2722 | Description : Application Information Transfer (RX) for RRRLP | |
2723 | Reference: 3GPP TS 04.18, 3.4.21.3 | |
2724 | | |
2725 | Parameters : b_applic_info: Segment of an APDU. | |
2726 | | |
2727 +------------------------------------------------------------------------------ | |
2728 */ | |
2729 LOCAL void dat_for_applic_info_rrlp ( T_B_APPLIC_INFO * b_applic_info ) | |
2730 { | |
2731 GET_INSTANCE_DATA; | |
2732 T_APPLIC_RX *applic_rx = &rr_data->applic_rx; | |
2733 | |
2734 UBYTE seg = ((b_applic_info->apdu_flags.f_seg << 1) | | |
2735 (b_applic_info->apdu_flags.l_seg ) ) & 0x03; | |
2736 | |
2737 switch ( applic_rx->state ) | |
2738 { | |
2739 case SAI_NULL : | |
2740 dat_for_applic_info_rrlp_rx_null ( b_applic_info, seg ); | |
2741 break; | |
2742 | |
2743 case SAI_SEGM : | |
2744 dat_for_applic_info_rrlp_rx_segm ( b_applic_info, seg ); | |
2745 break; | |
2746 | |
2747 default: | |
2748 break; | |
2749 } | |
2750 } | |
2751 | |
2752 /* | |
2753 +------------------------------------------------------------------------------ | |
2754 | Function : dat_for_applic_info | |
2755 +------------------------------------------------------------------------------ | |
2756 | Description : Main entry point for Application Information Transfer (RX) | |
2757 | Reference: 3GPP TS 04.18, 3.4.21.3 | |
2758 | | |
2759 | Parameters : b_applic_info: Segment of an APDU. | |
2760 | | |
2761 +------------------------------------------------------------------------------ | |
2762 */ | |
2763 GLOBAL void dat_for_applic_info ( T_B_APPLIC_INFO * b_applic_info ) | |
2764 { | |
2765 /* | |
2766 * handle RRLP, all other protocols are not supported | |
2767 */ | |
2768 if ( b_applic_info->apdu_id.protoc_ident EQ RRLP_LCS ) | |
2769 { | |
2770 dat_for_applic_info_rrlp ( b_applic_info ); | |
2771 } | |
2772 else | |
2773 { | |
2774 TRACE_EVENT_P1 ( "unsupported protocol %x", b_applic_info->apdu_id.protoc_ident ); | |
2775 } | |
2776 } | |
2777 #endif /* FF_EOTD */ | |
2778 | |
2779 | |
2780 /* | |
2781 +--------------------------------------------------------------------+ | |
2782 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
2783 | STATE : code ROUTINE : dat_for_handover_mob_alloc | | |
2784 +--------------------------------------------------------------------+ | |
2785 | |
2786 PURPOSE : This function generates a frequency hopping list for handover | |
2787 | |
2788 */ | |
2789 | |
2790 LOCAL BOOL dat_for_handover_mob_alloc(UBYTE *mob_alloc, | |
2791 T_LIST *hop_list_handover, | |
2792 T_VOID_STRUCT *mob_alloc_handover, | |
2793 T_DL_DATA_IND *dl_data_ind) | |
2794 { | |
2795 GET_INSTANCE_DATA; | |
2796 TRACE_FUNCTION("dat_for_handover_mob_alloc()"); | |
2797 /* | |
2798 * the handover command contains a mobile allocation. | |
2799 * Convert the bitmap to a list of the 1-bits in the | |
2800 * bitmap for generating a frequency hopping list. | |
2801 */ | |
2802 att_bits_to_byte (mob_alloc, | |
2803 ((T_mob_alloc *)mob_alloc_handover)->c_mac, | |
2804 ((T_mob_alloc *)mob_alloc_handover)->mac); | |
2805 | |
2806 /* | |
2807 * Now create the frequency hopping list | |
2808 */ | |
2809 if(!srv_create_chan_mob_alloc (&rr_data->cr_data.cd.cell_chan_desc, | |
2810 hop_list_handover, | |
2811 mob_alloc)) | |
2812 { | |
2813 dat_send_handov_fail_msg(RRC_FREQ_NOT_IMPL); | |
2814 | |
2815 RR_EM_SET_HANDOVER_FAIL_CAUSE(RRC_FREQ_NOT_IMPL); | |
2816 | |
2817 PFREE (dl_data_ind); | |
2818 return TRUE; | |
2819 } | |
2820 return FALSE; | |
2821 } | |
2822 | |
2823 /* | |
2824 +--------------------------------------------------------------------+ | |
2825 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
2826 | STATE : code ROUTINE : dat_cr_data_multirate_conf | | |
2827 +--------------------------------------------------------------------+ | |
2828 | |
2829 PURPOSE : This function extracts the multirate configuration and stores | |
2830 it in the rr_data. | |
2831 | |
2832 */ | |
2833 LOCAL void dat_cr_data_multirate_conf(U8 v_multirate_conf, T_multirate_conf *multirate_conf) | |
2834 | |
2835 { | |
2836 GET_INSTANCE_DATA; | |
2837 TRACE_FUNCTION("dat_cr_data_multirate_conf()"); | |
2838 | |
2839 if(rr_data->cr_data.ch_mode EQ CM_AMR) | |
2840 { | |
2841 if (v_multirate_conf) | |
2842 { | |
2843 /* | |
2844 * store a new multi-rate speech codec if available. | |
2845 */ | |
2846 UBYTE i; | |
2847 | |
2848 rr_data->cr_data.amr_conf.mr_vers = multirate_conf->mr_vers; | |
2849 rr_data->cr_data.amr_conf.nscb = multirate_conf->nscb; | |
2850 rr_data->cr_data.amr_conf.icmi = multirate_conf->icmi; | |
2851 rr_data->cr_data.amr_conf.st_mode = multirate_conf->st_mode; | |
2852 rr_data->cr_data.amr_conf.set_amr = multirate_conf->set_amr; | |
2853 | |
2854 /* | |
2855 * valid flag for the threshold and hystersis values. | |
2856 * multirate_conf.c_cod_prop | |
2857 * defines the number of threshold and hystersis values. | |
2858 */ | |
2859 rr_data->cr_data.amr_conf.v_cod_prop = multirate_conf->v_cod_prop; | |
2860 | |
2861 if(rr_data->cr_data.amr_conf.v_cod_prop) | |
2862 { | |
2863 rr_data->cr_data.amr_conf.c_cod_prop = multirate_conf->c_cod_prop; | |
2864 | |
2865 for (i=0; i< multirate_conf->c_cod_prop; i++) | |
2866 memcpy(&rr_data->cr_data.amr_conf.cod_prop[i], &multirate_conf->cod_prop[i], sizeof(T_cod_prop)); | |
2867 } /* if(rr_data->cr_data.amr_conf.v_cod_prop) */ | |
2868 } /* if (assign_cmd->v_multirate_conf) */ | |
2869 } /* if (rr_data->cr_data.ch_mode EQ CM_AMR) */ | |
2870 } | |
2871 | |
2872 /* | |
2873 +--------------------------------------------------------------------+ | |
2874 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
2875 | STATE : code ROUTINE : dat_class_chng_data_req | | |
2876 +--------------------------------------------------------------------+ | |
2877 | |
2878 PURPOSE : This function forms a peer CLASSMARK CHANGE request | |
2879 | |
2880 */ | |
2881 GLOBAL void dat_class_chng_data_req(void) | |
2882 { | |
2883 GET_INSTANCE_DATA; | |
2884 | |
2885 TRACE_FUNCTION("dat_class_chng_data_req()"); | |
2886 /* | |
2887 * The syntax check indicates no problems, then | |
2888 * process the message. | |
2889 * | |
2890 * The MS returns a classmark change message. | |
2891 */ | |
2892 { | |
2893 MCAST (class_chng, U_CLASS_CHNG);/* T_U_CLASS_CHNG */ | |
2894 PALLOC_MSG (dl_data_req, DL_DATA_REQ, U_CLASS_CHNG); | |
2895 | |
2896 /* | |
2897 * set channel type and sapi | |
2898 */ | |
2899 dat_code_prr_channel (&dl_data_req->ch_type, | |
2900 &dl_data_req->sapi, rr_data->sc_data.chan_desc.chan_type); | |
2901 | |
2902 class_chng->msg_type = U_CLASS_CHNG; | |
2903 class_chng->mob_class_2 = rr_data->ms_data.classmark2; | |
2904 class_chng->mob_class_2.rf_pow_cap = att_get_power (); | |
2905 class_chng->mob_class_3 = rr_data->ms_data.classmark3; | |
2906 class_chng->v_mob_class_3 = rr_data->ms_data.classmark2.class3; | |
2907 | |
2908 for_dat_data_req (dl_data_req); | |
2909 } | |
2910 } | |
2911 /* | |
2912 +--------------------------------------------------------------------+ | |
2913 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
2914 | STATE : code ROUTINE : dat_dedicated_req_ch_type2 | | |
2915 +--------------------------------------------------------------------+ | |
2916 | |
2917 PURPOSE : This function extracts the channle type from the channel | |
2918 description IE . | |
2919 | |
2920 */ | |
2921 LOCAL void dat_dedicated_req_ch_type2(T_ch_type2 *ch_type2, T_chan_desc_before *chan_desc_before, | |
2922 T_LIST *hop_list_before) | |
2923 { | |
2924 GET_INSTANCE_DATA; | |
2925 | |
2926 TRACE_FUNCTION("dat_dedicated_req_ch_type2()"); | |
2927 | |
2928 ch_type2->ch = chan_desc_before->chan_type; | |
2929 ch_type2->tn = chan_desc_before->tn; | |
2930 ch_type2->tsc = chan_desc_before->tsc; | |
2931 ch_type2->h = chan_desc_before->hop; | |
2932 if(ch_type2->h EQ H_NO) | |
2933 ch_type2->arfcn = chan_desc_before->arfcn; | |
2934 else | |
2935 { | |
2936 ch_type2->maio = chan_desc_before->maio; | |
2937 ch_type2->hsn = chan_desc_before->hsn; | |
2938 | |
2939 /* CSI-LLD section:4.1.1.11 | |
2940 * This function Updates the black list with the MA list received | |
2941 * in the assignment command | |
2942 */ | |
2943 cs_remove_BA_MA_from_black_list(rr_data->cs_data.region,hop_list_before); | |
2944 | |
2945 srv_create_list (hop_list_before, ch_type2->ma, | |
2946 MAX_MA_CHANNELS, TRUE, 0); | |
2947 } | |
2948 } | |
2949 | |
2950 #if defined (REL99) && defined (TI_PS_FF_EMR) | |
2951 /* | |
2952 +------------------------------------------------------------------------------ | |
2953 | Function : dat_for_meas_inf | |
2954 +------------------------------------------------------------------------------ | |
2955 | Description : Processing of measurement information message is done in this function. | |
2956 | All possible errors, if present, are detected and an error free MI-message | |
2957 | instance is decoded and data base updated with the enhanced measurement parameters. | |
2958 | Parameters : MI-message pointer | |
2959 | | |
2960 +------------------------------------------------------------------------------ | |
2961 */ | |
2962 GLOBAL BOOL dat_for_meas_inf (T_D_MEAS_INF *p_mi) | |
2963 { | |
2964 GET_INSTANCE_DATA; | |
2965 T_rr_enh_para *p_cur = &rr_data->sc_data.emr_data_current; | |
2966 T_rr_enh_para *p_temp = &rr_data->sc_data.emr_data_temp; | |
2967 BOOL send_enh_para = FALSE; | |
2968 T_gprs_rep_prio *p_rep = NULL; | |
2969 T_gprs_bsic *p_bl = NULL; | |
2970 | |
2971 #if defined (TI_PS_FF_RTD) AND defined (REL99) | |
2972 UBYTE i,j; | |
2973 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */ | |
2974 | |
2975 | |
2976 /* Step 1: Check if we received right BA_IND */ | |
2977 if( (rr_data->sc_data.ba_list_ded EQ TRUE) AND | |
2978 (p_mi->ba_ind NEQ rr_data->sc_data.ba_index ) ) | |
2979 { | |
2980 rr_data->sc_data.ba_list_ded = FALSE; | |
2981 rr_data->sc_data.ba_index = p_mi->ba_ind ; | |
2982 srv_clear_list (&rr_data->sc_data.cd.ncell_list); | |
2983 #ifdef TI_PS_FF_REL4 | |
2984 srv_clear_list (&rr_data->sc_data.cd.multiband_ncell_list); | |
2985 #else | |
2986 srv_clear_list (&rr_data->sc_data.five_ter_list); | |
2987 #endif | |
2988 att_clean_buf (IND_ALL_DEDI_SI); | |
2989 rr_data->sc_data.cd.sys_info_read &= ~ALL_DEDI_SYS_INFOS; | |
2990 TRACE_EVENT("Flushed off the entire dedicated mode BA-LIST as the BA-IND got changed"); | |
2991 } | |
2992 | |
2993 /* Step 2: Check report type. | |
2994 IMPORTANT ASSUMPTION: We will not process the other parameters if report type is Normal*/ | |
2995 if( p_mi->report_type NEQ ENHANCED_MEAS ) | |
2996 { | |
2997 /*check whether there are enhanced parameters and BA list, already. | |
2998 If present then it means that report type is changing from | |
2999 Enhanced to Normal*/ | |
3000 if ( p_cur->is_data_valid EQ TRUE ) | |
3001 { | |
3002 for_set_default_emr_data(p_cur); | |
3003 return TRUE; /*send enh para update to indicate change in report type*/ | |
3004 } | |
3005 else | |
3006 return send_enh_para; | |
3007 } | |
3008 | |
3009 /* Step 3: Check if we already have enh_para in current or temp | |
3010 and if there is change in parameters or continuation of reception*/ | |
3011 if(p_temp->is_data_valid EQ FALSE ) | |
3012 { | |
3013 /*This means we were not in the process of receiving. Check whether there | |
3014 is already information in current and if so, is there change in mp_change_mark*/ | |
3015 if( (p_cur->is_data_valid EQ TRUE ) AND | |
3016 (p_cur->mp_change_mark EQ p_mi->mp_cm ) ) | |
3017 { | |
3018 TRACE_EVENT("No change in Enhanced measurement parameters -ignore "); | |
3019 return send_enh_para; | |
3020 } | |
3021 /* This means there's either a change in MP change mark or receiving EMP for first time */ | |
3022 /* Decode rest of the parameters*/ | |
3023 p_temp->is_data_valid = TRUE; | |
3024 rr_data->sc_data.enh_para_status = ENH_PARA_INVALID_STATE; | |
3025 p_temp->enh_para.ncc_permitted = rr_data->sc_data.cd.ncc_permitted; | |
3026 } | |
3027 | |
3028 /*Note :If different values occur for the same parameter in different instances of a message, | |
3029 the instance with the highest index shall be used (sec.3.4.1.2.1, 4.18)*/ | |
3030 if ( (p_mi->mi_idx > rr_data->sc_data.prev_highest_index ) OR | |
3031 (rr_data->sc_data.prev_highest_index EQ NOT_PRESENT_8BIT) ) | |
3032 { | |
3033 p_temp->enh_para.rep_rate = p_mi->rep_rate; | |
3034 p_temp->enh_para.inv_bsic_enabled = p_mi->inv_bsic_rep; | |
3035 p_temp->mp_change_mark = p_mi->mp_cm; | |
3036 p_temp->msg_count = p_mi->mi_c; | |
3037 p_temp->rep_type = p_mi->report_type; | |
3038 if (p_mi->v_emp EQ TRUE ) /* This is updation of parameters other than BSIC list*/ | |
3039 { | |
3040 dat_update_emr_rep_para(&p_mi->emp,&p_temp->enh_para); | |
3041 } | |
3042 rr_data->sc_data.prev_highest_index = p_mi->mi_idx; | |
3043 } | |
3044 | |
3045 #if defined (TI_PS_FF_RTD) AND defined (REL99) | |
3046 if(p_mi->v_rtdd) | |
3047 dat_update_rtd_data(p_mi,p_temp); | |
3048 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */ | |
3049 | |
3050 | |
3051 /*Get relevant parameters to pass to BSIC and report priority list handler*/ | |
3052 if(p_mi->v_gprs_rep_prio EQ TRUE) | |
3053 p_rep = &p_mi->gprs_rep_prio; | |
3054 | |
3055 if( p_mi->v_gprs_bsic EQ TRUE) | |
3056 p_bl = &p_mi->gprs_bsic; | |
3057 | |
3058 if (for_dat_process_common_emr_data(p_rep,p_bl,p_mi->mi_idx, | |
3059 rr_data->sc_data.ba_list_ded) ) | |
3060 { | |
3061 rr_data->sc_data.enh_para_status = ENH_PARA_DEDICATED; | |
3062 | |
3063 if ( rr_data->sc_data.ba_list_ded EQ TRUE) | |
3064 send_enh_para = TRUE; | |
3065 } | |
3066 | |
3067 #if defined (TI_PS_FF_RTD) AND defined (REL99) | |
3068 if(p_mi->v_rtdd) | |
3069 { | |
3070 /* reset the temporary storage to RTD value not available */ | |
3071 for(j = 0;j < MAX_NR_OF_NCELL; j++ ) | |
3072 { | |
3073 p_temp->enh_para.enh_cell_list[j].v_rtd = FALSE; | |
3074 for(i = 0;i < MAX_NUM_OF_RTD_VALUES; i++) | |
3075 p_temp->enh_para.enh_cell_list[j].rtd[i]= RTD_NOT_AVAILABLE; | |
3076 }/*for*/ | |
3077 }/*if*/ | |
3078 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */ | |
3079 | |
3080 return send_enh_para; | |
3081 } | |
3082 #endif | |
3083 | |
3084 #endif |