comparison g23m-gsm/rr/rr_dats.c @ 0:75a11d740a02

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