FreeCalypso > hg > freecalypso-sw
comparison gsm-fw/g23m-gsm/rr/rr_dats.c @ 673:2f7df7a314f8
gsm-fw/g23m-gsm subtree: initial import from LoCosto source
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 28 Sep 2014 23:20:04 +0000 |
parents | |
children | e915a56954ae |
comparison
equal
deleted
inserted
replaced
672:0dc6f9e8e980 | 673:2f7df7a314f8 |
---|---|
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 #define ENTITY_RR | |
26 | |
27 /*==== INCLUDES ===================================================*/ | |
28 | |
29 #include <string.h> | |
30 #include <stdlib.h> | |
31 #include <stddef.h> /* offsetof */ | |
32 #include "typedefs.h" | |
33 #include "pcm.h" | |
34 #include "pconst.cdg" | |
35 #include "mconst.cdg" | |
36 #include "message.h" | |
37 #include "ccdapi.h" | |
38 #include "vsi.h" | |
39 #include "custom.h" | |
40 #include "gsm.h" | |
41 #include "prim.h" | |
42 #include "cnf_rr.h" | |
43 #include "tok.h" | |
44 #include "rr.h" | |
45 #include "em.h" | |
46 #include "rr_em.h" | |
47 | |
48 /*==== EXPORT =====================================================*/ | |
49 | |
50 /*==== PRIVAT =====================================================*/ | |
51 | |
52 #define TDMA_FRAMES_PER_HYPERFRAME 2715648 | |
53 #define QUARTER_BITS_PER_FRAME 5000 | |
54 | |
55 /*==== VARIABLES ==================================================*/ | |
56 | |
57 /*==== FUNCTIONS ==================================================*/ | |
58 | |
59 LOCAL BOOL dat_for_handover_mob_alloc(UBYTE *mob_alloc, | |
60 T_LIST *hop_list_handover, | |
61 T_VOID_STRUCT *mob_alloc_handover, | |
62 T_DL_DATA_IND *dl_data_ind); | |
63 | |
64 LOCAL void dat_cr_data_multirate_conf(U8 v_multirate_conf, T_multirate_conf *multirate_conf); | |
65 | |
66 LOCAL void dat_dedicated_req_ch_type2(T_ch_type2 *ch_type2, T_chan_desc_before *chan_desc_before, | |
67 T_LIST *hop_list_before); | |
68 /* | |
69 * ------------------------------------------------------------------- | |
70 * SIGNAL Processing functions | |
71 * ------------------------------------------------------------------- | |
72 */ | |
73 | |
74 /* | |
75 +--------------------------------------------------------------------+ | |
76 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
77 | STATE : code ROUTINE : dat_att_cell_selected | | |
78 +--------------------------------------------------------------------+ | |
79 | |
80 PURPOSE : Attachment process indicates that it has camped on a cell. | |
81 Data transfer process changes the state and connections | |
82 are possible. | |
83 | |
84 */ | |
85 | |
86 GLOBAL void dat_att_cell_selected (void) | |
87 { | |
88 GET_INSTANCE_DATA; | |
89 TRACE_FUNCTION ("dat_att_cell_selected()"); | |
90 | |
91 SET_STATE (STATE_DAT, DAT_IDLE); | |
92 } | |
93 | |
94 /* | |
95 +--------------------------------------------------------------------+ | |
96 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
97 | STATE : code ROUTINE : dat_att_null | | |
98 +--------------------------------------------------------------------+ | |
99 | |
100 PURPOSE : Attachment process indicates loss of coverage and connections | |
101 are not longer possible. | |
102 | |
103 */ | |
104 | |
105 GLOBAL void dat_att_null (void) | |
106 { | |
107 GET_INSTANCE_DATA; | |
108 | |
109 TRACE_FUNCTION ("dat_att_null()"); | |
110 | |
111 SET_STATE (STATE_DAT, DAT_NULL); | |
112 } | |
113 | |
114 /* | |
115 +--------------------------------------------------------------------+ | |
116 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
117 | STATE : code ROUTINE : dat_for_assign_cmd | | |
118 +--------------------------------------------------------------------+ | |
119 | |
120 PURPOSE : The function handles the reception of a channel | |
121 assignment message. | |
122 | |
123 */ | |
124 | |
125 GLOBAL void dat_for_assign_cmd (T_DL_DATA_IND *dl_data_ind, | |
126 T_D_ASSIGN_CMD *assign_cmd, | |
127 T_LIST *hop_list_after, | |
128 T_LIST *hop_list_before, | |
129 T_LIST *cell_chan_desc) | |
130 { | |
131 GET_INSTANCE_DATA; | |
132 UBYTE mob_alloc[65]; | |
133 | |
134 PALLOC (dedicated_req, MPH_DEDICATED_REQ); | |
135 | |
136 TRACE_FUNCTION ("dat_for_assign_cmd()"); | |
137 | |
138 switch (GET_STATE (STATE_DAT)) | |
139 { | |
140 case DAT_DEDICATED: | |
141 if (rr_data->ms_data.error.cs) | |
142 { | |
143 TRACE_EVENT_P1 ("RRC cause = %02x", rr_data->ms_data.error.cs); | |
144 } | |
145 /* | |
146 * dynamic configuration command : IHO | |
147 * Lock the DUT to the cell it is already camping - | |
148 * Ignore the Channel Assignment command message and send an | |
149 * Assignment failure message to the network. | |
150 */ | |
151 | |
152 if(rr_data->dyn_config.iho AND (rr_data->sc_data.ch_mode EQ CM_AMR)) | |
153 { | |
154 TRACE_EVENT("D_ASSIGN_CMD : IHO"); | |
155 for_set_content_error (RRC_CHANNEL_MODE); | |
156 } | |
157 | |
158 switch (rr_data->ms_data.error.cs) | |
159 { | |
160 /* case RRC_INVALID_MAN_INFO: this value is currently never set */ | |
161 case RRC_COND_IE_ERROR: /* 0x64 */ | |
162 { | |
163 /* | |
164 * If an mandatory info element error or a | |
165 * conditional info element error has been detected, | |
166 * a RR STATUS message is returned on the existing | |
167 * connection before l2 is suspended | |
168 */ | |
169 dat_send_rr_status_msg(rr_data->ms_data.error.cs); | |
170 PFREE (dedicated_req); | |
171 PFREE (dl_data_ind); | |
172 break ; | |
173 } | |
174 | |
175 case RRC_INCORRECT_MSG: /* 0x5f */ | |
176 { | |
177 /* | |
178 * If a structurally correct message has been detected, | |
179 * containing erroneous data, an Assignment Failure message | |
180 * is sent back. | |
181 */ | |
182 | |
183 /* | |
184 * If the ASSIGNMENT COMMAND is erroneous, then the | |
185 * ASSIGNMENT FAILURE command is sent via a priority | |
186 * DL_RECONNECT_REQ. This ensures DL will halt processing | |
187 * anything in its buffer until it has sent this message | |
188 * onto the nw. | |
189 * | |
190 */ | |
191 for_suspend_layer_2 (); | |
192 dat_send_assign_fail_msg(rr_data->ms_data.error.val); | |
193 | |
194 RR_EM_SET_ASSIGN_FAIL_CAUSE(rr_data->ms_data.error.val); | |
195 | |
196 PFREE (dedicated_req); | |
197 PFREE (dl_data_ind); | |
198 break; | |
199 } | |
200 | |
201 default: | |
202 /* | |
203 * the initial check was successful and the | |
204 * message is processed. | |
205 * | |
206 */ | |
207 for_suspend_layer_2 (); | |
208 | |
209 /* | |
210 * use data of the old cell if no new data | |
211 * are inserted in the message | |
212 */ | |
213 rr_data->cr_data.ch_mode = rr_data->sc_data.ch_mode; | |
214 rr_data->cr_data.ciph_on = rr_data->sc_data.ciph_on; | |
215 rr_data->cr_data.algo = rr_data->sc_data.algo; | |
216 rr_data->cr_data.cd.v_cell_chan_desc = | |
217 rr_data->sc_data.cd.v_cell_chan_desc; | |
218 memcpy (&rr_data->cr_data.cd.cell_chan_desc, | |
219 &rr_data->sc_data.cd.cell_chan_desc, | |
220 sizeof (T_LIST)); | |
221 | |
222 /* | |
223 * if AMR is supported set the default values | |
224 * to the current serving cell values. | |
225 */ | |
226 if(rr_data->sc_data.ch_mode EQ CM_AMR) | |
227 { | |
228 memcpy(&rr_data->cr_data.amr_conf, | |
229 &rr_data->sc_data.amr_conf, | |
230 sizeof (T_multirate_conf)); | |
231 } | |
232 else { | |
233 /* | |
234 * AMR is not supported, therefore set some dummy values. This is necessary because | |
235 * the later Layer1 configuration must include an AMR configuration!! | |
236 */ | |
237 memset(&rr_data->cr_data.amr_conf, 0, sizeof (T_multirate_conf)); | |
238 } | |
239 | |
240 if (assign_cmd->v_cell_chan_desc) | |
241 { | |
242 /* | |
243 * If the message contains a cell channel description | |
244 * use the new one. | |
245 */ | |
246 memcpy (&rr_data->cr_data.cd.cell_chan_desc, | |
247 cell_chan_desc, | |
248 sizeof (T_LIST)); | |
249 rr_data->cr_data.cd.v_cell_chan_desc = WITH_CHANGED_CONTENT; | |
250 } | |
251 | |
252 if (assign_cmd->v_chan_mode) | |
253 /* | |
254 * if the message contains a channel mode, use the new one. | |
255 */ | |
256 rr_data->cr_data.ch_mode = assign_cmd->chan_mode; | |
257 | |
258 /* | |
259 * If AMR is signalled check if new multi-rate speech codec is part of the assignment cmd | |
260 * otherwise use default values set earlier. | |
261 */ | |
262 | |
263 /* Implements RR Clone findings #9 */ | |
264 dat_cr_data_multirate_conf(assign_cmd->v_multirate_conf,&assign_cmd->multirate_conf); | |
265 | |
266 | |
267 if (assign_cmd->v_ciph_mode_set) | |
268 { | |
269 /* | |
270 * If ciphering is defined in the message, handle it. | |
271 */ | |
272 rr_data->cr_data.ciph_on = assign_cmd->ciph_mode_set.sc; | |
273 rr_data->cr_data.algo = assign_cmd->ciph_mode_set.algo_ident; | |
274 | |
275 if (rr_data->cr_data.ciph_on EQ CIPH_ON AND | |
276 rr_data->sc_data.ciph_received EQ FALSE) | |
277 { | |
278 /* | |
279 * if ciphering is not active, but set in the message | |
280 * this is a failure and the configuration is aborted. | |
281 * Instead the reconnection on the old channel is started. | |
282 */ | |
283 dat_send_assign_fail_msg(RRC_PROT_UNSPECIFIED); | |
284 | |
285 RR_EM_SET_ASSIGN_FAIL_CAUSE(RRC_PROT_UNSPECIFIED); | |
286 | |
287 PFREE (dedicated_req); | |
288 PFREE (dl_data_ind); | |
289 | |
290 return; | |
291 } | |
292 } | |
293 | |
294 if (assign_cmd->chan_desc.hop EQ 1 AND | |
295 assign_cmd->v_mob_alloc_after) | |
296 { | |
297 if (rr_data->cr_data.cd.v_cell_chan_desc EQ NO_CONTENT) | |
298 { | |
299 /* | |
300 * If the new channel needs hopping, but there is no | |
301 * cell channel description available, the configuration | |
302 * is aborted due to a conditional error. | |
303 * Instead the reconnection on the old channel is started. | |
304 */ | |
305 dat_send_assign_fail_msg(RRC_NO_CELL_ALLOC); | |
306 | |
307 RR_EM_SET_ASSIGN_FAIL_CAUSE(RRC_NO_CELL_ALLOC); | |
308 | |
309 PFREE (dedicated_req); | |
310 PFREE (dl_data_ind); | |
311 return; | |
312 } | |
313 | |
314 /* | |
315 * if the message contains a mobile allocation, | |
316 * build a list of 1-bits from the bitmap. | |
317 */ | |
318 att_bits_to_byte (mob_alloc, | |
319 assign_cmd->mob_alloc_after.c_mac, | |
320 assign_cmd->mob_alloc_after.mac); | |
321 | |
322 /* | |
323 * create a hopping list from mobile allocation and cell channel | |
324 * description | |
325 */ | |
326 if(!srv_create_chan_mob_alloc (&rr_data->cr_data.cd.cell_chan_desc, | |
327 hop_list_after, | |
328 mob_alloc)) | |
329 { | |
330 dat_send_assign_fail_msg(RRC_FREQ_NOT_IMPL); | |
331 | |
332 RR_EM_SET_ASSIGN_FAIL_CAUSE(RRC_FREQ_NOT_IMPL); | |
333 | |
334 PFREE (dedicated_req); | |
335 PFREE (dl_data_ind); | |
336 return; | |
337 } | |
338 } | |
339 | |
340 /* | |
341 * clean primitive to layer 1 | |
342 */ | |
343 memset (dedicated_req, 0, sizeof (T_MPH_DEDICATED_REQ)); | |
344 | |
345 dedicated_req->mod = MODE_CHAN_ASSIGN; | |
346 | |
347 rr_data->cr_data.chan_desc = assign_cmd->chan_desc; | |
348 | |
349 /* | |
350 * Set Channel Type | |
351 */ | |
352 dedicated_req->ch_type.ch = assign_cmd->chan_desc.chan_type; | |
353 dedicated_req->ch_type.tn = assign_cmd->chan_desc.tn; | |
354 dedicated_req->ch_type.tsc = assign_cmd->chan_desc.tsc; | |
355 dedicated_req->ch_type.h = assign_cmd->chan_desc.hop; | |
356 if (assign_cmd->chan_desc.hop EQ H_NO) | |
357 { | |
358 dedicated_req->ch_type.arfcn = assign_cmd->chan_desc.arfcn; | |
359 } | |
360 else | |
361 { | |
362 dedicated_req->ch_type.maio = assign_cmd->chan_desc.maio; | |
363 dedicated_req->ch_type.hsn = assign_cmd->chan_desc.hsn; | |
364 | |
365 /* CSI-LLD section:4.1.1.11 | |
366 * This function Updates the black list with the MA list received | |
367 * inthe assignment command | |
368 */ | |
369 cs_remove_BA_MA_from_black_list(rr_data->cs_data.region,hop_list_after); | |
370 | |
371 srv_create_list (hop_list_after, dedicated_req->ch_type.ma, | |
372 MAX_MA_CHANNELS, TRUE, 0); | |
373 } | |
374 | |
375 /* | |
376 * set initial power | |
377 */ | |
378 dedicated_req->tr_para.power = assign_cmd->pow_cmd.pow; | |
379 | |
380 /* | |
381 * set starting time if available. | |
382 */ | |
383 if (assign_cmd->v_start_time) | |
384 { | |
385 dedicated_req->start.v_start = TRUE; | |
386 dedicated_req->start.t1 = assign_cmd->start_time.t1; | |
387 dedicated_req->start.t2 = assign_cmd->start_time.t2; | |
388 dedicated_req->start.t3 = assign_cmd->start_time.t3; | |
389 } | |
390 | |
391 /* | |
392 * Setting of before starting time elements ! | |
393 */ | |
394 if (assign_cmd->v_chan_desc_before EQ FALSE) | |
395 dedicated_req->ch_type2.ch = NOT_PRESENT_8BIT; | |
396 else | |
397 { | |
398 if (assign_cmd->v_mob_alloc_before) | |
399 { | |
400 att_bits_to_byte (mob_alloc, | |
401 assign_cmd->mob_alloc_before.c_mac, | |
402 assign_cmd->mob_alloc_before.mac); | |
403 if(!srv_create_chan_mob_alloc (&rr_data->cr_data.cd.cell_chan_desc, | |
404 hop_list_before, | |
405 mob_alloc)) | |
406 { | |
407 dat_send_assign_fail_msg(RRC_FREQ_NOT_IMPL); | |
408 | |
409 RR_EM_SET_ASSIGN_FAIL_CAUSE( RRC_FREQ_NOT_IMPL); | |
410 | |
411 PFREE (dedicated_req); | |
412 PFREE (dl_data_ind); | |
413 return; | |
414 } | |
415 } | |
416 | |
417 dat_dedicated_req_ch_type2(&dedicated_req->ch_type2, &assign_cmd->chan_desc_before, | |
418 hop_list_before ); | |
419 | |
420 } | |
421 | |
422 | |
423 /* | |
424 * set dtx depending on the channel type (halfrate or fullrate) | |
425 */ | |
426 | |
427 if (dedicated_req->ch_type.ch EQ 2 OR | |
428 dedicated_req->ch_type.ch EQ 3) | |
429 dedicated_req->tr_para.dtx = | |
430 rr_data->sc_data.cd.dtx = rr_data->sc_data.cd.dtx_half; | |
431 else | |
432 dedicated_req->tr_para.dtx = | |
433 rr_data->sc_data.cd.dtx = rr_data->sc_data.cd.dtx_full; | |
434 | |
435 dedicated_req->arfcn = rr_data->nc_data[SC_INDEX].arfcn; | |
436 dedicated_req->tr_para.rlt = rr_data->sc_data.cd.cell_options.rlt; | |
437 dedicated_req->tr_para.pwrc = rr_data->sc_data.cd.cell_options.pow_ctrl; | |
438 dedicated_req->tr_para.mode = rr_data->cr_data.ch_mode; | |
439 | |
440 /* | |
441 * Set multi-rate speech codec | |
442 */ | |
443 dedicated_req->amr_conf.nscb = rr_data->cr_data.amr_conf.nscb; | |
444 dedicated_req->amr_conf.icmi = rr_data->cr_data.amr_conf.icmi; | |
445 dedicated_req->amr_conf.st_mode = rr_data->cr_data.amr_conf.st_mode; | |
446 dedicated_req->amr_conf.acs = rr_data->cr_data.amr_conf.set_amr; | |
447 | |
448 /* | |
449 * valid flag for the threshold and hystersis values. amr_conf.c_cod_prop | |
450 * defines the number of threshold and hystersis values. | |
451 */ | |
452 dedicated_req->amr_conf.v_cod_prop = rr_data->cr_data.amr_conf.v_cod_prop; | |
453 | |
454 if(dedicated_req->amr_conf.v_cod_prop) | |
455 { | |
456 int i; | |
457 dedicated_req->amr_conf.c_cod_prop = rr_data->cr_data.amr_conf.c_cod_prop; | |
458 for(i=0; i<dedicated_req->amr_conf.c_cod_prop; i++) | |
459 memcpy(&dedicated_req->amr_conf.cod_prop[i], | |
460 &rr_data->cr_data.amr_conf.cod_prop[i], | |
461 sizeof(T_cod_prop)); | |
462 } | |
463 | |
464 if (rr_data->cr_data.ciph_on) | |
465 { | |
466 /* | |
467 * set cipher parameter if available. | |
468 */ | |
469 dedicated_req->ciph.stat = rr_data->cr_data.ciph_on; | |
470 dedicated_req->ciph.algo = rr_data->cr_data.algo; | |
471 memcpy (dedicated_req->ciph.kc, rr_data->ms_data.kc, KC_STRING_SIZE); | |
472 } | |
473 | |
474 RR_EM_GET_HOPPING_CHANNEL (dedicated_req->ch_type.ma, dedicated_req->ch_type2.ma, | |
475 dedicated_req->start.v_start,dedicated_req->ch_type2.maio); | |
476 | |
477 EM_ASSIGNMENT_RECEIVED; | |
478 | |
479 /* | |
480 * configure layer 1 | |
481 */ | |
482 SET_STATE (STATE_DAT, DAT_CHAN_ASS); | |
483 PSENDX (PL, dedicated_req); | |
484 PFREE (dl_data_ind); | |
485 return; | |
486 } | |
487 break; | |
488 | |
489 default: | |
490 PFREE (dedicated_req); | |
491 PFREE (dl_data_ind); | |
492 break; | |
493 } | |
494 } | |
495 | |
496 /* | |
497 +--------------------------------------------------------------------+ | |
498 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
499 | STATE : code ROUTINE : dat_for_chan_mod | | |
500 +--------------------------------------------------------------------+ | |
501 | |
502 PURPOSE : The function handles a received channel mode modify message. | |
503 | |
504 */ | |
505 | |
506 GLOBAL void dat_for_chan_mod (T_DL_DATA_IND *dl_data_ind, | |
507 T_D_CHAN_MOD *chan_mod) | |
508 { | |
509 GET_INSTANCE_DATA; | |
510 MCAST (chan_mod_ack, U_CHAN_MOD_ACK); | |
511 | |
512 TRACE_FUNCTION ("dat_for_chan_mod()"); | |
513 | |
514 if (rr_data->ms_data.error.cs EQ 0) | |
515 { | |
516 /* | |
517 * the check in the formatter indicates no problems | |
518 * store new channel mode. | |
519 */ | |
520 rr_data->sc_data.ch_mode = chan_mod->chan_mode; | |
521 | |
522 /* | |
523 * the channel mode modify message contains a multi-rate configuration IEI | |
524 */ | |
525 if( chan_mod->v_multirate_conf AND (chan_mod->chan_mode EQ CM_AMR) ) | |
526 { | |
527 int i; | |
528 rr_data->sc_data.amr_conf.mr_vers = chan_mod->multirate_conf.mr_vers; | |
529 rr_data->sc_data.amr_conf.nscb = chan_mod->multirate_conf.nscb; | |
530 rr_data->sc_data.amr_conf.icmi = chan_mod->multirate_conf.icmi; | |
531 rr_data->sc_data.amr_conf.st_mode = chan_mod->multirate_conf.st_mode; | |
532 rr_data->sc_data.amr_conf.set_amr = chan_mod->multirate_conf.set_amr; | |
533 | |
534 rr_data->sc_data.amr_conf.v_cod_prop = chan_mod->multirate_conf.v_cod_prop; | |
535 if(rr_data->sc_data.amr_conf.v_cod_prop) | |
536 { | |
537 rr_data->sc_data.amr_conf.c_cod_prop = chan_mod->multirate_conf.c_cod_prop; | |
538 for (i=0; i< rr_data->sc_data.amr_conf.c_cod_prop; i++) | |
539 memcpy(&rr_data->sc_data.amr_conf.cod_prop[i], &chan_mod->multirate_conf.cod_prop[i], sizeof(T_cod_prop)); | |
540 } | |
541 } | |
542 | |
543 /* | |
544 * configure layer 1 | |
545 */ | |
546 dat_code_mph_chan_mode_req (chan_mod); | |
547 | |
548 EM_CHANNEL_MODE_MODIFY; | |
549 | |
550 /* | |
551 * indicate new channel mode to MM | |
552 */ | |
553 dat_code_channel_mode_to_mm (); | |
554 } | |
555 | |
556 { | |
557 /* | |
558 * build the answer to the network | |
559 * (channel mode modify acknowledge message) | |
560 */ | |
561 PALLOC_MSG (dl_data_req, DL_DATA_REQ, U_CHAN_MOD_ACK); | |
562 | |
563 /* | |
564 * set channel type and SAPI | |
565 */ | |
566 dat_code_prr_channel (&dl_data_req->ch_type, | |
567 &dl_data_req->sapi, | |
568 rr_data->sc_data.chan_desc.chan_type); | |
569 | |
570 chan_mod_ack->msg_type = U_CHAN_MOD_ACK; | |
571 memcpy (&chan_mod_ack->chan_desc, | |
572 &rr_data->sc_data.chan_desc, | |
573 sizeof (T_chan_desc)); | |
574 | |
575 /* | |
576 * set the current channel mode. if the new | |
577 * channel mode is supported by the MS, the new | |
578 * one is returned, else it is the previous one | |
579 * and layer 1 was not re-configured. | |
580 */ | |
581 chan_mod_ack->chan_mode = rr_data->sc_data.ch_mode; | |
582 | |
583 for_dat_data_req (dl_data_req); | |
584 | |
585 EM_CHANNEL_MODE_MODIFY_ACK; | |
586 } | |
587 | |
588 PFREE(dl_data_ind); | |
589 } | |
590 | |
591 /* | |
592 +--------------------------------------------------------------------+ | |
593 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
594 | STATE : code ROUTINE : dat_for_chan_rel | | |
595 +--------------------------------------------------------------------+ | |
596 | |
597 PURPOSE : Reception of a channel release message. | |
598 | |
599 */ | |
600 | |
601 GLOBAL void dat_for_chan_rel (T_DL_DATA_IND *dl_data_ind, | |
602 T_D_CHAN_REL *chan_rel) | |
603 { | |
604 GET_INSTANCE_DATA; | |
605 TRACE_FUNCTION ("dat_for_chan_rel()"); | |
606 | |
607 if (GET_STATE (STATE_DAT) NEQ DAT_NULL) | |
608 { | |
609 /* | |
610 * disconnect layer 2 link | |
611 */ | |
612 dat_disconnect_link (CAUSE_MAKE (DEFBY_STD, | |
613 ORIGSIDE_NET, | |
614 RR_ORIGINATING_ENTITY, | |
615 chan_rel->rr_cause)); | |
616 | |
617 #ifdef GPRS | |
618 if (chan_rel->v_gprs_resum) | |
619 { | |
620 rr_data->gprs_data.gprs_resump = chan_rel->gprs_resum.res_ack; | |
621 } | |
622 /* | |
623 o if the element is not available but we have send a susp_req | |
624 a resumption failure has occured (gprs_resump was already set | |
625 on tx of the suspension request) | |
626 o if the element is not present and we have not send a suspension | |
627 request there is no resumption failure. | |
628 o For Ericsson we have to do a RAU after every CS call even if the | |
629 call started on a GSM-only cell and we did not send a suspension request */ | |
630 else | |
631 if(att_gprs_is_avail()) | |
632 rr_data->gprs_data.gprs_resump = GPRS_RESUMPTION_NOT_ACK; | |
633 #endif | |
634 | |
635 if (chan_rel->v_ba_range) | |
636 { | |
637 /* | |
638 * convert RR_BA_RANGE to BCCH-LIST and | |
639 * send it with RR SYNC IND to MM | |
640 */ | |
641 dat_code_prr_bcch_info (chan_rel->v_ba_range, | |
642 &chan_rel->ba_range); | |
643 } | |
644 | |
645 EM_CHANNEL_RELEASE; | |
646 } | |
647 PFREE (dl_data_ind); | |
648 } | |
649 | |
650 /* | |
651 +--------------------------------------------------------------------+ | |
652 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
653 | STATE : code ROUTINE : dat_for_class_enq | | |
654 +--------------------------------------------------------------------+ | |
655 | |
656 PURPOSE : Reception of a classmark enquiry message. | |
657 | |
658 */ | |
659 | |
660 #ifdef REL99 | |
661 GLOBAL void dat_for_class_enq (T_DL_DATA_IND *dl_data_ind, | |
662 T_D_CLASS_ENQ *class_enq) | |
663 #else | |
664 GLOBAL void dat_for_class_enq (T_DL_DATA_IND *dl_data_ind) | |
665 #endif | |
666 { | |
667 TRACE_FUNCTION ("dat_for_class_enq()"); | |
668 | |
669 | |
670 if (dat_check_error_flag (SEND_RR_STATUS)) | |
671 { | |
672 /* | |
673 * The syntax check indicates no problems, then | |
674 * process the message. | |
675 * | |
676 * The MS returns a classmark change message. | |
677 */ | |
678 /* Implements RR Clone findings #15 */ | |
679 #ifdef REL99 | |
680 /*Perform checks on classmark enquiry mask IE, if present*/ | |
681 if ((class_enq->v_class_enq_mask EQ FALSE) OR | |
682 ((class_enq->v_class_enq_mask EQ TRUE) AND | |
683 (class_enq->class_enq_mask.class_req EQ CLASS_CHANGE_REQ) ) ) | |
684 #endif | |
685 dat_class_chng_data_req(); | |
686 } | |
687 | |
688 | |
689 EM_CLASSMARK_ENQUIRY; | |
690 | |
691 PFREE (dl_data_ind); | |
692 } | |
693 | |
694 /* | |
695 +--------------------------------------------------------------------+ | |
696 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
697 | STATE : code ROUTINE : send_mph_tch_loop_req | | |
698 +--------------------------------------------------------------------+ | |
699 | |
700 PURPOSE : Send the L1 primitive for close TCH loop. | |
701 | |
702 */ | |
703 | |
704 static void send_mph_tch_loop_req(T_DL_DATA_IND * dl_data_ind, | |
705 UBYTE loop_command) | |
706 { | |
707 /* | |
708 * configure layer 1 | |
709 */ | |
710 PREUSE (dl_data_ind, loop_req, MPH_TCH_LOOP_REQ);/* T_MPH_TCH_LOOP_REQ */ | |
711 loop_req->tch_loop = loop_command; | |
712 PSENDX (PL, loop_req); | |
713 } | |
714 | |
715 /* | |
716 +-----------------------------------------------------------------------+ | |
717 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
718 | STATE : code ROUTINE : send_close_tch_loop_ack_to_nw | | |
719 +-----------------------------------------------------------------------+ | |
720 | |
721 PURPOSE : Send the CLOSE TCH LOOP ACK message to the network. | |
722 | |
723 */ | |
724 static void send_close_tch_loop_ack_to_nw(void) | |
725 { | |
726 GET_INSTANCE_DATA; | |
727 /* | |
728 * if the TCH loop is open and a TCH is assigned | |
729 */ | |
730 | |
731 PALLOC_SDU (data_req, DL_DATA_REQ, 2*BITS_PER_BYTE); | |
732 /* | |
733 * set channel type and sapi for the response to the network | |
734 */ | |
735 dat_code_prr_channel (&data_req->ch_type, | |
736 &data_req->sapi, | |
737 rr_data->sc_data.chan_desc.chan_type); | |
738 | |
739 /* | |
740 * code the message without CCD | |
741 */ | |
742 data_req->sdu.l_buf = 16; | |
743 data_req->sdu.o_buf = ENCODE_OFFSET; | |
744 data_req->sdu.buf [0] = 0; | |
745 /*lint -e415 -e416 Likely access of out-of-bounds pointer*/ | |
746 data_req->sdu.buf [1] = 0; | |
747 data_req->sdu.buf [2] = 0; | |
748 data_req->sdu.buf [3] = 0x0F; /* TI=0, PD = TST */ | |
749 data_req->sdu.buf [4] = 0x01; /* MT = Close TCH Ack */ | |
750 /*lint +e415 +e416 Likely access of out-of-bounds pointer*/ | |
751 TRACE_EVENT ("DL_DATA_REQ (RR message)"); | |
752 | |
753 EM_TCH_LOOP_CLOSED; | |
754 | |
755 PSENDX (DL, data_req); | |
756 } | |
757 | |
758 | |
759 /* | |
760 +--------------------------------------------------------------------+ | |
761 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
762 | STATE : code ROUTINE : dat_for_close_loop_cmd | | |
763 +--------------------------------------------------------------------+ | |
764 | |
765 PURPOSE : Reception of a TCH Close Loop Command message. | |
766 | |
767 */ | |
768 | |
769 static const UBYTE LOOP_TYPE [32] = | |
770 { /* C B A Z Y */ | |
771 0x00, /* 0 0 0 0 0 -> Type A */ | |
772 0x01, /* 0 0 0 0 1 -> Type B */ | |
773 0x02, /* 0 0 0 1 0 -> Type C */ | |
774 0x02, /* 0 0 0 1 1 -> Type C */ | |
775 0x03, /* 0 0 1 0 0 -> Type D */ | |
776 0x03, /* 0 0 1 0 1 -> Type D */ | |
777 0x03, /* 0 0 1 1 0 -> Type D */ | |
778 0x03, /* 0 0 1 1 1 -> Type D */ | |
779 0x04, /* 0 1 0 0 0 -> Type E */ | |
780 0x04, /* 0 1 0 0 1 -> Type E */ | |
781 0x04, /* 0 1 0 1 0 -> Type E */ | |
782 0x04, /* 0 1 0 1 1 -> Type E */ | |
783 0x05, /* 0 1 1 0 0 -> Type F */ | |
784 0x05, /* 0 1 1 0 1 -> Type F */ | |
785 0x05, /* 0 1 1 1 0 -> Type F */ | |
786 0x05, /* 0 1 1 1 1 -> Type F */ | |
787 0xFF, /* 1 0 0 0 0 -> Not valid */ | |
788 0xFF, /* 1 0 0 0 1 -> Not valid */ | |
789 0xFF, /* 1 0 0 1 0 -> Not valid */ | |
790 0xFF, /* 1 0 0 1 1 -> Not valid */ | |
791 0xFF, /* 1 0 1 0 0 -> Not valid */ | |
792 0xFF, /* 1 0 1 0 1 -> Not valid */ | |
793 0xFF, /* 1 0 1 1 0 -> Not valid */ | |
794 0xFF, /* 1 0 1 1 1 -> Not valid */ | |
795 0xFF, /* 1 1 0 0 0 -> Not valid */ | |
796 0xFF, /* 1 1 0 0 1 -> Not valid */ | |
797 0xFF, /* 1 1 0 1 0 -> Not valid */ | |
798 0xFF, /* 1 1 0 1 1 -> Not valid */ | |
799 0x06, /* 1 1 1 0 0 -> Type I */ | |
800 0x06, /* 1 1 1 0 1 -> Type I */ | |
801 0x06, /* 1 1 1 1 0 -> Type I */ | |
802 0x06 /* 1 1 1 1 1 -> Type I */ | |
803 }; | |
804 | |
805 | |
806 GLOBAL void dat_for_close_loop_cmd (T_DL_DATA_IND * dl_data_ind, | |
807 UBYTE subchannel) | |
808 { | |
809 GET_INSTANCE_DATA; | |
810 UBYTE loop_command = NOT_PRESENT_8BIT; | |
811 | |
812 TRACE_FUNCTION ("dat_for_close_loop_cmd()"); | |
813 | |
814 if (dat_test_sim_available () OR !dat_check_sim_available () ) | |
815 { | |
816 /* | |
817 * only if a test SIM card is inserted | |
818 */ | |
819 if ((rr_data->tch_loop_subch EQ NOT_PRESENT_8BIT) AND | |
820 rr_data->sc_data.chan_desc.chan_type < CH_SDCCH_4_0) | |
821 { | |
822 switch ((loop_command = LOOP_TYPE [(subchannel>>1) & 0x1F])) | |
823 { | |
824 case TCH_LOOP_C: /* Loop C */ | |
825 /* first send ACK msg, then activate L1 */ | |
826 send_close_tch_loop_ack_to_nw(); | |
827 /* | |
828 * Delay to allow L1/HW to switch | |
829 */ | |
830 vsi_t_sleep (VSI_CALLER DELAY_CLOSE_TCH_LOOP_ACK); | |
831 send_mph_tch_loop_req(dl_data_ind, loop_command); | |
832 /* will be needed when TCH Open Loop Command will be received */ | |
833 rr_data->tch_loop_subch = loop_command; | |
834 break; | |
835 case TCH_LOOP_I: /* Loop I */ | |
836 if (rr_data->sc_data.ch_mode NEQ CM_AMR) | |
837 { | |
838 PFREE (dl_data_ind); | |
839 break; | |
840 } | |
841 case TCH_LOOP_A: | |
842 case TCH_LOOP_B: | |
843 case TCH_LOOP_D: | |
844 case TCH_LOOP_E: | |
845 case TCH_LOOP_F: | |
846 /* Loop A, B, D, E, F, I */ | |
847 send_mph_tch_loop_req(dl_data_ind, loop_command); | |
848 /* | |
849 * Delay to allow L1/HW to switch | |
850 */ | |
851 vsi_t_sleep (VSI_CALLER DELAY_CLOSE_TCH_LOOP_ACK); | |
852 send_close_tch_loop_ack_to_nw(); | |
853 /* will be needed when TCH Open Loop Command will be received */ | |
854 rr_data->tch_loop_subch = loop_command; | |
855 break; | |
856 default : | |
857 TRACE_EVENT_P1("TCH_LOOP_CLOSE_CMD : wrong subchannel (%x)", subchannel); | |
858 PFREE (dl_data_ind); | |
859 break; | |
860 } | |
861 } | |
862 else | |
863 { | |
864 PFREE (dl_data_ind); | |
865 } | |
866 } | |
867 else | |
868 { | |
869 PFREE (dl_data_ind); | |
870 } | |
871 } | |
872 | |
873 /* | |
874 +--------------------------------------------------------------------+ | |
875 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
876 | STATE : code ROUTINE : dat_for_test_interface | | |
877 +--------------------------------------------------------------------+ | |
878 | |
879 PURPOSE : Reception of a Test-Interface message. | |
880 | |
881 */ | |
882 | |
883 GLOBAL void dat_for_test_interface (T_DL_DATA_IND * dl_data_ind, | |
884 UBYTE tested_device) | |
885 { | |
886 TRACE_FUNCTION ("dat_for_test_interface()"); | |
887 | |
888 if (dat_test_sim_available ()) | |
889 { | |
890 /* | |
891 * Only if a test SIM card is inserted | |
892 * | |
893 * then configure layer 1 | |
894 */ | |
895 PREUSE (dl_data_ind, dai_req, MPH_DAI_REQ); /* T_MPH_DAI_REQ */ | |
896 | |
897 dai_req->device = tested_device; | |
898 | |
899 EM_TEST_INTERFACE; | |
900 | |
901 PSENDX (PL, dai_req); | |
902 } | |
903 else | |
904 { | |
905 /* | |
906 * else ignore the message | |
907 */ | |
908 PFREE (dl_data_ind); | |
909 } | |
910 } | |
911 | |
912 /* | |
913 +--------------------------------------------------------------------+ | |
914 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
915 | STATE : code ROUTINE : dat_for_ciph_cmd | | |
916 +--------------------------------------------------------------------+ | |
917 | |
918 PURPOSE : Reception of a cipher mode command message. | |
919 | |
920 */ | |
921 | |
922 GLOBAL void dat_for_ciph_cmd (T_DL_DATA_IND *dl_data_ind, | |
923 T_D_CIPH_CMD *ciph_cmd) | |
924 { | |
925 GET_INSTANCE_DATA; | |
926 TRACE_FUNCTION ("dat_for_cyph_cmd()"); | |
927 | |
928 if (dat_check_error_flag (SEND_RR_STATUS)) | |
929 { | |
930 /* | |
931 * the check in the formatter was successful | |
932 */ | |
933 if ( | |
934 ((rr_data->sc_data.ciph_on EQ CIPH_ON) AND | |
935 (ciph_cmd->ciph_mode_set.sc EQ START_CIPH_YES)) | |
936 OR | |
937 ((ciph_cmd->ciph_mode_set.sc EQ START_CIPH_YES) AND | |
938 (rr_data->dyn_config.nkc EQ 0 AND rr_data->ms_data.cksn > 6)) | |
939 ) | |
940 { | |
941 /* | |
942 * Respond with RR Status in 2 cases | |
943 * | |
944 * 1: if NW re-enables ciphering | |
945 * 2: if network has enabled ciphering "and" no valid ciphering key | |
946 * is available (and user specific handling of cksn is | |
947 * disabled (nck==0)). | |
948 * If network has not enabled ciphering, then ciphering key | |
949 * value is not checked | |
950 */ | |
951 dat_send_rr_status_msg(RRC_PROT_UNSPECIFIED); | |
952 } | |
953 else | |
954 { | |
955 MCAST (ciph_comp, U_CIPH_COMP); | |
956 PALLOC_MSG (dl_data_req, DL_DATA_REQ, U_CIPH_COMP); | |
957 | |
958 /* | |
959 * set channel type and SAPI for response to the network | |
960 */ | |
961 dat_code_prr_channel (&dl_data_req->ch_type, | |
962 &dl_data_req->sapi, | |
963 rr_data->sc_data.chan_desc.chan_type); | |
964 | |
965 /* | |
966 * store cipher parameter | |
967 */ | |
968 rr_data->sc_data.ciph_on = ciph_cmd->ciph_mode_set.sc; | |
969 | |
970 rr_data->sc_data.algo = ciph_cmd->ciph_mode_set.algo_ident; | |
971 rr_data->sc_data.ciph_received = TRUE; | |
972 memcpy (rr_data->ms_data.kc, rr_data->ms_data.new_kc, KC_STRING_SIZE); | |
973 | |
974 /* | |
975 * configure layer 1 | |
976 */ | |
977 | |
978 if ( rr_data->ms_data.cksn <= 6 ) | |
979 { | |
980 dat_code_mph_ciphering_req (rr_data->sc_data.ciph_on, | |
981 rr_data->sc_data.algo, | |
982 rr_data->ms_data.kc); | |
983 } | |
984 else | |
985 { | |
986 dat_code_mph_ciphering_req (CIPH_OFF, 0, NULL); | |
987 } | |
988 | |
989 if (ciph_cmd->ciph_res.cr EQ INC_IMEISV_YES) | |
990 { | |
991 /* | |
992 * if the response shall contain the IMEI, fill it in. | |
993 */ | |
994 ciph_comp->v_mob_ident = TRUE; | |
995 memcpy (&ciph_comp->mob_ident, &rr_data->ms_data.imei, | |
996 sizeof (T_mob_ident)); | |
997 } | |
998 else | |
999 { | |
1000 ciph_comp->v_mob_ident = FALSE; | |
1001 } | |
1002 | |
1003 ciph_comp->msg_type = U_CIPH_COMP; | |
1004 | |
1005 /* | |
1006 * send response to the network | |
1007 */ | |
1008 for_dat_data_req (dl_data_req); | |
1009 | |
1010 /* | |
1011 * Indicate changed ciphering mode to MM. | |
1012 * Any supression of ciphering information to MMI/ACI will | |
1013 * be done by the upper layers. | |
1014 */ | |
1015 dat_code_ciphering_to_mm (rr_data->sc_data.ciph_on); | |
1016 | |
1017 EM_CIPHERING_CMD; | |
1018 } | |
1019 } | |
1020 | |
1021 PFREE (dl_data_ind); | |
1022 } | |
1023 | |
1024 /* | |
1025 +--------------------------------------------------------------------+ | |
1026 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
1027 | STATE : code ROUTINE : dat_for_freq_redef | | |
1028 +--------------------------------------------------------------------+ | |
1029 | |
1030 PURPOSE : Reception of a frequency redefinition message. | |
1031 | |
1032 */ | |
1033 | |
1034 GLOBAL void dat_for_freq_redef (T_DL_DATA_IND *dl_data_ind, | |
1035 T_D_FREQ_REDEF *freq_redef, | |
1036 T_LIST *cell_chan_desc) | |
1037 { | |
1038 GET_INSTANCE_DATA; | |
1039 T_start start; | |
1040 T_LIST hop_list; | |
1041 UBYTE mob_alloc[65]; | |
1042 | |
1043 TRACE_FUNCTION ("dat_for_freq_redef()"); | |
1044 | |
1045 if (dat_check_error_flag (SEND_RR_STATUS)) | |
1046 { | |
1047 /* | |
1048 * the check in the formatter has passed | |
1049 */ | |
1050 memcpy (&rr_data->sc_data.chan_desc, | |
1051 &freq_redef->chan_desc, | |
1052 sizeof (T_chan_desc)); | |
1053 | |
1054 /* | |
1055 * convert the mobile allocation from the message format | |
1056 * to a list of 1-bit positions to build the hopping list. | |
1057 */ | |
1058 att_bits_to_byte (mob_alloc, | |
1059 freq_redef->mob_alloc.c_mac, | |
1060 freq_redef->mob_alloc.mac); | |
1061 | |
1062 dat_set_last_used_channel (&rr_data->sc_data.chan_desc); | |
1063 | |
1064 if (freq_redef->v_cell_chan_desc) | |
1065 { | |
1066 /* | |
1067 * if the message contains a new cell channel description | |
1068 * copy the new one, else use the old one. | |
1069 */ | |
1070 srv_copy_list (&rr_data->sc_data.cd.cell_chan_desc, | |
1071 cell_chan_desc, | |
1072 sizeof (T_LIST)); | |
1073 rr_data->sc_data.cd.v_cell_chan_desc = WITH_CONTENT; | |
1074 } | |
1075 | |
1076 if (rr_data->sc_data.cd.v_cell_chan_desc NEQ NO_CONTENT) | |
1077 { | |
1078 /* | |
1079 * create the hopping list from cell channel description and | |
1080 * mobile allocation. | |
1081 */ | |
1082 if(! srv_create_chan_mob_alloc (&rr_data->sc_data.cd.cell_chan_desc, | |
1083 &hop_list, | |
1084 mob_alloc)) | |
1085 { | |
1086 | |
1087 U32 st = 51*((26 + freq_redef->start_time.t3 - freq_redef->start_time.t2 )%26) | |
1088 + freq_redef->start_time.t3 + 1326*freq_redef->start_time.t1; | |
1089 U32 ct = dl_data_ind->fn%STARTING_TIME_INTERVAL; | |
1090 | |
1091 #if defined(_SIMULATION_) | |
1092 TRACE_EVENT_WIN_P5 ("D_FREQ_REDEF: t1=%u t2=%u t3=%u, st=%u, ct=%u", | |
1093 freq_redef->start_time.t1, freq_redef->start_time.t2, | |
1094 freq_redef->start_time.t3, st, ct); | |
1095 TRACE_EVENT_WIN_P2 ("D_FREQ_REDEF: (st-ct) %u <= %u ?", | |
1096 ((STARTING_TIME_INTERVAL + st - ct)%STARTING_TIME_INTERVAL), STARTING_TIME_INTERVAL1); | |
1097 #endif | |
1098 | |
1099 if(((STARTING_TIME_INTERVAL + st - ct)%STARTING_TIME_INTERVAL) <= STARTING_TIME_INTERVAL1) | |
1100 { | |
1101 /*XXX this should only be done if the starting time has not yet expired */ | |
1102 dat_send_rr_status_msg(RRC_FREQ_NOT_IMPL); | |
1103 } | |
1104 else | |
1105 { | |
1106 /* | |
1107 * 3GPP TS 04.18, section 3.4.5.1 | |
1108 * Frequency redefinition procedure, abnormal cases: | |
1109 * If the mobile station receives a FREQUENCY REDEFINITION message | |
1110 * with a Mobile Allocation IE indexing frequencies that are not all | |
1111 * in one band and a Starting Time IE indicating a time that has | |
1112 * elapsed, then the mobile station shall locally abort the radio | |
1113 * connection and, if permitted, attempt Call Re-establishment. | |
1114 * | |
1115 * Inform MM about a radio link failure and start cell reselection. | |
1116 * It would be possible to create a new cause but RLF does exactly | |
1117 * what is needed and this is really 'some kind of' RLF. | |
1118 */ | |
1119 rr_data->net_lost = TRUE; | |
1120 att_code_rr_abort_ind (RRCS_ABORT_RAD_LNK_FAIL); | |
1121 att_stop_dedicated(); | |
1122 } | |
1123 } | |
1124 else | |
1125 { | |
1126 /* | |
1127 * copy start time for the new hopping list | |
1128 */ | |
1129 start.v_start = TRUE; | |
1130 start.t1 = freq_redef->start_time.t1; | |
1131 start.t2 = freq_redef->start_time.t2; | |
1132 start.t3 = freq_redef->start_time.t3; | |
1133 | |
1134 /* | |
1135 * configure layer 1 with the new hopping list | |
1136 */ | |
1137 dat_code_mph_freq_redef_req (&start, | |
1138 &hop_list); | |
1139 } | |
1140 } | |
1141 } | |
1142 | |
1143 PFREE (dl_data_ind); | |
1144 } | |
1145 | |
1146 /* | |
1147 +--------------------------------------------------------------------+ | |
1148 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
1149 | STATE : code ROUTINE : dat_for_handov_cmd | | |
1150 +--------------------------------------------------------------------+ | |
1151 | |
1152 PURPOSE : Reception of a handover command message. | |
1153 | |
1154 */ | |
1155 | |
1156 GLOBAL void dat_for_handov_cmd (T_DL_DATA_IND *dl_data_ind, | |
1157 T_D_HANDOV_CMD *handov_cmd, | |
1158 T_LIST *cell_chan_desc, | |
1159 T_LIST *hop_list_after, | |
1160 T_LIST *hop_list_before) | |
1161 { | |
1162 GET_INSTANCE_DATA; | |
1163 UBYTE mob_alloc [65]; | |
1164 | |
1165 TRACE_FUNCTION ("dat_for_handov_cmd()"); | |
1166 | |
1167 rr_data->dyn_config.fho = 0; | |
1168 | |
1169 /* | |
1170 * dynamic configuration command : IHO | |
1171 * Lock the DUT to the cell it is already camping - | |
1172 * Ignore the Handover command message and send an | |
1173 * Handover failure message to the network. | |
1174 */ | |
1175 | |
1176 if(rr_data->dyn_config.iho AND (rr_data->sc_data.ch_mode EQ CM_AMR)) | |
1177 { | |
1178 TRACE_EVENT("D_HANDOV_CMD : IHO"); | |
1179 for_set_content_error (RRC_CHANNEL_MODE); | |
1180 } | |
1181 | |
1182 switch (rr_data->ms_data.error.cs) | |
1183 { | |
1184 /* | |
1185 * in case of mandatory info element error, | |
1186 * the message is returned immediately. | |
1187 */ | |
1188 /* case RRC_INVALID_MAN_INFO: this value is currently never set */ | |
1189 case RRC_COND_IE_ERROR: | |
1190 { | |
1191 /* | |
1192 * build a RR status message. | |
1193 */ | |
1194 dat_send_rr_status_msg(rr_data->ms_data.error.cs); | |
1195 PFREE (dl_data_ind); | |
1196 break; | |
1197 } | |
1198 | |
1199 case RRC_INCORRECT_MSG: | |
1200 { | |
1201 /* | |
1202 * If a structurally correct message has been detected, | |
1203 * containing erroneous data, an Assignment Failure message | |
1204 * is sent back. | |
1205 */ | |
1206 | |
1207 /* | |
1208 * Even though it's not possible to go onto the new channel | |
1209 * we still need to suspend the current link and send the | |
1210 * HANDOVER FAILURE command via a priority DL_RECONNECT_REQ. | |
1211 * This ensures DL will halt processing anything in its | |
1212 * buffer until it has sent this message onto the nw | |
1213 */ | |
1214 for_suspend_layer_2 (); | |
1215 dat_send_handov_fail_msg(rr_data->ms_data.error.val); | |
1216 | |
1217 RR_EM_SET_HANDOVER_FAIL_CAUSE(rr_data->ms_data.error.val); | |
1218 | |
1219 PFREE (dl_data_ind); | |
1220 break; | |
1221 } | |
1222 | |
1223 | |
1224 default: | |
1225 /* | |
1226 * the message check has passed. | |
1227 * first of all suspend current layer 2 link | |
1228 */ | |
1229 | |
1230 TRACE_EVENT_P1 ("HO:default (%02x)", rr_data->ms_data.error.cs); | |
1231 | |
1232 for_suspend_layer_2 (); | |
1233 | |
1234 /* | |
1235 * set for the optional information elements | |
1236 * of the handover message the default value | |
1237 * to the current serving cell value. | |
1238 */ | |
1239 rr_data->cr_data.ch_mode = rr_data->sc_data.ch_mode; | |
1240 rr_data->cr_data.ciph_on = rr_data->sc_data.ciph_on; | |
1241 rr_data->cr_data.algo = rr_data->sc_data.algo; | |
1242 rr_data->cr_data.cd.v_cell_chan_desc = | |
1243 rr_data->sc_data.cd.v_cell_chan_desc; | |
1244 memcpy (&rr_data->cr_data.cd.cell_chan_desc, | |
1245 &rr_data->sc_data.cd.cell_chan_desc, | |
1246 sizeof (T_LIST)); | |
1247 | |
1248 /* | |
1249 * if AMR is supported set the default values | |
1250 * to the current serving cell values. | |
1251 */ | |
1252 if(rr_data->sc_data.ch_mode EQ CM_AMR) | |
1253 { | |
1254 memcpy(&rr_data->cr_data.amr_conf, | |
1255 &rr_data->sc_data.amr_conf, | |
1256 sizeof (T_multirate_conf)); | |
1257 } | |
1258 else { | |
1259 /* | |
1260 * AMR is not supported, therefore set some dummy values. This is necessary because | |
1261 * the later Layer1 configuration must include an AMR configuration!! | |
1262 */ | |
1263 memset(&rr_data->cr_data.amr_conf, 0, sizeof (T_multirate_conf)); | |
1264 } | |
1265 | |
1266 /* | |
1267 * set BSIC, BCCH channel number and channel description from | |
1268 * the handover command. | |
1269 */ | |
1270 rr_data->nc_data[CR_INDEX].bsic = (handov_cmd->cell_desc.ncc << 3) + | |
1271 handov_cmd->cell_desc.bcc; | |
1272 rr_data->nc_data[CR_INDEX].arfcn = handov_cmd->cell_desc.bcch_arfcn_lo + | |
1273 (handov_cmd->cell_desc.bcch_arfcn_hi << 8); | |
1274 memcpy (&rr_data->cr_data.chan_desc, | |
1275 &handov_cmd->chan_desc_after, | |
1276 sizeof (T_chan_desc)); | |
1277 | |
1278 if (handov_cmd->v_synch_ind) | |
1279 { | |
1280 /* | |
1281 * store the Handover synchronisation information if available. | |
1282 */ | |
1283 memcpy (&rr_data->ms_data.ho_type, &handov_cmd->synch_ind, | |
1284 sizeof (T_synch_ind)); | |
1285 } | |
1286 else | |
1287 { | |
1288 /* | |
1289 * else set the values to the default values. | |
1290 */ | |
1291 rr_data->ms_data.ho_type.rot = TIME_DIFF_NO; | |
1292 rr_data->ms_data.ho_type.nci = TRUE; | |
1293 rr_data->ms_data.ho_type.si = SYI_NON_SYNCH; | |
1294 } | |
1295 | |
1296 if (rr_data->ms_data.ho_type.si EQ SYI_PSEUDO_SYNCH AND | |
1297 ! rr_data->ms_data.classmark2.ps) | |
1298 { | |
1299 /* | |
1300 * if the handover requests a pseudo synchronized handover | |
1301 * and the mobile does not support this, a handover failure | |
1302 * message is send and the procedure is aborted with | |
1303 * reconnection to the old channel. | |
1304 */ | |
1305 dat_send_handov_fail_msg(RRC_INCORRECT_MSG); | |
1306 | |
1307 RR_EM_SET_HANDOVER_FAIL_CAUSE(RRC_INCORRECT_MSG); | |
1308 | |
1309 PFREE (dl_data_ind); | |
1310 return; | |
1311 } | |
1312 else | |
1313 { | |
1314 if (handov_cmd->v_cell_chan_desc) | |
1315 { | |
1316 /* | |
1317 * if the handover command contains a new cell channel description | |
1318 * copy the new list. | |
1319 */ | |
1320 srv_copy_list (&rr_data->cr_data.cd.cell_chan_desc, | |
1321 cell_chan_desc, | |
1322 sizeof (T_LIST)); | |
1323 rr_data->cr_data.cd.v_cell_chan_desc = WITH_CHANGED_CONTENT; | |
1324 } | |
1325 | |
1326 if (handov_cmd->v_chan_mode) | |
1327 { | |
1328 /* | |
1329 * store a new channel mode if available. | |
1330 */ | |
1331 rr_data->cr_data.ch_mode = handov_cmd->chan_mode; | |
1332 } | |
1333 | |
1334 | |
1335 /* | |
1336 * If AMR is signalled check if new multi-rate speech codec is part of the handover cmd | |
1337 * otherwise use default values set earlier. If AMR is not signalled use the dummy values | |
1338 * instead either set earlier. | |
1339 */ | |
1340 | |
1341 /* Implements RR Clone findings #9 */ | |
1342 dat_cr_data_multirate_conf(handov_cmd->v_multirate_conf, &handov_cmd->multirate_conf); | |
1343 | |
1344 | |
1345 if (handov_cmd->v_ciph_mode_set) | |
1346 { | |
1347 /* | |
1348 * if the message contains cipher mode parameter | |
1349 * copy the parameters | |
1350 */ | |
1351 rr_data->cr_data.ciph_on = handov_cmd->ciph_mode_set.sc; | |
1352 rr_data->cr_data.algo = handov_cmd->ciph_mode_set.algo_ident; | |
1353 | |
1354 /* | |
1355 * if ciphering is already enabled and the handover command | |
1356 * requests ciphering again, the procedure is aborted with | |
1357 * a handover failure message. | |
1358 */ | |
1359 if (rr_data->cr_data.ciph_on EQ CIPH_ON AND | |
1360 rr_data->sc_data.ciph_received EQ FALSE) | |
1361 { | |
1362 dat_send_handov_fail_msg(RRC_PROT_UNSPECIFIED); | |
1363 | |
1364 RR_EM_SET_HANDOVER_FAIL_CAUSE(RRC_PROT_UNSPECIFIED); | |
1365 | |
1366 PFREE (dl_data_ind); | |
1367 return; | |
1368 } | |
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 advance | |
1440 * 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 provide | |
1446 * to BTS 1 the value of OTD + t0 in the "HANDOVER COMPLETE" | |
1447 * message. | |
1448 * | |
1449 * NOTE : measurement_report.otd is the TA sent by the | |
1450 * network in downlink SACCH. TA is roundtrip propogation delay in bit periods. | |
1451 * t0 denotes the "one way" line of sight propagation delay between | |
1452 * the MS and BTS 0, in "half bits". | |
1453 * t0 = measurement_report.otd * 2 / 2. | |
1454 */ | |
1455 rr_data->sc_data.observed_ta = | |
1456 ( (rr_data->ms_data.measurement_report.ncells.time_alignmt[i1] | |
1457 + fn_offset* QUARTER_BITS_PER_FRAME)/2 | |
1458 + rr_data->ms_data.measurement_report.otd ) % 2097152; | |
1459 } | |
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. multirate_conf.c_cod_prop | |
2856 * defines the number of threshold and hystersis values. | |
2857 */ | |
2858 rr_data->cr_data.amr_conf.v_cod_prop = multirate_conf->v_cod_prop; | |
2859 | |
2860 if(rr_data->cr_data.amr_conf.v_cod_prop) | |
2861 { | |
2862 rr_data->cr_data.amr_conf.c_cod_prop = multirate_conf->c_cod_prop; | |
2863 | |
2864 for (i=0; i< multirate_conf->c_cod_prop; i++) | |
2865 memcpy(&rr_data->cr_data.amr_conf.cod_prop[i], &multirate_conf->cod_prop[i], sizeof(T_cod_prop)); | |
2866 } /* if(rr_data->cr_data.amr_conf.v_cod_prop) */ | |
2867 } /* if (assign_cmd->v_multirate_conf) */ | |
2868 } /* if (rr_data->cr_data.ch_mode EQ CM_AMR) */ | |
2869 } | |
2870 | |
2871 /* | |
2872 +--------------------------------------------------------------------+ | |
2873 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
2874 | STATE : code ROUTINE : dat_class_chng_data_req | | |
2875 +--------------------------------------------------------------------+ | |
2876 | |
2877 PURPOSE : This function forms a peer CLASSMARK CHANGE request | |
2878 | |
2879 */ | |
2880 GLOBAL void dat_class_chng_data_req(void) | |
2881 { | |
2882 GET_INSTANCE_DATA; | |
2883 | |
2884 TRACE_FUNCTION("dat_class_chng_data_req()"); | |
2885 /* | |
2886 * The syntax check indicates no problems, then | |
2887 * process the message. | |
2888 * | |
2889 * The MS returns a classmark change message. | |
2890 */ | |
2891 { | |
2892 MCAST (class_chng, U_CLASS_CHNG);/* T_U_CLASS_CHNG */ | |
2893 PALLOC_MSG (dl_data_req, DL_DATA_REQ, U_CLASS_CHNG); | |
2894 | |
2895 /* | |
2896 * set channel type and sapi | |
2897 */ | |
2898 dat_code_prr_channel (&dl_data_req->ch_type, | |
2899 &dl_data_req->sapi, rr_data->sc_data.chan_desc.chan_type); | |
2900 | |
2901 class_chng->msg_type = U_CLASS_CHNG; | |
2902 class_chng->mob_class_2 = rr_data->ms_data.classmark2; | |
2903 class_chng->mob_class_2.rf_pow_cap = att_get_power (); | |
2904 class_chng->mob_class_3 = rr_data->ms_data.classmark3; | |
2905 class_chng->v_mob_class_3 = rr_data->ms_data.classmark2.class3; | |
2906 | |
2907 for_dat_data_req (dl_data_req); | |
2908 } | |
2909 } | |
2910 /* | |
2911 +--------------------------------------------------------------------+ | |
2912 | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | |
2913 | STATE : code ROUTINE : dat_dedicated_req_ch_type2 | | |
2914 +--------------------------------------------------------------------+ | |
2915 | |
2916 PURPOSE : This function extracts the channle type from the channel | |
2917 description IE . | |
2918 | |
2919 */ | |
2920 LOCAL void dat_dedicated_req_ch_type2(T_ch_type2 *ch_type2, T_chan_desc_before *chan_desc_before, | |
2921 T_LIST *hop_list_before) | |
2922 { | |
2923 GET_INSTANCE_DATA; | |
2924 | |
2925 TRACE_FUNCTION("dat_dedicated_req_ch_type2()"); | |
2926 | |
2927 ch_type2->ch = chan_desc_before->chan_type; | |
2928 ch_type2->tn = chan_desc_before->tn; | |
2929 ch_type2->tsc = chan_desc_before->tsc; | |
2930 ch_type2->h = chan_desc_before->hop; | |
2931 if(ch_type2->h EQ H_NO) | |
2932 ch_type2->arfcn = chan_desc_before->arfcn; | |
2933 else | |
2934 { | |
2935 ch_type2->maio = chan_desc_before->maio; | |
2936 ch_type2->hsn = chan_desc_before->hsn; | |
2937 | |
2938 /* CSI-LLD section:4.1.1.11 | |
2939 * This function Updates the black list with the MA list received | |
2940 * in the assignment command | |
2941 */ | |
2942 cs_remove_BA_MA_from_black_list(rr_data->cs_data.region,hop_list_before); | |
2943 | |
2944 srv_create_list (hop_list_before, ch_type2->ma, | |
2945 MAX_MA_CHANNELS, TRUE, 0); | |
2946 } | |
2947 } | |
2948 | |
2949 #if defined (REL99) && defined (TI_PS_FF_EMR) | |
2950 /* | |
2951 +------------------------------------------------------------------------------ | |
2952 | Function : dat_for_meas_inf | |
2953 +------------------------------------------------------------------------------ | |
2954 | Description : Processing of measurement information message is done in this function. | |
2955 | All possible errors, if present, are detected and an error free MI-message | |
2956 | instance is decoded and data base updated with the enhanced measurement parameters. | |
2957 | Parameters : MI-message pointer | |
2958 | | |
2959 +------------------------------------------------------------------------------ | |
2960 */ | |
2961 GLOBAL BOOL dat_for_meas_inf (T_D_MEAS_INF *p_mi) | |
2962 { | |
2963 GET_INSTANCE_DATA; | |
2964 T_rr_enh_para *p_cur = &rr_data->sc_data.emr_data_current; | |
2965 T_rr_enh_para *p_temp = &rr_data->sc_data.emr_data_temp; | |
2966 BOOL send_enh_para = FALSE; | |
2967 T_gprs_rep_prio *p_rep = NULL; | |
2968 T_gprs_bsic *p_bl = NULL; | |
2969 | |
2970 #if defined (TI_PS_FF_RTD) AND defined (REL99) | |
2971 UBYTE i,j; | |
2972 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */ | |
2973 | |
2974 | |
2975 /* Step 1: Check if we received right BA_IND */ | |
2976 if( (rr_data->sc_data.ba_list_ded EQ TRUE) AND | |
2977 (p_mi->ba_ind NEQ rr_data->sc_data.ba_index ) ) | |
2978 { | |
2979 rr_data->sc_data.ba_list_ded = FALSE; | |
2980 rr_data->sc_data.ba_index = p_mi->ba_ind ; | |
2981 srv_clear_list (&rr_data->sc_data.cd.ncell_list); | |
2982 #ifdef TI_PS_FF_REL4 | |
2983 srv_clear_list (&rr_data->sc_data.cd.multiband_ncell_list); | |
2984 #else | |
2985 srv_clear_list (&rr_data->sc_data.five_ter_list); | |
2986 #endif | |
2987 att_clean_buf (IND_ALL_DEDI_SI); | |
2988 rr_data->sc_data.cd.sys_info_read &= ~ALL_DEDI_SYS_INFOS; | |
2989 TRACE_EVENT("Flushed off the entire dedicated mode BA-LIST as the BA-IND got changed"); | |
2990 } | |
2991 | |
2992 /* Step 2: Check report type. | |
2993 IMPORTANT ASSUMPTION: We will not process the other parameters if report type is Normal*/ | |
2994 if( p_mi->report_type NEQ ENHANCED_MEAS ) | |
2995 { | |
2996 /*check whether there are enhanced parameters and BA list, already. | |
2997 If present then it means that report type is changing from | |
2998 Enhanced to Normal*/ | |
2999 if ( p_cur->is_data_valid EQ TRUE ) | |
3000 { | |
3001 for_set_default_emr_data(p_cur); | |
3002 return TRUE; /*send enh para update to indicate change in report type*/ | |
3003 } | |
3004 else | |
3005 return send_enh_para; | |
3006 } | |
3007 | |
3008 /* Step 3: Check if we already have enh_para in current or temp | |
3009 and if there is change in parameters or continuation of reception*/ | |
3010 if(p_temp->is_data_valid EQ FALSE ) | |
3011 { | |
3012 /*This means we were not in the process of receiving. Check whether there | |
3013 is already information in current and if so, is there change in mp_change_mark*/ | |
3014 if( (p_cur->is_data_valid EQ TRUE ) AND | |
3015 (p_cur->mp_change_mark EQ p_mi->mp_cm ) ) | |
3016 { | |
3017 TRACE_EVENT("No change in Enhanced measurement parameters -ignore "); | |
3018 return send_enh_para; | |
3019 } | |
3020 /* This means there's either a change in MP change mark or receiving EMP for first time */ | |
3021 /* Decode rest of the parameters*/ | |
3022 p_temp->is_data_valid = TRUE; | |
3023 rr_data->sc_data.enh_para_status = ENH_PARA_INVALID_STATE; | |
3024 p_temp->enh_para.ncc_permitted = rr_data->sc_data.cd.ncc_permitted; | |
3025 } | |
3026 | |
3027 /*Note :If different values occur for the same parameter in different instances of a message, | |
3028 the instance with the highest index shall be used (sec.3.4.1.2.1, 4.18)*/ | |
3029 if ( (p_mi->mi_idx > rr_data->sc_data.prev_highest_index ) OR | |
3030 (rr_data->sc_data.prev_highest_index EQ NOT_PRESENT_8BIT) ) | |
3031 { | |
3032 p_temp->enh_para.rep_rate = p_mi->rep_rate; | |
3033 p_temp->enh_para.inv_bsic_enabled = p_mi->inv_bsic_rep; | |
3034 p_temp->mp_change_mark = p_mi->mp_cm; | |
3035 p_temp->msg_count = p_mi->mi_c; | |
3036 p_temp->rep_type = p_mi->report_type; | |
3037 if (p_mi->v_emp EQ TRUE ) /* This is updation of parameters other than BSIC list*/ | |
3038 { | |
3039 dat_update_emr_rep_para(&p_mi->emp,&p_temp->enh_para); | |
3040 } | |
3041 rr_data->sc_data.prev_highest_index = p_mi->mi_idx; | |
3042 } | |
3043 | |
3044 #if defined (TI_PS_FF_RTD) AND defined (REL99) | |
3045 if(p_mi->v_rtdd) | |
3046 dat_update_rtd_data(p_mi,p_temp); | |
3047 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */ | |
3048 | |
3049 | |
3050 /*Get relevant parameters to pass to BSIC and report priority list handler*/ | |
3051 if(p_mi->v_gprs_rep_prio EQ TRUE) | |
3052 p_rep = &p_mi->gprs_rep_prio; | |
3053 | |
3054 if( p_mi->v_gprs_bsic EQ TRUE) | |
3055 p_bl = &p_mi->gprs_bsic; | |
3056 | |
3057 if (for_dat_process_common_emr_data(p_rep,p_bl,p_mi->mi_idx, | |
3058 rr_data->sc_data.ba_list_ded) ) | |
3059 { | |
3060 rr_data->sc_data.enh_para_status = ENH_PARA_DEDICATED; | |
3061 | |
3062 if ( rr_data->sc_data.ba_list_ded EQ TRUE) | |
3063 send_enh_para = TRUE; | |
3064 } | |
3065 | |
3066 #if defined (TI_PS_FF_RTD) AND defined (REL99) | |
3067 if(p_mi->v_rtdd) | |
3068 { | |
3069 /* reset the temporary storage to RTD value not available */ | |
3070 for(j = 0;j < MAX_NR_OF_NCELL; j++ ) | |
3071 { | |
3072 p_temp->enh_para.enh_cell_list[j].v_rtd = FALSE; | |
3073 for(i = 0;i < MAX_NUM_OF_RTD_VALUES; i++) | |
3074 p_temp->enh_para.enh_cell_list[j].rtd[i]= RTD_NOT_AVAILABLE; | |
3075 }/*for*/ | |
3076 }/*if*/ | |
3077 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */ | |
3078 | |
3079 return send_enh_para; | |
3080 } | |
3081 #endif | |
3082 | |
3083 #endif |