comparison src/g23m-gsm/rr/rr_dats.c @ 104:27a4235405c6

src/g23m-gsm: import from LoCosto source
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 04 Oct 2016 18:24:05 +0000
parents
children
comparison
equal deleted inserted replaced
103:76d139c7a25e 104:27a4235405c6
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