comparison src/g23m-gsm/dl/dl_state.c @ 1:fa8dc04885d8

src/g23m-*: import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:25:50 +0000
parents
children
comparison
equal deleted inserted replaced
0:4e78acac3d88 1:fa8dc04885d8
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GSM-PS
4 | Modul : DL_STATE
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 state machine of the component DL
18 | (replaces the old channel dependent implementation)
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef DL_STATE_C
23 #define DL_STATE_C
24
25 #define ENTITY_DL
26 #define NEW_REJ_ACK /* Acknowledgement by valid reject frame
27 * in accordance with 3GPP 04.06, 5.5.3.1
28 * "On receipt of a valid I frame or supervisory frame"
29 */
30
31 /*==== INCLUDES ===================================================*/
32
33 #include "typedefs.h"
34 #include <string.h>
35 #include "vsi.h"
36 #include "pconst.cdg"
37 #include "custom.h"
38 #include "gsm.h"
39 #include "mon_dl.h"
40 #include "prim.h"
41 #include "pei.h"
42 #include "tok.h"
43 #include "ccdapi.h"
44 #include "dl.h"
45 #include "dl_em.h"
46 #include "dl_trc.h"
47
48 /*==== TYPEDEFS ===================================================*/
49 typedef struct
50 {
51 UBYTE channel;
52 UBYTE sapi;
53 UBYTE state;
54 UBYTE T200_Stop;
55 UBYTE T200_Start;
56 UBYTE pf_bit_flag;
57 UBYTE dl_data_ind;
58 UBYTE mdl_error_ind;
59 T_CCH* pcch;
60 } T_CCH_INTERN;
61 #define T_CCH_INTERN_INIT {0,0,0,0,0,0,0}
62
63 /*==== EXPORT =====================================================*/
64 /*==== PRIVAT =====================================================*/
65 static int frame_validation (UBYTE channel_type, UBYTE* frame);
66
67 static int downlink_idle (T_CCH_INTERN* pcch_i, UBYTE *frame);
68 static int downlink_contention_resolution (T_CCH_INTERN* pcch_i, UBYTE *frame);
69 static int downlink_mfe (T_CCH_INTERN* pcch_i, UBYTE *frame);
70 static int downlink_timer_recovery (T_CCH_INTERN* pcch_i, UBYTE *frame);
71 static int downlink_awaiting_release (T_CCH_INTERN* pcch_i, UBYTE *frame);
72
73 static void downlink_mfe_information (T_CCH_INTERN* pcch_i, UBYTE *frame);
74 static void downlink_mfe_supervisory (T_CCH_INTERN* pcch_i, UBYTE *frame);
75 static void downlink_mfe_sabm (T_CCH_INTERN* pcch_i, UBYTE *frame);
76 static void downlink_mfe_dm (T_CCH_INTERN* pcch_i, UBYTE *frame);
77 static void downlink_mfe_tr_unnumbered (T_CCH_INTERN* pcch_i, UBYTE *frame, UBYTE state);
78 static void downlink_i_frame (T_CCH_INTERN* pcch_i, UBYTE *frame);
79 static void downlink_tr_supervisory (T_CCH_INTERN* pcch_i, UBYTE *frame);
80 static void downlink_tr_information (T_CCH_INTERN* pcch_i, UBYTE *frame);
81
82 static void invoke_retransmission (T_CCH_INTERN* pcch_i, UBYTE frame_nr);
83 static void enquiry_response (T_CCH_INTERN* pcch_i, UBYTE *frame);
84 static void mdl_error_ind (UBYTE cause, UBYTE channel_type, UBYTE sapi);
85 static void nr_error_recovery (T_CCH_INTERN* pcch_i, UBYTE *frame);
86 static void concatenate (UBYTE ch_type, UBYTE sapi, UBYTE *frame);
87 static void free_sending_buffer (UBYTE ch_type, UBYTE sapi);
88
89 static void repeat_sabm (UBYTE channel, UBYTE sapi);
90 static void delayed_release_ind(UBYTE channel);
91
92 static int uplink_idle (UBYTE channel, UBYTE sapi);
93 static int uplink_awaiting_establishment (UBYTE channel, UBYTE sapi, UBYTE no_signalling_mode);
94 static int uplink_mfe (UBYTE channel, UBYTE sapi, UBYTE no_signalling_mode);
95 static int uplink_timer_recovery (UBYTE channel, UBYTE sapi, UBYTE no_signalling_mode);
96
97 static void T200_expiry (UBYTE channel, UBYTE sapi);
98
99 /*==== VARIABLES ==================================================*/
100
101 /*Removed the const from the definition,rework for issue 25370*/
102 static UBYTE l2_empty_frame [25] = {
103 0x00, 0x00, /* the first two dummy bytes only for SACCH L1 header! */
104 /* here begins the normal empty frame (SDCCH, FACCH) */
105 0x01, /* address field: SAPI 0 */
106 0x03, /* control field: UI frame */
107 0x01, /* length field: length = 0 */
108 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
109 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
110 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
111 0x2b, 0x2b, 0x2b, 0x2b, 0x2b };
112 #if 0
113 static UBYTE l2_invalid_frame [25] = {
114 0x00, 0x00, /* the first two dummy bytes only for SACCH L1 header! */
115 /* here begins the normal empty frame (SDCCH, FACCH) */
116 0x1D, /* address field: SAPI 7 (unallocated SAPI; no action shall be taken on such frames) */
117 0x03, /* control field: UI frame */
118 0x01, /* length field: length = 0 */
119 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
120 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
121 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
122 0x2b, 0x2b, 0x2b, 0x2b, 0x2b };
123 static UBYTE l2_invalid_frame_0 [25] = {
124 0x00, 0x00, /* the first two dummy bytes only for SACCH L1 header! */
125 /* here begins the normal empty frame (SDCCH, FACCH) */
126 0x00, /* address field: SAPI 0 */
127 0x00, /* control field: UI frame */
128 0x00, /* length field: length = 0 */
129 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x00 };
133 #endif /* 0|1 */
134 static T_CCH_INTERN cch_i;
135
136 #if defined(CHECK_PCCHI)
137 #define CHECK_PCCH_I() if (check_pcch_i(pcch_i, __LINE__)()return;
138 #define CHECK_PCCH_Ir() if (check_pcch_i(pcch_i, __LINE__)()return -1;
139 #else
140 #define CHECK_PCCH_I()
141 #define CHECK_PCCH_Ir()
142 #endif /* CHECK_PCCHI */
143
144 /*==== FUNCTIONS ==================================================*/
145 int dl_downlink (UBYTE error_flag, UBYTE channel_type, UBYTE* frame, ULONG fn)
146 {
147 UBYTE channel_state = STATE_INVALID;
148 UBYTE channel = NOT_PRESENT_8BIT;
149 UBYTE frame_sapi = PS_SAPI_0; /* to calm lint, will be new set for valid frames */
150 static UBYTE invalid = 0;
151 int ret = -2;
152 int cause;
153 int l2_offset;
154
155 GET_INSTANCE_DATA;
156
157 TRACE_EVENT_WIN_P1 ("downlink(): dcch0_ch_type:%s",
158 CH_TYPE_NAME[dl_data->dcch0_ch_type]);
159 TRACE_EVENT_WIN_P6 ("DL: DCCH0=%s,%s vr=%u vs=%u va=%u T200=%u",
160 CH_TYPE_NAME[dl_data->cch[C_DCCH0].ch_type],
161 STATE_DCCH0_NAME[dl_data->state[C_DCCH0]],
162 dl_data->cch[C_DCCH0].vr, dl_data->cch[C_DCCH0].vs, dl_data->cch[C_DCCH0].va,
163 dl_data->cch[C_DCCH0].T200_counter);
164 TRACE_EVENT_WIN_P6 ("DL: DCCH3=%s,%s vr=%u vs=%u va=%u T200=%u",
165 CH_TYPE_NAME[dl_data->cch[C_DCCH3].ch_type],
166 STATE_DCCH3_NAME[dl_data->state[C_DCCH3]],
167 dl_data->cch[C_DCCH3].vr, dl_data->cch[C_DCCH3].vs, dl_data->cch[C_DCCH3].va,
168 dl_data->cch[C_DCCH3].T200_counter);
169
170 if (channel_type EQ L2_CHANNEL_SACCH)
171 {
172 l2_offset = 2; /* with layer 1 header */
173 }
174 else
175 {
176 l2_offset = 0; /* without layer 1 header */
177 }
178
179 #define RR_SHORT_PD_HANDLING
180 #if defined(RR_SHORT_PD_HANDLING)
181 /* Handling of unacknowledged UI frames with format type Bter */
182 #if defined(RR_SHORT_PD_DETECT_KNOWN_MSG_ONLY) /* detection of known messages only */
183 cause = 0;
184 switch (frame[l2_offset])
185 {
186 case RR_SHORT_PD_SI10:
187 case RR_SHORT_PD_MEAS_INFO:
188 if (channel_type EQ L2_CHANNEL_SACCH)
189 cause = 1;
190 break;
191 case RR_SHORT_PD_NOTI_FACCH:
192 if ((channel_type EQ L2_CHANNEL_FACCH_F) OR
193 (channel_type EQ L2_CHANNEL_FACCH_H))
194 cause = 1;
195 break;
196 case RR_SHORT_PD_UPLINK_FREE:
197 cause = 1;
198 break;
199 default:
200 break;
201 }
202 if (cause)
203 {
204 drr_dl_short_unitdata_ind (channel_type, error_flag, frame,
205 &frame[l2_offset],
206 (channel_type EQ L2_CHANNEL_SACCH) ? DL_N201_SACCH_Bter : DL_N201_DCCH_Bter, fn);
207 return 0;
208 }
209 #else /* detection of all possible messages with short L2 header and format Bter */
210 TRACE_EVENT_WIN_P4 ("detection of format Bter: %02x&%02x=%02x ?= %02x",
211 frame[l2_offset], BTER_FORMAT_MASK, GET_BTER_FORMAT (&frame[l2_offset]), SHORT_L2_HEADER_TYPE_1);
212 if ((GET_BTER_FORMAT (&frame[l2_offset]) EQ SHORT_L2_HEADER_TYPE_1))
213 {
214 drr_dl_short_unitdata_ind (channel_type, error_flag, frame,
215 &frame[l2_offset],
216 (UBYTE)((channel_type EQ L2_CHANNEL_SACCH) ? DL_N201_SACCH_Bter : DL_N201_DCCH_Bter), fn);
217 return 0;
218 }
219 #endif /* kind of Bter detection */
220 #endif /* RR_SHORT_PD_HANDLING */
221
222 /* check frame */
223
224 if (error_flag EQ VALID_BLOCK)
225 {
226 frame_sapi = GET_SAPI (frame+l2_offset);
227 if ((frame_sapi NEQ PS_SAPI_0) AND (frame_sapi NEQ PS_SAPI_3))
228 {
229 TRACE_EVENT_WIN_P1 ("downlink() returns -1 (wrong SAPI=%u)", frame_sapi);
230 return -1;
231 }
232
233 cause = frame_validation (channel_type, frame+l2_offset);
234 if (cause >= 0)
235 {
236 TRACE_FUNCTION ("frame validation failed!");
237 if (invalid EQ 0)
238 {
239 TRACE_ERROR ("invalid frame");
240 invalid = 1; /* only one message per succession */
241 }
242 mdl_error_ind ((UBYTE)cause, channel_type, frame_sapi);
243 return 0;/* ETSI GSM 04.06 Annex G.2 - G.4 */
244 }
245 else
246 invalid = 0;
247
248 #if defined(DL_2TO1) || defined(_SIMULATION_)
249 /* Handling of unacknowledged UI frames on SACCH with SAPI=0 (not format type Bter) */
250 if ((channel_type EQ L2_CHANNEL_SACCH) AND
251 (frame_sapi EQ PS_SAPI_0) AND
252 (GET_FORMAT_TYPE(frame+l2_offset) EQ U_FORMAT) AND
253 (GET_U_TYPE(frame+l2_offset) EQ UI_FRAME) )
254 {
255 drr_dl_unitdata_ind (error_flag, frame, frame+l2_offset+3,
256 (UBYTE)(GET_LENGTH_INDICATOR (frame+l2_offset)), fn);
257 return 0;
258 }
259 #endif /* DL_2TO1 || _SIMULATION_ */
260 }
261 #if defined(DL_2TO1)
262 else if (channel_type EQ L2_CHANNEL_SACCH)
263 { /*
264 * Indicate invalid SACCH frame for decrement of radio link timeout counter.
265 * The invalid frame possible contains invalid headers, use length 0.
266 */
267 drr_dl_unitdata_ind (error_flag, frame, frame+l2_offset+3, 0, fn);
268 }
269 #endif /* DL_2TO1 */
270
271 if (error_flag NEQ VALID_BLOCK)
272 {
273 TRACE_EVENT_WIN ("invalid frame->stop download handling");
274 return 0; /* no further handling */
275 }
276
277 memset (&cch_i, 0, sizeof (T_CCH_INTERN));
278 switch (channel_type)
279 {
280 case L2_CHANNEL_SDCCH:
281 if (frame_sapi EQ PS_SAPI_3)
282 {
283 channel = C_DCCH3;
284 break;
285 }
286 /*lint -fallthrough*/
287 case L2_CHANNEL_FACCH_F:
288 case L2_CHANNEL_FACCH_H:
289 if (frame_sapi EQ PS_SAPI_0)
290 channel = C_DCCH0;
291 break;
292 case L2_CHANNEL_SACCH:
293 if (frame_sapi EQ PS_SAPI_3)
294 { /* SACCH with SAPI=3 only supported with associated TCH (FACCH) */
295 if ((dl_data->cch[C_DCCH0].ch_type EQ L2_CHANNEL_FACCH_H) OR
296 (dl_data->cch[C_DCCH0].ch_type EQ L2_CHANNEL_FACCH_F))
297 channel = C_DCCH3;
298 }
299 else
300 {
301 TRACE_EVENT_WIN ("No handling of SACCH with SAPI=0 here!");
302 /*
303 * The SACCH with SAPI=0 is handled some lines before for DL_2TO1 and
304 * simulation. Handling of frames other than UI frames is not supported.
305 */
306 }
307 break;
308 default:
309 break;
310 }/* endswitch channel_type */
311
312 if (channel EQ NOT_PRESENT_8BIT)
313 {
314 TRACE_EVENT_WIN ("downlink() returns -3");
315 return -3;
316 }
317 else
318 {
319
320 #if defined(DELAYED_SABM)
321 /* ignore downlinked frames before delayed SABM was sent */
322 if ((channel EQ C_DCCH0) AND
323 (dl_data->dcch0_sabm_flag NEQ NOT_PRESENT_8BIT))
324 {
325 DL_OFFLINE_TRACE (TRACE_DL_EVENT, channel, channel_type, "DL:pend.SABM->ignore");
326 return 0;
327 }
328 #endif /* DELAYED_SABM */
329
330 cch_i.channel = channel;
331 cch_i.sapi = frame_sapi;
332 #if defined(_SIMULATION_)
333 if (channel_type EQ L2_CHANNEL_SACCH)
334 {
335 TRACE_EVENT_WIN_P1 ("SACCH: set SAPI=%u set during downlink", frame_sapi);
336 }
337 #endif /* _SIMULATION_ */
338
339 cch_i.state = channel_state = dl_data->state[channel];
340 cch_i.pcch = &dl_data->cch[channel];
341 /*
342 * The channel type pcch->ch_type is overwritten as input to the downlink
343 * sub functions. In case of DCCH0 this is temporary only and the channel
344 * type have to be re-assigned with the value of dl_data->dcch0_ch_type.
345 */
346 cch_i.pcch->ch_type = channel_type;
347 if (cch_i.pcch->vtx NEQ EMPTY_CMD)
348 { /* save bit for the case of unsolicited frames */
349 cch_i.pf_bit_flag = cch_i.pcch->f_bit;
350 }
351 TRACE_EVENT_WIN_P4 ("downlink() in:%s SAPI=%u st=%u vtx=%s",
352 CH_TYPE_NAME[channel_type], frame_sapi, channel_state,
353 VTX_NAME[cch_i.pcch->vtx]);
354 TRACE_EVENT_WIN_P9 ("vr=%u vs=%u va=%u rc=%u contres=%u reje=%u ackp=%u %c=%u",
355 cch_i.pcch->vr, cch_i.pcch->vs, cch_i.pcch->va, cch_i.pcch->rc,
356 cch_i.pcch->contention_resolution, cch_i.pcch->reject_exception,
357 cch_i.pcch->acknowledge_pending,
358 cch_i.pcch->time_flag ? 'T' : 't', cch_i.pcch->T200_counter);
359 }
360
361 switch (channel_state)
362 {
363 case STATE_DISABLED:
364 case STATE_IDLE_DL:
365 ret = downlink_idle (&cch_i, frame+l2_offset);
366 break;
367 case STATE_CONTENTION_RESOLUTION:
368 ret = downlink_contention_resolution (&cch_i, frame+l2_offset);
369 break;
370 case STATE_MULTIPLE_FRAME_ESTABLISHED:
371 ret = downlink_mfe (&cch_i, frame+l2_offset);
372 break;
373 case STATE_TIMER_RECOVERY:
374 ret = downlink_timer_recovery (&cch_i, frame+l2_offset);
375 break;
376 case STATE_AWAITING_RELEASE:
377 ret = downlink_awaiting_release (&cch_i, frame+l2_offset);
378 break;
379 }/* endswitch channel_state */
380 if (channel EQ C_DCCH0)
381 { /*
382 * Reconstruct the temporary overwritten pcch->ch_type with the value
383 * of dl_data->dcch0_ch_type.
384 */
385 cch_i.pcch->ch_type = dl_data->dcch0_ch_type;
386 }
387
388
389 TRACE_EVENT_WIN_P5 ("%s SAPI=%u vtx=%s (%s#%u)", CH_TYPE_NAME[cch_i.pcch->ch_type], cch_i.sapi,
390 VTX_NAME[cch_i.pcch->vtx],
391 __FILE10__, __LINE__);
392 if (ret NEQ 0)
393 {
394 TRACE_EVENT_WIN_P1 ("downlink() returns %d", ret);
395 return ret;
396 }
397
398 /* transfer states and flags to dl_data */
399 dl_data->cch[channel].f_bit_flag = dl_data->cch[channel].f_bit = cch_i.pf_bit_flag;
400 if (cch_i.T200_Start)
401 {
402 dl_data->cch[channel].T200_counter = T200_STOPPED;
403 dl_data->cch[channel].time_flag = TRUE;
404 }
405 else if (cch_i.T200_Stop)
406 {
407 dl_data->cch[channel].T200_counter = T200_STOPPED;
408 dl_data->cch[channel].time_flag = FALSE;
409 }
410
411 if (cch_i.dl_data_ind)
412 {
413 com_data_ind(channel_type, frame_sapi, fn);
414 }
415
416 if (channel_state NEQ cch_i.state)
417 {
418 set_channel_state (
419 (UBYTE)((frame_sapi EQ PS_SAPI_0) ? C_DCCH0 : C_DCCH3), cch_i.state);
420 }
421
422 if (cch_i.mdl_error_ind)
423 {
424 mdl_error_ind ( cch_i.mdl_error_ind, channel_type, frame_sapi);
425 }
426
427
428
429 TRACE_EVENT_WIN_P4 ("downlink() out:%s SAPI=%u st=%u vtx=%s",
430 CH_TYPE_NAME[channel_type], cch_i.sapi, cch_i.state,
431 VTX_NAME[cch_i.pcch->vtx]);
432 TRACE_EVENT_WIN_P9 ("vr=%u vs=%u va=%u rc=%u contres=%u reje=%u ackp=%u %c=%u",
433 cch_i.pcch->vr, cch_i.pcch->vs, cch_i.pcch->va, cch_i.pcch->rc,
434 cch_i.pcch->contention_resolution, cch_i.pcch->reject_exception,
435 cch_i.pcch->acknowledge_pending,
436 cch_i.pcch->time_flag ? 'T' : 't', cch_i.pcch->T200_counter);
437 TRACE_EVENT_WIN_P4 ("T200=%s %s %s %s",
438 cch_i.T200_Start ? "Start" : cch_i.T200_Stop ? "Stop" : "...",
439 cch_i.pf_bit_flag ? "P/F" : "",
440 cch_i.dl_data_ind ? "DATA_IND" : "", cch_i.mdl_error_ind ? "ERROR_IND" : "");
441 TRACE_EVENT_WIN_P1 ("downlink() returns %d", ret);
442
443 return ret;
444 }/* endfunc downlink */
445
446 LOCAL int frame_validation (UBYTE channel_type, UBYTE* frame)
447 {
448 UBYTE frame_length;
449 BOOL frame_m_bit;
450 UBYTE N201;
451
452 if (!GET_EA (frame))
453 return FRAME_NOT_IMPLEMENTED; /* ETSI GSM 04.06 Annex G.2.3 */
454
455 if (!GET_EL (frame))
456 return FRAME_NOT_IMPLEMENTED; /* ETSI GSM 04.06 Annex G.4.1 */
457
458 frame_length = GET_LENGTH_INDICATOR (frame);
459 frame_m_bit = GET_M_BIT (frame);
460
461 /* get the maximal number of octets */
462 switch (channel_type)
463 {
464 case L2_CHANNEL_SDCCH:
465 N201 = N201_SDCCH;
466 break;
467 case L2_CHANNEL_SACCH:
468 N201 = N201_SACCH;
469 break;
470 default:/* CH_TYPE_FACCH_FR, L2_CHANNEL_FACCH_H */
471 N201 = N201_FACCH;
472 break;
473 }
474
475 switch (GET_FORMAT_TYPE (frame))
476 {
477 case I_FORMAT: /* I format */
478 case I1_FORMAT:
479 if ((frame_length > N201) OR (frame_length EQ 0))
480 return I_FRAME_WITH_INCORRECT_LENGTH; /* ETSI GSM 04.06 Annex G.4.2 */
481 if ((frame_length < N201) AND (frame_m_bit EQ 1))
482 return I_FRAME_WITH_INCORRECT_USE_OF_M_BIT; /* ETSI GSM 04.06 Annex G.4.2 */
483 break;
484 case S_FORMAT: /* S format */
485 if (frame_length OR frame_m_bit)
486 return S_FRAME_WITH_INCORRECT_PARAMETERS; /* ETSI GSM 04.06 Annex G.4.3 */
487 if ((frame[1] & 0x0f) EQ 0x0d)
488 return FRAME_NOT_IMPLEMENTED; /* ETSI GSM 04.06 Annex G.3.1 */
489 break;
490 case U_FORMAT: /* U format */
491 switch (GET_U_TYPE (frame))
492 {
493 case DM_FRAME:
494 case DISC_FRAME:
495 if (frame_length OR frame_m_bit)
496 return U_FRAME_WITH_INCORRECT_PARAMETERS; /* ETSI GSM 04.06 Annex G.4.4 */
497 break;
498 case UA_FRAME:
499 case SABM_FRAME:
500 case UI_FRAME:
501 if ((frame_length > N201) OR (frame_m_bit))
502 return U_FRAME_WITH_INCORRECT_PARAMETERS; /* ETSI GSM 04.06 Annex G.4.5 */
503 break;
504 default:
505 return FRAME_NOT_IMPLEMENTED; /* ETSI GSM 04.06 Annex G.3.2 */
506 /*break;*/
507 }/* endswitch U frame_type */
508 break;
509 }/* endswitch frame_format */
510
511 /*
512 * ETSI GSM 04.06 Annex G.2.1, G.2.2 will be check in the following functions
513 */
514
515 return -1; /* frame is valid */
516 }/* endfunc frame_validation */
517
518 static int downlink_idle( T_CCH_INTERN* pcch_i, UBYTE *frame)
519 {
520 /*
521 * According to 3GPP TS 04.05, 5.4.5 Idle state:
522 * While in the idle state:
523 * - the receipt of a DISC command shall result in the transmission of a
524 * DM response with the F bit set to the value of the received P bit;
525 * - the receipt of an I frame or supervisory frame with the P bit set to "1"
526 * shall result in the transmission of a DM response with the F bit set to
527 * "1" (as defined in subclause 5.2.2);
528 * - the content of any received I frame shall be discarded;
529 * - on receipt of an SABM command, the procedures defined in subclause 5.4.1
530 * shall be followed;
531 * - on receipt of UI commands, the procedures defined in subclause 5.3 shall
532 * be followed;
533 * - all other frame types shall be discarded.
534 */
535 T_CCH* pcch;
536
537 CHECK_PCCH_Ir();
538 pcch = pcch_i->pcch;
539
540 TRACE_FUNCTION ("downlink_idle()");
541
542 switch (GET_FORMAT_TYPE (frame))
543 {
544 case S_FORMAT: /* S frame */
545 if (GET_S_TYPE (frame) NEQ RR_CMD)
546 break;
547 /*lint -fallthrough*/
548 case I_FORMAT: /* I frame */
549 case I1_FORMAT:
550 if (GET_P_BIT (frame))
551 {
552 pcch->vtx = DM_CMD;
553 pcch_i->pf_bit_flag = TRUE;
554 }
555 break;
556 case U_FORMAT: /* U frame */
557 if (GET_CR (frame))
558 { /* command */
559 switch (GET_U_TYPE (frame))
560 {
561 case SABM_FRAME:
562 if (!GET_LENGTH_INDICATOR (frame) AND pcch_i->sapi EQ PS_SAPI_3)
563 { /*
564 * Mobile Terminated Establishment, but only for SAPI=3!
565 *
566 * According to 3GPP TS 04.06, 5.4.1 Establishment of multiple frame
567 * operation, 5.4.1.1 General, Note:
568 * For SAPI 0 the data link is always established by the MS.
569 */
570 com_restore_queue ( pcch_i->sapi, NULL);
571 pcch->vtx = UA_CMD;
572 pcch_i->pf_bit_flag = GET_P_BIT (frame);
573 pcch->va = 0;
574 pcch->vr = 0;
575 pcch->vs = 0;
576 pcch->rc = 0;
577 }
578 break;
579 case DISC_FRAME:
580 pcch->vtx = DM_CMD;
581 pcch_i->pf_bit_flag = GET_P_BIT (frame);
582 break;
583 case UI_FRAME:
584 /* drr_dl_unitdata_ind() was called in the main downlink function */
585 break;
586 default:
587 break;
588 }
589 }
590 break;
591 default:
592 break;
593 }
594
595 return 0;
596 }/* endfunc downlink_idle */
597
598 static int downlink_contention_resolution(T_CCH_INTERN* pcch_i, UBYTE *frame)
599 {
600 GET_INSTANCE_DATA;
601 UBYTE frame_type;
602 UBYTE frame_format;
603 UBYTE frame_cr;
604
605 UBYTE establish_cnf = FALSE;
606 UBYTE release_ind = FALSE;
607 UBYTE release_ind_cs = NOT_PRESENT_8BIT;
608
609 T_CCH* pcch;
610
611 CHECK_PCCH_Ir();
612 pcch = pcch_i->pcch;
613
614 TRACE_FUNCTION ("downlink_contention_resolution()");
615
616 frame_format = GET_FORMAT_TYPE (frame);
617 if (frame_format EQ U_FORMAT)
618 { /* U frame */
619 frame_cr = GET_CR (frame);
620 frame_type = GET_U_TYPE (frame);
621 if (frame_cr)
622 { /* command */
623 switch (frame_type)
624 {
625 case SABM_FRAME:
626 if (pcch_i->sapi EQ PS_SAPI_3)
627 { /* DCCH3 */
628 /*
629 * According to 3GPP TS 04.06, 5.4.6.1:
630 * SAPI = 3, Collision of unnumbered commands and responses.
631 * Collision situations (Identical transmitted and received commands)
632 * shall be resolved in the following way: If the transmitted and
633 * received unnumbered commands (SABM or DISC) are the same, the data
634 * link layer entities shall send the UA response at the earliest
635 * possible opportunity. The indicated state shall be entered after
636 * receiving the UA response. The data link layer entities shall each
637 * notify its respective layer 3 entity by means of the appropriate
638 * confirm primitive, i.e. DL-ESTABLISH-CONFIRM or DL-RELEASE-CONFIRM.
639 */
640 if (!GET_LENGTH_INDICATOR (frame))
641 {
642 com_clear_queue (PS_SAPI_3);
643 /* establish_cnf = TRUE; cnf will be sent at uplink opportunity */
644
645 pcch_i->pf_bit_flag = GET_P_BIT (frame);
646 pcch->vtx = UA_CMD;
647 pcch->va = 0;
648 pcch->vr = 0;
649 pcch->vs = 0;
650 pcch->rc = 0;
651 pcch_i->T200_Stop = TRUE;
652 }
653 else
654 {
655 /* no contention resolution procedure with SAPI=3! */
656 }
657 }
658 else
659 {/* DCCH0 */
660 /*
661 * According to 3GPP TS 04.06, 5.4.1.1 General:
662 * NOTE: SAPI=0 the data link is always established by the MS!
663 *
664 * According to 3GPP TS 04.06, 5.4.1.4 Contention resolution
665 * establishment procedure:
666 * All frames other than unnumbered frame formats received for the
667 * SAPI in use during the establishment procedures shall be ignored.
668 * The reception of unnumbered frames other than UA is treated as
669 * specified for the normal establishment case.
670 * NOTE 4: In fact, there are no foreseen cases in which the network
671 * will send SABM, DISC or DM, but for sake of completeness
672 * these occurrences are specified and must be treated.
673 */
674 establish_cnf = TRUE;/* Treated as normal establishment case */
675 pcch_i->pf_bit_flag = GET_P_BIT (frame);
676 pcch->vtx = UA_CMD;
677 pcch->va = 0;
678 pcch->vr = 0;
679 pcch->vs = 0;
680 pcch->rc = 0;
681 pcch_i->T200_Stop = TRUE;
682 }
683 break;
684
685 case DISC_FRAME:
686 {
687 release_ind = TRUE;
688
689 pcch_i->pf_bit_flag = GET_P_BIT (frame);
690 pcch->vtx = DM_CMD;
691 }
692 break;
693
694 default:
695 break;
696 }/* endswitch command frame_type */
697 }
698 else
699 { /* response */
700 switch (frame_type)
701 {
702 case DM_FRAME:
703 /*
704 * PATCH LE 14.09.99
705 * Ignore DM(F=0) frames
706 */
707 if (GET_P_BIT (frame))
708 {
709 release_ind = TRUE;
710 }
711 break;
712
713 case UA_FRAME:
714 if (pcch_i->sapi EQ PS_SAPI_0)
715 {
716 if (pcch->contention_resolution)
717 {
718 if (com_compare_L3_msg (dl_data->dcch0_queue.switch_buffer, frame))
719 {
720 establish_cnf = TRUE;
721 COM_FREE_QUEUE_BUFFER(&dl_data->dcch0_queue, INDEX_SWITCH_BUFFER);
722 }
723 else
724 {
725 release_ind = TRUE;
726 release_ind_cs = CAUSE_DL_INFO_FIELD_MISMATCH;
727 }
728 }
729 else
730 {
731 if (!GET_LENGTH_INDICATOR (frame))
732 {
733 establish_cnf = TRUE;
734 }
735 else
736 {
737 release_ind = TRUE;
738 }
739 }
740 }/* endif PS_SAPI_0 */
741 else if (pcch_i->sapi EQ PS_SAPI_3)
742 {
743 if (!GET_LENGTH_INDICATOR (frame) OR (pcch->ch_type EQ L2_CHANNEL_SACCH))
744 {
745 establish_cnf = TRUE;
746 }
747 else
748 {
749 release_ind = TRUE;
750 }
751
752 }/* endif PS_SAPI_3 */
753
754 if (establish_cnf AND (pcch_i->sapi EQ PS_SAPI_0))
755 {
756 dcch3_enable(pcch->ch_type);
757 }
758
759 break;/* endbreak UA_FRAME */
760
761 default:
762 break;
763 }/* endswitch response frame_type */
764 }/* endifelse command/response */
765
766 if (establish_cnf)
767 {
768 drr_dl_establish_cnf (pcch->ch_type, pcch_i->sapi);
769 pcch->va = 0;
770 pcch->vr = 0;
771 pcch->vs = 0;
772 pcch_i->T200_Stop = TRUE;
773 pcch_i->state = STATE_MULTIPLE_FRAME_ESTABLISHED;
774 }
775 else if (release_ind)
776 {
777 if (pcch_i->sapi EQ PS_SAPI_0)
778 {
779 if (pcch->contention_resolution)
780 {
781 pcch->contention_resolution = FALSE;
782 COM_FREE_QUEUE_BUFFER(&dl_data->dcch0_queue, INDEX_SWITCH_BUFFER);
783 }
784 }
785
786 drr_dl_release_ind (pcch->ch_type, pcch_i->sapi, release_ind_cs, FALSE);
787 pcch_i->T200_Stop = TRUE;
788 pcch_i->state = STATE_IDLE_DL;
789 }
790
791 }/* endif frame_format == 3 (only unnumbered frames) */
792
793 return 0;
794 }/* endfunc downlink_contention_resolution */
795
796 static int downlink_mfe(T_CCH_INTERN* pcch_i, UBYTE *frame)
797 {
798 TRACE_EVENT_WIN ("downlink_mfe()");
799
800 switch (GET_FORMAT_TYPE (frame))
801 {
802 case I_FORMAT:/* I frame */
803 case I1_FORMAT:
804 downlink_mfe_information (pcch_i, frame);
805 break;
806 case S_FORMAT: /* S frame */
807 downlink_mfe_supervisory (pcch_i, frame);
808 break;
809 case U_FORMAT: /* U frame */
810 downlink_mfe_tr_unnumbered (pcch_i, frame,
811 STATE_MULTIPLE_FRAME_ESTABLISHED);
812 break;
813 default:
814 TRACE_EVENT_WIN ("invalid/unknown frame");
815 break;
816 }
817
818 return 0;
819 }/* endfunc downlink_mfe */
820
821 static void downlink_mfe_supervisory (T_CCH_INTERN* pcch_i, UBYTE *frame)
822 {
823 UBYTE frame_cr;
824 UBYTE frame_pollbit;
825 UBYTE frame_nr;
826 UBYTE frame_type;
827 T_CCH* pcch;
828
829 CHECK_PCCH_I();
830 pcch = pcch_i->pcch;
831
832 TRACE_EVENT_WIN ("downlink_mfe_supervisory()");
833
834 frame_type = GET_S_TYPE (frame);
835
836 /*
837 * Ignore RNR frame without notification
838 * (ETSI GSM 04.06, section 6.
839 * "Special protocol operation on SAPI=0 and SAPI=3", page 53)
840 */
841 if (frame_type EQ RNR_FRAME)
842 return;
843
844 frame_cr = GET_CR (frame);
845 frame_pollbit = GET_P_BIT (frame);
846 frame_nr = GET_RECEIVE_NUMBER (frame);
847
848 /* in accordance with CCITT Q.921 figure B.7 (sheet 5 to 7 of 10) */
849 if (frame_pollbit)
850 {
851 if (frame_cr)
852 {
853 enquiry_response (pcch_i, frame);
854 }
855 else
856 {
857 mdl_error_ind (UNSOLICITED_SUPERVISORY_RESPONSE, pcch->ch_type, pcch_i->sapi);/* 3GPP TS 04.06, 5.4.2.2 */
858 }
859 }
860
861 if (com_check_nr (pcch->va, pcch->vs, frame_nr))
862 {
863 /*
864 * N(R) check is successfull
865 * in accordance with CCITT Q.921 figure B.7 (sheet 6 and 7 of 10)
866 */
867
868 switch (frame_type)
869 {
870 case RR_FRAME:
871 if (frame_nr EQ pcch->vs)
872 {
873 /* T200 handling under ETSI GSM 04.06 section 5.5.3.1 */
874 if (((8 + frame_nr - pcch->va ) & 7) > 0 /*frame_nr > pcch->va*/)
875 pcch_i->T200_Stop = TRUE;
876
877 pcch->va = frame_nr;
878
879 free_sending_buffer (pcch->ch_type, pcch_i->sapi);
880 }
881 else
882 {
883 if (frame_nr NEQ pcch->va)
884 {
885 pcch->va = frame_nr;
886 pcch_i->T200_Start = TRUE;
887 }
888 }
889 break;
890 case REJ_FRAME:
891 /*
892 * in accordance with ETSI GSM 04.06; chapter 5.5.4.1 i)
893 *
894 * clear existing peer receiver busy condition (not applicable in GSM)
895 */
896
897 /* reset timer T200 */
898 pcch_i->T200_Stop = TRUE;
899 /*
900 * If REJ command with P bit set to 1,
901 * transmit an appropiate supervisory response frame with F bit set to 1
902 */
903 if (frame_pollbit AND frame_cr)
904 enquiry_response (pcch_i, frame);
905 /* transmit the corresponding I frame asap */
906 invoke_retransmission (pcch_i, frame_nr);
907
908
909 /*
910 * set its send state variable V(S) and its acknowledge state
911 * variable V(A) to the value of the N(R) contained in the REJ frame
912 * control field
913 */
914 pcch->vs = pcch->va = frame_nr;
915
916 /*
917 * if it was an REJ response frame with the F bit set to 1, notify
918 * a protocol violation to layer 3 (cause=unsolicited supervisory frame)
919 *
920 * fulfilled at the beginning of this function!
921 */
922 break;
923 case RNR_FRAME:
924 /*
925 * Ignore frame without notification
926 * (ETSI GSM 04.06, section 6.
927 * "Special protocol operation on SAPI=0 and SAPI=3", page 53)
928 */
929 break;
930 default:
931 TRACE_EVENT_WIN ("invalid S frame"); /* GSM 04.06 Annex G.3.1 */
932 mdl_error_ind (FRAME_NOT_IMPLEMENTED, pcch->ch_type, pcch_i->sapi);
933 break;
934 }
935
936 }
937 else
938 {
939 nr_error_recovery (pcch_i, frame);
940 }
941 }/* endfunc downlink_mfe_supervisory */
942
943
944 static void downlink_mfe_sabm (T_CCH_INTERN* pcch_i, UBYTE *frame)
945 {
946 TRACE_EVENT_WIN ("downlink_mfe_sabm()");
947
948 if (!GET_LENGTH_INDICATOR (frame))
949 {
950 T_CCH* pcch;
951
952 CHECK_PCCH_I();
953 pcch = pcch_i->pcch;
954
955 if (pcch_i->sapi EQ PS_SAPI_0)
956 {
957 /* SACCH0: only unacknowledge mode available -> ignore SABM */
958 if (pcch->ch_type EQ L2_CHANNEL_SACCH)
959 return;
960 /*
961 * SDCCH0, FACCH: can not be a normal establishment procedure
962 * because for SAPI=0 the data link is always established by the MS.
963 * Therefore only the V state variables and any exception states
964 * will be reseted.
965 */
966 }
967 else if (pcch_i->sapi EQ PS_SAPI_3)
968 { /*
969 * SDCCH3, SACCH: normal establishment procedure,
970 * might be a re-establishment according to GSM 04.06, 5.4.1.2
971 */
972 com_clear_queue (PS_SAPI_3);
973 }
974
975 /* respond with an unnumbered acknowledgement */
976 pcch->vtx = UA_CMD;
977 /* with the F bit set to the same value as the P bit */
978 pcch_i->pf_bit_flag = GET_P_BIT (frame);
979 /* reset timer T200 */
980 pcch_i->T200_Stop = TRUE;
981 /* reset all state variables (internal sequence counter) */
982 pcch->va = 0;
983 pcch->vr = 0;
984 pcch->vs = 0;
985 /* reset the retransmission counter */
986 pcch->rc = 0;
987 /* clear all exception conditions */
988 pcch->reject_exception = FALSE;
989 pcch->acknowledge_pending = FALSE;
990 /* enter the multiple-frame-established state */
991 pcch_i->state = STATE_MULTIPLE_FRAME_ESTABLISHED;
992 }
993 else
994 {
995 /*
996 * frame_length NEQ 0 is only possible in contention resolution establishment
997 * initiated by mobile!
998 */
999 mdl_error_ind (U_FRAME_WITH_INCORRECT_PARAMETERS, pcch_i->pcch->ch_type, pcch_i->sapi);/* according to GSM 04.06, 5.4.2.1 */
1000 }
1001 }/* endfunc mfe_sabm */
1002
1003 static void downlink_mfe_dm (T_CCH_INTERN* pcch_i, UBYTE *frame)
1004 {
1005 T_CCH* pcch;
1006
1007 CHECK_PCCH_I();
1008 pcch = pcch_i->pcch;
1009
1010 if (!GET_P_BIT (frame))
1011 { /* release after unsolicited DM response during connection */
1012
1013 /* New! Called now by mdl_error_ind() from caller of this function
1014 * drr_dl_release_ind (dl_data, pcch->ch_type, pcch_i->sapi, NOT_PRESENT_8BIT);
1015 */
1016
1017 if ((pcch->ch_type EQ L2_CHANNEL_SDCCH) AND (pcch_i->sapi EQ PS_SAPI_3))
1018 {
1019 pcch_i->T200_Stop = TRUE;
1020 com_clear_queue (PS_SAPI_3);
1021 }
1022 }
1023 }/* endfunc mfe_dm */
1024
1025 static void downlink_mfe_tr_unnumbered (T_CCH_INTERN* pcch_i,
1026 UBYTE *frame, UBYTE state)
1027 {
1028 UBYTE frame_type;
1029 T_CCH* pcch;
1030
1031 TRACE_EVENT_WIN ("downlink_mfe_tr_unnumbered()");
1032
1033 CHECK_PCCH_I();
1034 pcch = pcch_i->pcch;
1035
1036 frame_type = GET_U_TYPE (frame);
1037 if (GET_CR (frame))
1038 { /* command */
1039 switch (frame_type)
1040 {
1041 case SABM_FRAME:
1042 downlink_mfe_sabm (pcch_i, frame);
1043 break;
1044 case UI_FRAME:
1045 /* drr_dl_unitdata_ind() was called in the main downlink function */
1046 break;
1047 case DISC_FRAME:
1048 pcch->vtx = UA_CMD;
1049 pcch_i->T200_Stop = TRUE;
1050 pcch_i->state = STATE_AWAITING_RELEASE;
1051 #if !defined(LATE_LEAVING_DEDICATED)
1052 com_leave_dedicated (pcch->ch_type);
1053 #endif /* LATE_LEAVING_DEDICATED */
1054 if (pcch_i->sapi EQ PS_SAPI_0)
1055 {
1056 dcch3_enable(pcch->ch_type);
1057 }
1058 break;
1059 default:
1060 /* GSM 04.06 Annex G.2.2, G.3.2 */
1061 TRACE_EVENT_WIN_P1 ("invalid command U frame (%02x)", frame_type);
1062 break;
1063 }
1064 }
1065 else
1066 { /* response */
1067 switch (frame_type)
1068 {
1069 case DM_FRAME:
1070 /* fulfill the actions required by 3GPP TS 4.06 section 5.4.2.2, table 7 */
1071 if (!GET_P_BIT(frame))
1072 {
1073 mdl_error_ind (UNSOLICITED_DM_RESPONSE_ABNORMAL_REL, pcch->ch_type, pcch_i->sapi);
1074 }
1075 else if (state EQ STATE_MULTIPLE_FRAME_ESTABLISHED)
1076 {
1077 mdl_error_ind (UNSOLICITED_DM_RESPONSE, pcch->ch_type, pcch_i->sapi);
1078 }
1079
1080 downlink_mfe_dm (pcch_i, frame);
1081 break;
1082 case UA_FRAME:
1083 mdl_error_ind (UNSOLICITED_UA_RESPONSE, pcch->ch_type, pcch_i->sapi);
1084 break;
1085 default:
1086 /* GSM 04.06 Annex G.2.2, G.3.2 */
1087 TRACE_EVENT_WIN_P1 ("invalid response U frame (%02x)", frame_type);
1088 break;
1089 }
1090 }
1091 }/* endfunc downlink_mfe_unnumbered */
1092
1093 static void downlink_i_frame (T_CCH_INTERN* pcch_i, UBYTE *frame)
1094 {
1095 /*
1096 * in accordance with CCITT Q.921 figure B.7 (sheet 8 of 10)
1097 * in accordance with CCITT Q.921 figure B.8 (sheet 7 of 9)
1098 * according to GSM 04.06 (same as CCITT Q.921!)
1099 */
1100
1101 UBYTE frame_pollbit;
1102 T_CCH* pcch;
1103
1104 CHECK_PCCH_I();
1105 pcch = pcch_i->pcch;
1106
1107 frame_pollbit = GET_P_BIT (frame);
1108
1109 if (GET_SEND_NUMBER (frame) EQ pcch->vr)
1110 {
1111 pcch->vr++;
1112 pcch->vr &= 7;
1113 pcch->reject_exception = FALSE;
1114 concatenate (pcch->ch_type, pcch_i->sapi, frame);
1115 if (!GET_M_BIT (frame))
1116 pcch_i->dl_data_ind = TRUE;/* send DL-DATA indication */
1117
1118 if (frame_pollbit)
1119 {
1120 pcch_i->pf_bit_flag = TRUE;
1121 pcch->vtx = RR_RSP;
1122 pcch->acknowledge_pending = FALSE;
1123 }
1124 else if (pcch->acknowledge_pending EQ FALSE)
1125 {
1126 #if defined(IFRAME_AS_RR)
1127 pcch->vtx = RR_CMD;
1128 #else
1129 pcch->vtx = RR_RSP;
1130 #endif /* IFRAME_AS_RR */
1131 }
1132 }/* endif ns == vr */
1133 else
1134 {
1135 if (pcch->reject_exception)
1136 {
1137 if (frame_pollbit)
1138 {
1139 pcch_i->pf_bit_flag = TRUE;
1140 /*pcch->vtx = RR_RSP; */
1141 pcch->vtx = REJ_CMD;
1142 pcch->acknowledge_pending = FALSE;
1143 }
1144 }
1145 else
1146 {
1147 pcch->reject_exception = TRUE;
1148 pcch_i->pf_bit_flag = frame_pollbit;
1149 pcch->vtx = REJ_CMD;
1150 pcch->acknowledge_pending = FALSE;
1151 }
1152 if (pcch->vtx EQ REJ_CMD)
1153 {
1154 TRACE_EVENT_WIN_P1 ("->REJ_CMD pf=%u", pcch_i->pf_bit_flag);
1155 }
1156 }/* endelse ns != vr */
1157 }/* endfunc downlink_i_frame */
1158
1159 static void downlink_mfe_information ( T_CCH_INTERN* pcch_i, UBYTE *frame)
1160 {
1161 UBYTE frame_nr;
1162 T_CCH* pcch;
1163
1164 CHECK_PCCH_I();
1165 pcch = pcch_i->pcch;
1166
1167 TRACE_EVENT_WIN ("downlink_mfe_information()");
1168
1169 if (!GET_CR (frame))
1170 { /* GSM 04.06 Annex G.2.2 */
1171 TRACE_EVENT_WIN ("invalid I response (C=0)");
1172 return;
1173 }
1174
1175 frame_nr = GET_RECEIVE_NUMBER (frame);
1176
1177 /* in accordance with CCITT Q.921 figure B.7 (sheet 8 of 10) */
1178 downlink_i_frame (pcch_i, frame);
1179
1180 /* in accordance with CCITT Q.921 figure B.7 (sheet 9 of 10) */
1181 if (com_check_nr (pcch->va, pcch->vs, frame_nr))
1182 { /* N(R) check is successfull */
1183 if (frame_nr EQ pcch->vs)
1184 {
1185
1186 /* T200 handling under ETSI GSM 04.06 section 5.5.3.1 */
1187 if (((8 + frame_nr - pcch->va ) & 7) > 0 /*frame_nr > pcch->va*/)
1188 pcch_i->T200_Stop = TRUE;
1189
1190 pcch->va = frame_nr;
1191 free_sending_buffer (pcch->ch_type, pcch_i->sapi);
1192 }
1193 else if (frame_nr NEQ pcch->va)
1194 {
1195 pcch->va = frame_nr;
1196 pcch_i->T200_Start = TRUE;
1197 }
1198 }
1199 else
1200 {
1201 nr_error_recovery (pcch_i, frame);
1202 }/* endifelse com_check_nr */
1203 }/* endfunc downlink_mfe_information */
1204
1205 static int downlink_timer_recovery(T_CCH_INTERN* pcch_i, UBYTE *frame)
1206 {
1207 TRACE_EVENT_WIN ("downlink_timer_recovery()");
1208
1209 switch (GET_FORMAT_TYPE (frame))
1210 {
1211 case I_FORMAT:
1212 case I1_FORMAT: /* I frame */
1213 downlink_tr_information (pcch_i, frame);
1214 break;
1215 case S_FORMAT: /* S frame */
1216 downlink_tr_supervisory (pcch_i, frame);
1217 break;
1218 case U_FORMAT: /* U frame */
1219 downlink_mfe_tr_unnumbered (pcch_i, frame, STATE_TIMER_RECOVERY);
1220 break;
1221 default:
1222 TRACE_EVENT_WIN ("invalid/unknown frame");
1223 break;
1224 }
1225
1226 return 0;
1227 }/* endfunc downlink_tr */
1228
1229 static void downlink_tr_supervisory (T_CCH_INTERN* pcch_i, UBYTE *frame)
1230 {
1231 UBYTE frame_cr;
1232 UBYTE frame_pollbit;
1233 UBYTE frame_nr;
1234 T_CCH* pcch;
1235
1236 CHECK_PCCH_I();
1237 pcch = pcch_i->pcch;
1238
1239 TRACE_EVENT_WIN ("downlink_tr_supervisory()");
1240
1241 frame_cr = GET_CR (frame);
1242 frame_pollbit = GET_P_BIT (frame);
1243 frame_nr = GET_RECEIVE_NUMBER (frame);
1244
1245 switch (GET_S_TYPE (frame))
1246 {
1247 case RR_FRAME:
1248 /*
1249 * in accordance with CCITT Q.921 figure B.8 (sheet 5 and 6 of 9) and
1250 * 3GPP 04.06, 5.5.3.1 "On receipt of a valid I frame or supervisory frame"
1251 * and 5.5.7 "Waiting acknowledgement".
1252 */
1253 if (frame_pollbit AND frame_cr)
1254 {
1255 enquiry_response (pcch_i, frame);
1256 }
1257
1258 if (com_check_nr (pcch->va, pcch->vs, frame_nr))
1259 {
1260 /* N(R) check is successfull */
1261
1262 TRACE_EVENT_WIN_P5 ("V(A)=%d =< N(R)=%d =< V(S)=%d check is successfull, pf=%u cr=%u",
1263 pcch->va, frame_nr, pcch->vs, frame_pollbit, frame_cr);
1264
1265 pcch->va = frame_nr;
1266
1267 if (frame_pollbit AND !frame_cr)
1268 { /*
1269 * 3GPP 04.06, 5.5.7:
1270 * The timer recovery state is only cleared if the DL receives a valid
1271 * supervisory frame response with the F bit set to 1.
1272 */
1273 pcch_i->T200_Stop = TRUE;
1274 pcch_i->state = STATE_MULTIPLE_FRAME_ESTABLISHED;
1275 /* acknowledgement according to GSM 04.06, 5.5.3.1*/
1276 free_sending_buffer (pcch->ch_type, pcch_i->sapi);
1277 }
1278 else
1279 {
1280 invoke_retransmission (pcch_i, frame_nr);
1281 }
1282 }
1283 else
1284 {
1285 nr_error_recovery (pcch_i, frame);
1286 }/* endifelse com_check_nr */
1287 break;
1288
1289 case REJ_FRAME:
1290 #if defined(NEW_REJ_ACK)
1291 /*
1292 * in accordance with
1293 * 3GPP 04.06, 5.5.3.1 "On receipt of a valid I frame or supervisory frame"
1294 */
1295 if (com_check_nr (pcch->va, pcch->vs, frame_nr))
1296 {
1297 /* N(R) check is successfull */
1298
1299 TRACE_EVENT_WIN_P5 ("V(A)=%d =< N(R)=%d =< V(S)=%d check is successfull, pf=%u cr=%u",
1300 pcch->va, frame_nr, pcch->vs, frame_pollbit, frame_cr);
1301
1302 /* acknowledgement according to GSM 04.06, 5.5.3.1*/
1303 free_sending_buffer (pcch->ch_type, pcch_i->sapi);
1304
1305 pcch->va = frame_nr;
1306 }
1307 #endif /* NEW_REJ_ACK */
1308
1309 /*
1310 * in accordance with GSM 04.06; chapter 5.5.4.1
1311 * Receipt of a valid REJ frame [ii) and iii)]
1312 *
1313 * clear existing peer receiver busy condition (not applicable in GSM)
1314 */
1315
1316 if (frame_pollbit AND !frame_cr)
1317 {/* REJ response with F bit set to 1 */
1318 /* clear the timer recovery state */
1319 pcch_i->state = STATE_MULTIPLE_FRAME_ESTABLISHED;
1320
1321 /* reset timer T200 */
1322 pcch_i->T200_Stop = TRUE;
1323
1324 #if defined(NEW_REJ_ACK)
1325 /* transmit the corresponding I frame asap */
1326 if (pcch->va NEQ frame_nr)
1327 {
1328 TRACE_EVENT_WIN_P2 ("REJ: V(A)=%d != N(R)=%d => invoke retransmission",
1329 pcch->va, frame_nr);
1330
1331 invoke_retransmission (pcch_i, frame_nr);
1332 }
1333 #else /* NEW_REJ_ACK */
1334 /* transmit the corresponding I frame asap */
1335 invoke_retransmission (pcch_i, frame_nr);
1336 #endif /* NEW_REJ_ACK */
1337
1338
1339 /*
1340 * set its send state variable V(S) and its acknowledge state
1341 * variable V(A) to the value of the N(R) contained in the REJ frame
1342 * control field
1343 */
1344 pcch->vs = pcch->va = frame_nr;
1345 }
1346 else
1347 {
1348 /*
1349 * set its its acknowledge state variable V(A) to the value
1350 * of the N(R) contained in the REJ frame control field
1351 */
1352 pcch->va = frame_nr;
1353
1354 /*
1355 * if REJ command with P bit set to 1,
1356 * transmit an appropiate supervisory response frame with F bit set to 1
1357 */
1358 if (frame_pollbit AND frame_cr)
1359 {
1360 enquiry_response (pcch_i, frame);
1361 }
1362 }
1363 break;
1364
1365 case RNR_FRAME:
1366 /*
1367 * ignore RNR frame without notification
1368 * (ETSI GSM 04.06, section 6.
1369 * "Special protocol operation on SAPI=0 and SAPI=3", page 53)
1370 */
1371 default:
1372 /* frame not implemented, */
1373 TRACE_EVENT_WIN ("invalid S frame"); /* GSM 04.06 Annex G.3.1 */
1374 return;
1375 }/* endswitch frame_type */
1376
1377
1378 }/* endfunc downlink_tr_supervisory */
1379
1380 static void downlink_tr_information ( T_CCH_INTERN* pcch_i, UBYTE *frame)
1381 {
1382 T_CCH* pcch;
1383 UBYTE frame_nr;
1384
1385 CHECK_PCCH_I();
1386 pcch = pcch_i->pcch;
1387
1388 TRACE_EVENT_WIN ("downlink_tr_information()");
1389
1390 if (!GET_CR (frame))
1391 { /* GSM 04.06 Annex G.2.2 */
1392 TRACE_EVENT_WIN ("invalid I response (C=0)");
1393 return;
1394 }
1395
1396 /* in accordance with CCITT Q.921 figure B.8 (sheet 7 of 9) */
1397 downlink_i_frame (pcch_i, frame);
1398
1399 /*
1400 * in accordance with CCITT Q.921 figure B.8 (sheet 8 of 9) and
1401 * 3GPP 04.06, 5.5.3.1 "On receipt of a valid I frame or supervisory frame"
1402 * and 5.5.7 "Waiting acknowledgement".
1403 */
1404 frame_nr = GET_RECEIVE_NUMBER (frame);
1405 if (com_check_nr (pcch->va, pcch->vs, frame_nr))
1406 pcch->va = frame_nr;/* N(R) check is successfull */
1407 else
1408 nr_error_recovery (pcch_i, frame);
1409 }/* endfunc downlink_tr_information */
1410
1411 static int downlink_awaiting_release(T_CCH_INTERN* pcch_i, UBYTE *frame)
1412 {
1413 T_CCH* pcch;
1414
1415 CHECK_PCCH_Ir();
1416 pcch = pcch_i->pcch;
1417
1418 TRACE_FUNCTION ("downlink_awaiting_release()");
1419
1420 if (GET_FORMAT_TYPE (frame) EQ U_FORMAT)
1421 { /* U frame */
1422 if (GET_CR (frame))
1423 { /* command */
1424 switch (GET_U_TYPE (frame))
1425 {
1426 case SABM_FRAME:
1427 if (pcch_i->sapi EQ PS_SAPI_0)
1428 {
1429 pcch->vtx = DM_CMD;
1430 pcch_i->pf_bit_flag = GET_P_BIT (frame);
1431 pcch_i->T200_Stop = TRUE;
1432 pcch_i->state = STATE_IDLE_DL;
1433 drr_dl_release_cnf (pcch->ch_type, PS_SAPI_0, FALSE);
1434 }
1435 break;
1436 case UI_FRAME:
1437 /* drr_dl_unitdata_ind() was called in the main downlink function */
1438 break;
1439 case DISC_FRAME:
1440 pcch->vtx = UA_CMD;
1441 pcch_i->T200_Stop = TRUE;
1442 #if !defined(LATE_LEAVING_DEDICATED)
1443 com_leave_dedicated (pcch->ch_type);
1444 #endif /* LATE_LEAVING_DEDICATED */
1445 break;
1446 default:
1447 /* GSM 04.06 Annex G.2.2, G.3.2 */
1448 TRACE_EVENT_WIN_P1 ("invalid command U frame (%02x)", GET_U_TYPE (frame));
1449 break;
1450 }
1451 }
1452 else
1453 { /* response */
1454 switch (GET_U_TYPE (frame))
1455 {
1456 case DM_FRAME:
1457 /*
1458 * PATCH LE 14.09.99
1459 * Ignore DM(F=0) frames
1460 */
1461 if (!GET_P_BIT (frame))
1462 break;
1463
1464 /* the same as UA_FRAME */
1465 /*lint -fallthrough*/
1466
1467 case UA_FRAME:
1468 pcch_i->T200_Stop = TRUE;
1469 #if defined(LATE_LEAVING_DEDICATED)
1470 com_leave_dedicated (pcch->ch_type);
1471 #endif /* LATE_LEAVING_DEDICATED */
1472 pcch_i->state = STATE_IDLE_DL;
1473 drr_dl_release_cnf (pcch->ch_type, pcch_i->sapi, TRUE);
1474 break;
1475
1476 default:
1477 TRACE_EVENT_WIN_P1 ("invalid response U frame (%02x)", GET_U_TYPE (frame));
1478 break;
1479 }
1480 }
1481 }
1482 return 0;
1483 }/* endfunc downlink_awaiting_release */
1484
1485 static void invoke_retransmission (T_CCH_INTERN* pcch_i, UBYTE frame_nr)
1486 {
1487 T_CCH* pcch;
1488
1489 CHECK_PCCH_I();
1490 pcch = pcch_i->pcch;
1491
1492 if (pcch->vs NEQ frame_nr)
1493 { /* decrement V(S) and recover queue for retransmission */
1494 TRACE_EVENT_WIN ("invoke retransmission");
1495
1496 pcch->vs--;
1497 pcch->vs &= 7;
1498 com_recover_queue (pcch_i->sapi);
1499 }
1500 }/* endfunc invoke_retransmission */
1501
1502
1503 static void enquiry_response (T_CCH_INTERN* pcch_i, UBYTE *frame)
1504 {
1505 T_CCH* pcch;
1506
1507 CHECK_PCCH_I();
1508 pcch = pcch_i->pcch;
1509
1510 TRACE_EVENT_WIN ("enquiry_response()");
1511 /*
1512 * in accordance with ETSI GSM 04.06, 5.5.3.2 Receiving supervisory
1513 * commands with the P bit set to "1" and ETSI GSM 04.06, 5.5.4.1 iii
1514 */
1515
1516 pcch_i->pf_bit_flag = TRUE;
1517 pcch->acknowledge_pending = FALSE;
1518 pcch->vtx = RR_RSP;
1519 }/* endfunc enquiry_response */
1520
1521 #if defined(_SIMULATION_)
1522 LOCAL const char * const _str_error_ind_cause[] =
1523 {
1524 "T200_EXPIRED_N200_PLUS_1_TIMES, \"T200 expired (N200 + 1 times)\"",
1525 "CS_REEST_REQ, \"re-establishment request\"",
1526 "UNSOLICITED_UA_RESPONSE, \"unsolicited UA response\"",
1527 "UNSOLICITED_DM_RESPONSE, \"unsolicited DM response\"",
1528 "UNSOLICITED_DM_RESPONSE_ABNORMAL_REL, \"unsolicited DM response, multiple frame established state\"",
1529 "UNSOLICITED_SUPERVISORY_RESPONSE, \"unsolicited supervisory response\"",
1530 "SEQUENCE_ERROR, \"sequence error\"",
1531 "U_FRAME_WITH_INCORRECT_PARAMETERS, \"U frame with incorrect parameters\"",
1532 "S_FRAME_WITH_INCORRECT_PARAMETERS, \"S frame with incorrect parameters\"",
1533 "I_FRAME_WITH_INCORRECT_USE_OF_M_BIT, \"I frame with incorrect use of M bit\"",
1534 "I_FRAME_WITH_INCORRECT_LENGTH, \"I frame with incorrect length\"",
1535 "FRAME_NOT_IMPLEMENTED, \"frame not implemented\"",
1536 };
1537 #endif /* _SIMULATION_ */
1538
1539 static void mdl_error_ind (UBYTE cause,
1540 UBYTE channel_type, UBYTE sapi)
1541 {
1542 TRACE_EVENT_WIN_P2 ("mdl_error_ind(%u %s)", cause, _str_error_ind_cause[cause]);
1543 switch(cause)
1544 {
1545 case T200_EXPIRED_N200_PLUS_1_TIMES:
1546 case UNSOLICITED_DM_RESPONSE:
1547 case UNSOLICITED_DM_RESPONSE_ABNORMAL_REL:
1548 case SEQUENCE_ERROR:
1549 drr_error_ind (channel_type, sapi);
1550 break;
1551 default:
1552 break;
1553 }
1554 }/* endfunc mdl_error_ind */
1555
1556 static void nr_error_recovery (T_CCH_INTERN* pcch_i, UBYTE *frame)
1557 {
1558
1559 T_CCH* pcch;
1560
1561 CHECK_PCCH_I();
1562 pcch = pcch_i->pcch;
1563
1564 TRACE_EVENT_WIN ("nr_error_recovery()");
1565 DL_OFFLINE_TRACE (TRACE_DL_EVENT, TRACE_CH_UNKNOWN, pcch->ch_type, "N(R) sequence error");
1566
1567 switch (pcch->ch_type)
1568 {
1569 case L2_CHANNEL_SDCCH:
1570 if (pcch_i->sapi EQ PS_SAPI_3)
1571 break;
1572 /*lint -fallthrough*/
1573 case L2_CHANNEL_SACCH:
1574 case L2_CHANNEL_FACCH_F:
1575 case L2_CHANNEL_FACCH_H:
1576 if ((GET_P_BIT (frame) EQ 1) AND !GET_M_BIT (frame))
1577 pcch_i->dl_data_ind = TRUE; /* indicate a complete message to layer 3 */
1578 else
1579 pcch_i->dl_data_ind = FALSE;/* no indication if P bit set to "0" or message is incomplete */
1580
1581 /*
1582 * GSM 04.06, 5.7.4 The data link shall remain in current state
1583 * until it´s release by layer 3 ???
1584 */
1585 pcch_i->mdl_error_ind = SEQUENCE_ERROR; /* send mdl error ind after sequence error */
1586
1587 DL_EM_CHANNEL_FAILURE;
1588
1589 break;
1590 }
1591 pcch->vtx = EMPTY_CMD;/* no answer after N(R) sequence error */
1592 }/* endfunc nr_error_recovery */
1593
1594
1595 static void concatenate (UBYTE ch_type, UBYTE sapi,UBYTE *frame)
1596 {
1597 GET_INSTANCE_DATA;
1598 switch (ch_type)
1599 {
1600 case L2_CHANNEL_SDCCH:
1601 if (sapi EQ PS_SAPI_0)
1602 com_concatenate (&dl_data->dcch0_in_msg, frame);
1603 else if (sapi EQ PS_SAPI_3)
1604 com_concatenate (&dl_data->dcch3_in_msg, frame);
1605 break;
1606 case L2_CHANNEL_SACCH:
1607 if (sapi EQ PS_SAPI_3)
1608 {
1609 com_concatenate (&dl_data->dcch3_in_msg, frame);
1610 }
1611 break;
1612 case L2_CHANNEL_FACCH_F:
1613 case L2_CHANNEL_FACCH_H:
1614 if (sapi EQ PS_SAPI_0)
1615 {
1616 com_concatenate (&dl_data->dcch0_in_msg, frame);
1617 }
1618 break;
1619 default:
1620 break;
1621 }
1622 }/* endfunc concatenate */
1623
1624 /*
1625 +--------------------------------------------------------------------+
1626 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
1627 | STATE : code ROUTINE : free_sending_buffer |
1628 +--------------------------------------------------------------------+
1629
1630 PURPOSE : After confirmation of an I frame the sending buffer is
1631 released if it was the last segment. This avoids
1632 resending of I frames after resumption.
1633
1634 */
1635 static void free_sending_buffer ( UBYTE ch_type, UBYTE sapi)
1636 {
1637 GET_INSTANCE_DATA;
1638 T_QUEUE *queue = NULL;
1639
1640 TRACE_EVENT_WIN_P2 ("free_sending_buffer():%s SAPI=%u", CH_TYPE_NAME[ch_type], sapi);
1641
1642 switch (ch_type)
1643 {
1644 case L2_CHANNEL_SDCCH:
1645 if (sapi EQ PS_SAPI_0)
1646 queue = &dl_data->dcch0_queue;
1647 else if (sapi EQ PS_SAPI_3)
1648 queue = &dl_data->dcch3_queue;
1649 break;
1650 case L2_CHANNEL_SACCH:
1651 if (sapi EQ PS_SAPI_3)
1652 queue = &dl_data->dcch3_queue;
1653 break;
1654 case L2_CHANNEL_FACCH_F:
1655 case L2_CHANNEL_FACCH_H:
1656 if (sapi EQ PS_SAPI_0)
1657 queue = &dl_data->dcch0_queue;
1658 break;
1659 default:
1660 break;
1661 }
1662
1663 if (queue)
1664 {
1665 if (queue->switch_buffer)
1666 {
1667 TRACE_EVENT_WIN_P3 ("CNF on %s SAPI=%u %s (switch_buffer)",
1668 CH_TYPE_NAME[queue->switch_buffer->ch_type],
1669 queue->switch_buffer->sapi,
1670 queue->switch_buffer->cnf ? "CNF required" : "");
1671
1672 com_l3trace (TRACE_UPLINK, queue->switch_buffer->ch_type, (UBYTE *)queue->switch_buffer);
1673 COM_FREE_QUEUE_BUFFER ( queue, INDEX_SWITCH_BUFFER);
1674 }
1675 else if (queue->sending_buffer)
1676 {
1677 TRACE_EVENT_WIN_P4 ("CNF on %s SAPI=%u %s (sending_buffer) act_length=%u",
1678 CH_TYPE_NAME[queue->sending_buffer->ch_type],
1679 queue->sending_buffer->sapi,
1680 queue->sending_buffer->cnf ? "CNF required" : "",
1681 queue->act_length);
1682
1683 if (queue->act_length EQ 0)
1684 { /* entire message has been sent */
1685 com_l3trace (TRACE_UPLINK, queue->sending_buffer->ch_type, (UBYTE *)queue->sending_buffer);
1686
1687 if (queue->sending_buffer->cnf)
1688 {
1689 drr_dl_data_cnf (sapi);
1690 }
1691 else
1692 {
1693 COM_FREE_QUEUE_BUFFER (queue, INDEX_SENDING_BUFFER);
1694 }
1695 }
1696 }
1697 else
1698 {
1699 TRACE_EVENT_WIN_P2 ("%s SAPI=%u: sending_buffer and switch_buffer=NULL !!!",
1700 CH_TYPE_NAME[ch_type], sapi);
1701 }
1702 }
1703 }/* endfunc concatenate */
1704
1705 static void T200_expiry ( UBYTE channel, UBYTE sapi)
1706 {
1707 GET_INSTANCE_DATA;
1708 UBYTE old_state;
1709 UBYTE new_state;
1710 T_CCH * pcch = &dl_data->cch[channel];
1711 UBYTE N200_counter;
1712
1713 TRACE_FUNCTION ("T200_expiry()");
1714
1715 switch (pcch->ch_type)
1716 {
1717 case L2_CHANNEL_SACCH:
1718 N200_counter = SACCH_N200;
1719 break;
1720 case L2_CHANNEL_SDCCH:
1721 N200_counter = SDCCH_N200;
1722 break;
1723 case L2_CHANNEL_FACCH_F:
1724 N200_counter = FACCH_N200_FR;
1725 break;
1726 case L2_CHANNEL_FACCH_H:
1727 N200_counter = FACCH_N200_HR;
1728 break;
1729 default:
1730 N200_counter = NOT_PRESENT_8BIT;
1731 break;
1732 }
1733
1734 new_state = old_state = dl_data->state[channel];
1735 switch (old_state)
1736 {
1737 case STATE_CONTENTION_RESOLUTION:
1738 repeat_sabm (channel, sapi);
1739 break;
1740
1741 case STATE_MULTIPLE_FRAME_ESTABLISHED:
1742 pcch->rc = 1;
1743 pcch->p_bit_flag= 1;
1744 pcch->time_flag = TRUE;
1745 new_state = STATE_TIMER_RECOVERY;
1746 break;
1747
1748 case STATE_TIMER_RECOVERY:
1749 if (N200_counter EQ NOT_PRESENT_8BIT)
1750 break; /* invalid channel */
1751
1752 if (pcch->rc >= N200_counter)
1753 { /* release connection due to T200 expired N200 plus 1 times */
1754
1755 TRACE_EVENT_WIN_P1 ("T200 expired, N200=%u", N200_counter);
1756
1757 /* New! Called now by mdl_error_ind().
1758 * drr_dl_release_ind (dl_data, pcch->ch_type, sapi, NOT_PRESENT_8BIT);
1759 */
1760 mdl_error_ind (T200_EXPIRED_N200_PLUS_1_TIMES, pcch->ch_type, sapi);
1761
1762 if (sapi EQ PS_SAPI_0)
1763 {
1764 dcch3_init_dl_data();
1765 pcch->T200_counter = 0;
1766 pcch->time_flag = FALSE;
1767 pcch->contention_resolution = FALSE;
1768 pcch->vtx = EMPTY_CMD;
1769 new_state = STATE_IDLE_DL;
1770 }
1771 }
1772 else
1773 {
1774 pcch->rc++;
1775 pcch->p_bit_flag = 1;
1776 pcch->time_flag = TRUE;
1777 }
1778 break;
1779
1780 case STATE_AWAITING_RELEASE:
1781 if (pcch->rc >= N200_ESTABLISHMENT)
1782 {
1783 TRACE_EVENT_WIN_P1 ("T200 expired, N200=%u", N200_ESTABLISHMENT);
1784 drr_dl_release_cnf (pcch->ch_type, sapi, TRUE);
1785 new_state = STATE_IDLE_DL;
1786
1787 }
1788 else
1789 {
1790 pcch->rc++;
1791 pcch->vtx = DISC_CMD;
1792 pcch->time_flag = TRUE;
1793 }
1794 break;
1795
1796 default:
1797 break;
1798 }/* endswitch old_state */
1799
1800 if (new_state NEQ old_state)
1801 {
1802 set_channel_state (channel, new_state);
1803 }
1804
1805 }/* endfunc T200_expiry */
1806
1807 /*
1808 +--------------------------------------------------------------------+
1809 | PROJECT : GSM-PS (6147) MODULE : state |
1810 | STATE : code ROUTINE : repeat_sabm |
1811 +--------------------------------------------------------------------+
1812
1813 PURPOSE : Repeat if possible the SABM command.
1814
1815 */
1816
1817 static void repeat_sabm (UBYTE channel, UBYTE sapi)
1818 {
1819 GET_INSTANCE_DATA;
1820 T_CCH* pcch = &dl_data->cch[channel];
1821
1822 TRACE_FUNCTION ("repeat_sabm()");
1823
1824 if (pcch->rc >= N200_ESTABLISHMENT)
1825 {
1826 if (sapi EQ PS_SAPI_0)
1827 pcch->contention_resolution = FALSE;
1828
1829 DL_OFFLINE_TRACE (TRACE_DL_EVENT, channel, pcch->ch_type, ">N200_EST");
1830 SYST_TRACE_P ((SYST, "DL: >N200 of SABM"));
1831 TRACE_ERROR ("DL: >N200 of SABM");
1832
1833 DL_EM_CHANNEL_ESTABLISHMENT_FAILED;
1834
1835 mdl_error_ind(T200_EXPIRED_N200_PLUS_1_TIMES, pcch->ch_type, sapi);
1836 set_channel_state (channel, STATE_IDLE_DL);
1837 /* New! Called now by mdl_error_ind().
1838 * drr_dl_release_ind (dl_data, pcch->ch_type, sapi, NOT_PRESENT_8BIT);
1839 */
1840 }
1841 else
1842 {
1843 pcch->rc++;
1844 pcch->vtx = SABM_CMD;
1845 pcch->time_flag = TRUE;
1846 TRACE_EVENT_P1 ("DL: T200 %u. repeat of SABM", pcch->rc);
1847 }
1848 }/* endfunc repeat_sabm */
1849
1850 GLOBAL void set_channel_state (UBYTE channel, UBYTE state)
1851 {
1852 GET_INSTANCE_DATA;
1853 if (dl_data->state[channel] NEQ state)
1854 {
1855 #ifdef TRACE_STATE
1856 vsi_o_state_ttrace ("STATE_%s:%s -> %s", PROCESS_NAME[channel],
1857 channel EQ C_DCCH3 ? STATE_DCCH3_NAME[dl_data->state[channel]]:
1858 STATE_DCCH0_NAME[dl_data->state[channel]],
1859 channel EQ C_DCCH3 ? STATE_DCCH3_NAME[state] :
1860 STATE_DCCH0_NAME[state]);
1861 #endif /* TRACE_STATE */
1862 dl_data->state[channel] = state;
1863 DL_OFFLINE_TRACE (TRACE_CHSTATE, channel, dl_data->cch[channel].ch_type, NULL);
1864 }
1865 }/* endfunc set_channel_state */
1866
1867 static void set_T200_counter (T_CCH* pcch, UBYTE sapi)
1868 {
1869 switch (pcch->ch_type)
1870 {
1871 case L2_CHANNEL_SACCH:
1872 pcch->T200_counter = sapi EQ PS_SAPI_0 ?
1873 T200_SDCCH_SAPI_0_CNT : T200_SACCH_SAPI_3_CNT;
1874 break;
1875 default:
1876 TRACE_EVENT_WIN_P1 ("set_T200_counter: unknown ch_type=%u -> use SDCCH", pcch->ch_type);
1877 /*lint -fallthrough*/
1878 case L2_CHANNEL_SDCCH:
1879 pcch->T200_counter = sapi EQ PS_SAPI_0 ?
1880 T200_SDCCH_SAPI_0_CNT : T200_SDCCH_SAPI_3_CNT;
1881 break;
1882 case L2_CHANNEL_FACCH_F:
1883 pcch->T200_counter = T200_FACCH_SAPI_0_CNT_FR;
1884 break;
1885 case L2_CHANNEL_FACCH_H:
1886 pcch->T200_counter = T200_FACCH_SAPI_0_CNT_HR;
1887 break;
1888 }/* endswitch ch_type */
1889 pcch->time_flag = FALSE;
1890
1891 TRACE_EVENT_WIN_P3 ("set_T200_counter: %s, SAPI=%u: %u",
1892 CH_TYPE_NAME[pcch->ch_type], sapi, pcch->T200_counter);
1893 }/* endfunc set_T200_counter */
1894
1895 #if defined(DELAYED_RELEASE_IND)
1896 static void delayed_release_ind( UBYTE channel)
1897 {
1898 GET_INSTANCE_DATA;
1899 /* delay DL RELEASE IND to RR for FTA 25.2.3 *********** */
1900 if (dl_data->release_ind_ch_type NEQ NOT_PRESENT_8BIT)
1901 {
1902 if (dl_data->release_ind_delay > 0)
1903 dl_data->release_ind_delay--;
1904
1905 if (dl_data->release_ind_delay EQ 0)
1906 {
1907 DL_OFFLINE_TRACE (TRACE_DL_EVENT, TRACE_CH_UNKNOWN,
1908 dl_data->release_ind_ch_type, "UL:send delayed REL IND");
1909 drr_dl_release_ind (dl_data->release_ind_ch_type,
1910 dl_data->release_ind_sapi, NOT_PRESENT_8BIT, TRUE);
1911 }
1912 else
1913 {
1914 DL_OFFLINE_TRACE (TRACE_DL_EVENT, TRACE_CH_UNKNOWN,
1915 dl_data->release_ind_ch_type, "UL:pend. delay REL IND");
1916 }
1917
1918 }
1919 }
1920
1921 #endif /* DELAYED_RELEASE_IND */
1922
1923 T_RADIO_FRAME* dl_uplink(UBYTE channel, UBYTE sapi,
1924 UBYTE no_signalling_mode, BOOL recursive)
1925 {
1926 GET_INSTANCE_DATA;
1927 T_CCH* pcch = &dl_data->cch[channel];
1928 T_RADIO_FRAME* p_l2_frame = &dl_data->l2_frame;
1929 int send = UPLINK_NULL;
1930
1931 TRACE_EVENT_WIN_P3 ("uplink(): %s dcch0_ch_type:%s dedi=%u",
1932 CH_TYPE_NAME[pcch->ch_type], CH_TYPE_NAME[dl_data->dcch0_ch_type], dl_data->RR_dedicated);
1933 TRACE_EVENT_WIN_P6 ("UL: DCCH0=%s,%s vr=%u vs=%u va=%u T200=%u",
1934 CH_TYPE_NAME[dl_data->cch[C_DCCH0].ch_type],
1935 STATE_DCCH0_NAME[dl_data->state[C_DCCH0]],
1936 dl_data->cch[C_DCCH0].vr, dl_data->cch[C_DCCH0].vs, dl_data->cch[C_DCCH0].va,
1937 dl_data->cch[C_DCCH0].T200_counter);
1938 TRACE_EVENT_WIN_P6 ("UL: DCCH3=%s,%s vr=%u vs=%u va=%u T200=%u",
1939 CH_TYPE_NAME[dl_data->cch[C_DCCH3].ch_type],
1940 STATE_DCCH3_NAME[dl_data->state[C_DCCH3]],
1941 dl_data->cch[C_DCCH3].vr, dl_data->cch[C_DCCH3].vs, dl_data->cch[C_DCCH3].va,
1942 dl_data->cch[C_DCCH3].T200_counter);
1943
1944
1945 /* check SACCH SAPI and channel */
1946 if (pcch->ch_type EQ L2_CHANNEL_SACCH)
1947 {
1948 if (!dl_data->RR_dedicated)
1949 {
1950 sapi = PS_SAPI_0;
1951 send = UPLINK_EMPTY;
1952 TRACE_EVENT_WIN ("SACCH without dedicated channel: change SAPI->0, UPLINK_EMPTY");
1953 }
1954 else if (dl_data->state[C_DCCH0] EQ STATE_SUSPENDED)
1955 {
1956 sapi = PS_SAPI_0;
1957 send = UPLINK_REPORT;
1958 TRACE_EVENT_WIN ("SACCH during suspended dedicated channel: change SAPI->0, UPLINK_REPORT");
1959 }
1960 else if (sapi EQ PS_SAPI_3)
1961 {
1962 if ((dl_data->state[C_DCCH0] <= STATE_IDLE_DL)
1963 OR
1964 (dl_data->dcch0_ch_type EQ L2_CHANNEL_SDCCH)
1965 OR
1966 ((dl_data->cch[C_DCCH3].vtx EQ EMPTY_CMD) AND
1967 (!com_queue_awaiting_transmission (PS_SAPI_3)) AND
1968 (dl_data->state[C_DCCH3] NEQ STATE_AWAITING_ESTABLISHMENT)
1969 ) )
1970 {
1971 sapi = PS_SAPI_0;
1972 TRACE_EVENT_WIN ("SACCH with SAPI=3 only together with FACCH and frame is awaiting tx: change SAPI->0");
1973 }
1974 else
1975 {
1976 channel = C_DCCH3;
1977 pcch = &dl_data->cch[channel];
1978 TRACE_EVENT_WIN ("SACCH with SAPI=3 together with FACCH: change channel->C_DCCH3");
1979 }
1980 }
1981 }
1982 else if ((dl_data->RR_dedicated) AND
1983 (dl_data->dcch0_ch_type NEQ pcch->ch_type))
1984 {
1985 TRACE_EVENT_WIN_P2 ("dcch0_ch_type (%s) NEQ %s -> unexpected,unsolicited,invalid channel => UPLINK_EMPTY",
1986 CH_TYPE_NAME[dl_data->dcch0_ch_type],
1987 CH_TYPE_NAME[dl_data->cch[C_DCCH0].ch_type]);
1988 send = UPLINK_EMPTY;
1989 }
1990
1991 /* decrease T200 counter ************************************ */
1992 if (channel EQ C_DCCH3)
1993 {
1994 if (dl_data->cch[C_DCCH3].T200_counter >= T200_ACTIVE)
1995 {
1996 dl_data->cch[C_DCCH3].T200_counter--;
1997 TRACE_EVENT_WIN_P2 ("T200(SAPI_0)=%u T200(SAPI_3)=%u*",
1998 dl_data->cch[C_DCCH0].T200_counter, dl_data->cch[C_DCCH3].T200_counter);
1999 /*DL_OFFLINE_TRACE (TRACE_DL_EVENT, channel, pcch->ch_type, "dec T200(SAPI_3)");*/
2000 }
2001 }
2002 else
2003 {
2004 if (pcch->ch_type NEQ L2_CHANNEL_SACCH) /* no T200 for SACCH with SAPI=0 */
2005 {
2006 if (dl_data->cch[C_DCCH0].T200_counter >= T200_ACTIVE)
2007 {
2008 dl_data->cch[C_DCCH0].T200_counter--;
2009 TRACE_EVENT_WIN_P2 ("T200(SAPI_0)=%u* T200(SAPI_3)=%u",
2010 dl_data->cch[C_DCCH0].T200_counter, dl_data->cch[C_DCCH3].T200_counter);
2011 /*DL_OFFLINE_TRACE (TRACE_DL_EVENT, channel, pcch->ch_type, "dec T200(SAPI_0)");*/
2012 }
2013 }
2014 }
2015
2016 /* check activity of DL ************************************* */
2017 if (dl_data->dl_active AND dl_data->state[channel] EQ STATE_MULTIPLE_FRAME_ESTABLISHED)
2018 {
2019 TRACE_EVENT_WIN_P1 ("uplink(): %s dl_active", PROCESS_NAME[channel]);
2020 DL_OFFLINE_TRACE (TRACE_DL_EVENT, channel, pcch->ch_type, "UL:&dl_active");
2021
2022 /* signalling only */
2023 send = UPLINK_EMPTY;
2024 }/* endif dl_active */
2025
2026 #if defined(DELAYED_SABM)
2027 /* delay uplink SABM to PL for FTA 26.6.6.1 and 25.2.3 *********** */
2028 if ((channel EQ C_DCCH0) AND (dl_data->dcch0_sabm_flag NEQ NOT_PRESENT_8BIT))
2029 {
2030 dcch0_delay_sabm (pcch);
2031 if (dl_data->dcch0_sabm_flag NEQ NOT_PRESENT_8BIT)
2032 send = UPLINK_EMPTY; /* send dummy only */
2033 }
2034 #endif /* DELAYED_SABM */
2035
2036
2037 #if defined(DELAYED_RELEASE_IND)
2038 delayed_release_ind (channel);
2039 #endif /* DELAYED_RELEASE_IND */
2040
2041 if ((send EQ UPLINK_NULL) OR (send EQ UPLINK_EMPTY))
2042 { /* After a L3 release at the last downlink DL should send a DISC */
2043 TRACE_EVENT_WIN_P6 ("uplink():%s %s SAPI=%u vtx=%s %s (#%u)",
2044 PROCESS_NAME[channel], CH_TYPE_NAME[pcch->ch_type], sapi,
2045 VTX_NAME[pcch->vtx], SEND_NAME[send], __LINE__);
2046 switch (channel)
2047 {
2048 case C_DCCH0:
2049 send = dcch0_check_disc (send);
2050 break;
2051 case C_DCCH3:
2052 send = dcch3_check_disc (send);
2053 break;
2054 default:
2055 break;
2056 }
2057 TRACE_EVENT_WIN_P6 ("uplink():%s %s SAPI=%u vtx=%s %s (#%u)",
2058 PROCESS_NAME[channel], CH_TYPE_NAME[pcch->ch_type], sapi,
2059 VTX_NAME[pcch->vtx], SEND_NAME[send], __LINE__);
2060 }
2061
2062 if (send EQ UPLINK_NULL)
2063 {
2064 TRACE_EVENT_WIN_P5 ("uplink():%s %s SAPI=%u vtx=%s %s",
2065 PROCESS_NAME[channel], CH_TYPE_NAME[pcch->ch_type], sapi,
2066 VTX_NAME[pcch->vtx], recursive ? "RECURSIVE" : "");
2067
2068 TRACE_EVENT_WIN_P8 ("UL: DCCH%u=%s,%s vr=%u vs=%u va=%u T200=%u (#%u)",
2069 sapi, CH_TYPE_NAME[dl_data->cch[channel].ch_type],
2070 STATE_DCCH3_NAME[dl_data->state[channel]],
2071 dl_data->cch[channel].vr, dl_data->cch[channel].vs, dl_data->cch[channel].va,
2072 dl_data->cch[channel].T200_counter, __LINE__);
2073
2074 /* check timer T200 expiry ****************************** */
2075 if ((channel EQ C_DCCH0) AND
2076 (dl_data->cch[C_DCCH0].T200_counter EQ T200_EXPIRED))
2077 T200_expiry (C_DCCH0, PS_SAPI_0);
2078 if ((channel EQ C_DCCH3) AND
2079 (dl_data->cch[C_DCCH3].T200_counter EQ T200_EXPIRED))
2080 T200_expiry (C_DCCH3, PS_SAPI_3);
2081
2082 TRACE_EVENT_WIN_P8 ("UL: DCCH%u=%s,%s vr=%u vs=%u va=%u T200=%u (#%u)",
2083 sapi, CH_TYPE_NAME[dl_data->cch[channel].ch_type],
2084 STATE_DCCH3_NAME[dl_data->state[channel]],
2085 dl_data->cch[channel].vr, dl_data->cch[channel].vs, dl_data->cch[channel].va,
2086 dl_data->cch[channel].T200_counter, __LINE__);
2087
2088 /* state machine **************************************** */
2089 switch (dl_data->state[channel])
2090 {
2091 case STATE_IDLE_DL:
2092 if (pcch->vtx EQ EMPTY_CMD AND !dl_data->RR_dedicated)
2093 break;
2094 send = uplink_idle (channel, sapi);
2095 break;
2096 case STATE_CONTENTION_RESOLUTION: /* the same as STATE_AWAITING_ESTABLISHMENT */
2097 send = uplink_awaiting_establishment (channel, sapi, no_signalling_mode);
2098 break;
2099 case STATE_MULTIPLE_FRAME_ESTABLISHED:
2100 send = uplink_mfe (channel, sapi, no_signalling_mode);
2101 break;
2102 case STATE_TIMER_RECOVERY:
2103 send = uplink_timer_recovery (channel, sapi, no_signalling_mode);
2104 break;
2105 case STATE_AWAITING_RELEASE:
2106 send = uplink_awaiting_release ( channel, sapi);
2107 break;
2108 case STATE_SUSPENDED: /* only DCCH0 */
2109 send = UPLINK_NULL;
2110 break;
2111 case STATE_DISABLED: /* only SABM/UA or SACCH and SDCCH (SAPI 3) */
2112 if (channel EQ C_DCCH3)
2113 {
2114 if (pcch->vtx EQ UA_CMD)
2115 {
2116 send = uplink_idle (channel, sapi);
2117 }
2118 else
2119 {
2120 send = UPLINK_EMPTY;
2121 }
2122 }
2123 break;
2124 }/* endswitch channel_state */
2125
2126 }/* endif send == NULL */
2127
2128 TRACE_EVENT_WIN_P8 ("UL: DCCH%u=%s,%s vr=%u vs=%u va=%u T200=%u (#%u)",
2129 sapi, CH_TYPE_NAME[dl_data->cch[channel].ch_type],
2130 STATE_DCCH3_NAME[dl_data->state[channel]],
2131 dl_data->cch[channel].vr, dl_data->cch[channel].vs, dl_data->cch[channel].va,
2132 dl_data->cch[channel].T200_counter, __LINE__);
2133
2134 if (pcch->ch_type EQ L2_CHANNEL_SACCH)
2135 { /*
2136 * According to 3GPP TS 04.05, 4.2.2 Priority:
2137 * The priority arrangement on the SACCH must ensure that if a SAPI = 3
2138 * frame is awaiting transmission, two SAPI = 0 frames are not sent in
2139 * consecutive SACCH frames. In addition, for the mobile to network
2140 * direction it must also be ensured that any SAPI = 3 frame is followed
2141 * by at least one SAPI = 0 frame.
2142 */
2143
2144 TRACE_EVENT_WIN_P3 ("sacch_last_uplink_sapi=%u SAPI=%u send=%s",
2145 dl_data->sacch_last_uplink_sapi, sapi, SEND_NAME[send]);
2146
2147 if ((dl_data->sacch_last_uplink_sapi EQ PS_SAPI_3) OR
2148 ((sapi EQ PS_SAPI_3 ) AND (send EQ UPLINK_EMPTY)))
2149 {/* last uplinked SACCH frame was one with SAPI=3
2150 * or
2151 * no SACCH SAPI=3 frame is awaiting transmission
2152 * -> uplink of a SACCH SAPI=0 frame
2153 */
2154 sapi = PS_SAPI_0;
2155 }
2156
2157 if (send EQ UPLINK_EMPTY)
2158 {
2159 sapi = PS_SAPI_0;
2160 }
2161
2162 if ((sapi EQ PS_SAPI_0) AND (dl_data->state[C_DCCH0] >= STATE_SUSPENDED))
2163 { /*
2164 * uplink measurement reports only if SAPI=0 is suspended,
2165 * on contention resolution procedure, established or awaiting release
2166 */
2167 send = UPLINK_REPORT;
2168 TRACE_EVENT_WIN ("uplink(): SACCH REPORT now");
2169 }
2170
2171 TRACE_EVENT_WIN_P2 ("sacch_last_uplink_sapi:=%u->%u", dl_data->sacch_last_uplink_sapi, sapi);
2172 dl_data->sacch_last_uplink_sapi = sapi;
2173 }
2174 else if ((pcch->ch_type EQ L2_CHANNEL_SDCCH) AND (channel NEQ C_DCCH3))
2175 { /*
2176 * According to 3GPP TS 04.05, 4.2.2 Priority:
2177 * The priority between data links on SDCCH shall be as follows:
2178 * Highest priority : SAPI = 0, Lowest priority : SAPI = 3.
2179 */
2180 if ((sapi EQ PS_SAPI_0) AND (send <= UPLINK_EMPTY))
2181 { /* special case: nothing is awaiting transmission for SAPI=0 */
2182 if ((dl_data->cch[C_DCCH3].vtx NEQ EMPTY_CMD) OR
2183 com_queue_awaiting_transmission(PS_SAPI_3) OR
2184 (dl_data->cch[C_DCCH3].T200_counter NEQ T200_STOPPED))
2185 {/* something is awaiting transmission for SAPI=3 */
2186 if (dl_data->state[C_DCCH0] >= STATE_CONTENTION_RESOLUTION)
2187 { /*
2188 * uplink SAPI=3 only if SAPI=0 is on contention resolution procedure
2189 * or established or awaiting release
2190 */
2191 send = UPLINK_DCCH3;
2192 }
2193 }
2194
2195 }
2196 }
2197 else
2198 {
2199 /* no special treatment of FACCH */
2200 }
2201
2202 /* return uplink frame buffer pointer dependent on the value of send */
2203 TRACE_EVENT_WIN_P4 ("%s on %s SAPI=%u RR_dedicated=%u",
2204 SEND_NAME[send], CH_TYPE_NAME[pcch->ch_type], sapi, dl_data->RR_dedicated);
2205
2206 switch (send)
2207 {
2208 case UPLINK_NORMAL:
2209 break;
2210
2211 case UPLINK_UA:
2212 case UPLINK_UA_F:
2213 com_build_UA_response (pcch->ch_type, sapi, (UBYTE)((send EQ UPLINK_UA_F) ? 1 : 0));
2214 break;
2215
2216 case UPLINK_IFRAME:
2217 case UPLINK_IFRAME_P:
2218 {
2219 UBYTE m_bit;
2220 UBYTE p_bit = (send EQ UPLINK_IFRAME_P) ? 1 : 0;
2221 T_QUEUE *queue;
2222
2223 if (pcch->ch_type EQ L2_CHANNEL_SACCH)
2224 {
2225 sapi = PS_SAPI_3; /* acknowledged mode only for SAPI=3 */
2226 TRACE_EVENT_WIN ("SACCH with I frame: acknowledged mode only for SAPI=3");
2227 }
2228
2229 if (sapi EQ PS_SAPI_0)
2230 queue = &dl_data->dcch0_queue;
2231 else
2232 queue = &dl_data->dcch3_queue;
2233
2234 if (send EQ UPLINK_IFRAME)
2235 {
2236 com_read_queue (pcch->ch_type, sapi, &m_bit);
2237 }
2238 else
2239 {/* TIMER_RECOVERY state -> repetition of the last frame */
2240 pcch->vs--;
2241 pcch->vs &= 7;
2242 pcch->p_bit_flag = 0;
2243 m_bit = queue->m_bit; /* remember last m bit */
2244 TRACE_EVENT_WIN_P2 ("TIMER_RECOVERY state: decrement vs to %u, remember m=%u", pcch->vs, m_bit);
2245 }
2246
2247
2248 com_build_I_command (pcch->ch_type, sapi, pcch->vs, pcch->vr,
2249 p_bit, m_bit, queue);
2250 pcch->vs++;
2251 pcch->vs &= 7;
2252 TRACE_EVENT_WIN_P4 ("%s SAPI=%u new vs=%u (pcch=%08x)",
2253 CH_TYPE_NAME[pcch->ch_type], sapi, pcch->vs, pcch);
2254 }
2255 set_T200_counter (pcch, sapi);
2256 break;
2257
2258 case UPLINK_RR:
2259 case UPLINK_RR_F:
2260 if (pcch->ch_type EQ L2_CHANNEL_SACCH)
2261 {/*
2262 * There are some tests at the start of dl_uplink() to determine the right
2263 * SAPI value for SACCH. But the resulting value may be wrong because of
2264 * the priority arrangement according to 3GPP TS 04.05, section 4.2.2.
2265 * In case the MS has to uplink a RR frame it is clear that
2266 * L2 is in acknowledged mode and this can be done only with
2267 * a SAPI value of 3 for SACCH.
2268 */
2269 sapi = PS_SAPI_3; /* acknowledged mode only for SAPI=3 */
2270 TRACE_EVENT_WIN ("SACCH with supervisory frame: acknowledged mode only for SAPI=3");
2271 }
2272 com_build_RR_response (pcch->ch_type, sapi, pcch->vr,
2273 (UBYTE)((send EQ UPLINK_RR_F) ? 1 : 0));
2274 break;
2275
2276 case UPLINK_REJ:
2277 case UPLINK_REJ_F:
2278 if (pcch->ch_type EQ L2_CHANNEL_SACCH)
2279 {/*
2280 * There are some tests at the start of dl_uplink() to determine the right
2281 * SAPI value for SACCH. But the resulting value may be wrong because of
2282 * the priority arrangement according to 3GPP TS 04.05, section 4.2.2.
2283 * In case the MS has to uplink a REJ frame it is clear that
2284 * L2 is in acknowledged mode and this can be done only with
2285 * a SAPI value of 3 for SACCH.
2286 */
2287 sapi = PS_SAPI_3; /* acknowledged mode only for SAPI=3 */
2288 TRACE_EVENT_WIN ("SACCH with supervisory frame: acknowledged mode only for SAPI=3");
2289 }
2290 com_build_REJ_response (pcch->ch_type, sapi, pcch->vr,
2291 (UBYTE)((send EQ UPLINK_REJ_F) ? 1 : 0));
2292 break;
2293
2294 case UPLINK_REPORT:
2295 if (dl_data->RR_dedicated)
2296 {/* measurement report only in RR dedicated mode */
2297 sacch0_send_data ();
2298 com_l3trace (TRACE_UACK_UP, pcch->ch_type, (UBYTE *)p_l2_frame+5);
2299
2300
2301 /* no deleting of vtx!!! */
2302 return p_l2_frame;
2303 /* break; not necessary */
2304 }/* endif measurement report only in RR dedicated mode */
2305
2306 /* else go through to UPLINK_EMPTY */
2307 /*lint -fallthrough*/
2308
2309 default:
2310 possible_reset_dcch0_ch_type();
2311
2312 /* check RR message with short PD, short L2 header type 1, format Bter */
2313 if ((dl_data->state[C_DCCH0] >= STATE_SUSPENDED) AND
2314 dl_data->rr_short_pd_buffer.l_buf AND
2315 (dl_data->rr_short_pd_ch_type EQ pcch->ch_type))
2316 { /* RR message with short PD, short L2 header type 1, format Bter */
2317 com_build_UI_Bter (pcch->ch_type);
2318 return p_l2_frame;
2319 }
2320
2321 if (((pcch->ch_type EQ L2_CHANNEL_FACCH_F) OR
2322 (pcch->ch_type EQ L2_CHANNEL_FACCH_H))
2323 AND
2324 ((no_signalling_mode NEQ SIG_ONLY)
2325 #if defined(DELAYED_SABM)
2326 OR
2327 /* suppress UI frames if delayed SABM is pending
2328 * (independent from signalling mode) */
2329 (dl_data->dcch0_sabm_flag NEQ NOT_PRESENT_8BIT)
2330 #endif /* DELAYED_SABM */
2331 #if defined(DELAYED_RELEASE_IND)
2332 OR
2333 (dl_data->release_ind_ch_type NEQ NOT_PRESENT_8BIT)
2334 #endif /* DELAYED_RELEASE_IND */
2335 ))
2336 {
2337 TRACE_EVENT_WIN ("UPLINK_NULL return");
2338 return NULL;
2339 }
2340 /* break; not necessary */
2341
2342 {
2343 T_RADIO_FRAME* empty_frame;
2344
2345 TRACE_EVENT_WIN ("UPLINK_EMPTY return");
2346 /* The use of one byte array instead of two T_RADIO_FRAME structures
2347 * saves 21 byte. Casting is in this case the better way then two calls
2348 * of memcpy.
2349 */
2350 if (pcch->ch_type EQ L2_CHANNEL_SACCH)
2351 empty_frame = (T_RADIO_FRAME*)(&l2_empty_frame[0]);
2352 else
2353 empty_frame = (T_RADIO_FRAME*)(&l2_empty_frame[2]);
2354
2355 ATRC (empty_frame, 23);
2356
2357 return empty_frame;
2358 }
2359 /* break; not necessary */
2360
2361 case UPLINK_DCCH3:
2362 return dl_uplink (C_DCCH3, PS_SAPI_3, no_signalling_mode, TRUE);
2363 /* break; not necessary */
2364 }/* endswitch send */
2365
2366
2367 /*
2368 * UPLINK_NORMAL, UPLINK_IFRAME (_P), UPLINK_UA (_F),
2369 * UPLINK_RR (_F), UPLINK_REJ (_F)
2370 */
2371 TRACE_EVENT_WIN_P5 ("%s SAPI=%u delete vtx=%s ->EMPTY_CMD (%s#%u)",
2372 CH_TYPE_NAME[pcch->ch_type], sapi, VTX_NAME[pcch->vtx], __FILE10__, __LINE__);
2373 pcch->vtx = EMPTY_CMD;
2374
2375 possible_reset_dcch0_ch_type();
2376
2377 return p_l2_frame;
2378 }/* endfunc dl_uplink */
2379
2380 static int uplink_idle (UBYTE channel, UBYTE sapi)
2381 {
2382 GET_INSTANCE_DATA;
2383 T_CCH* pcch = &dl_data->cch[channel];
2384 int ret = UPLINK_NORMAL;
2385 int ua_response = FALSE;
2386
2387 TRACE_EVENT_WIN_P3 ("uplink_idle(): %s %s SAPI=%d",
2388 PROCESS_NAME[channel], CH_TYPE_NAME[pcch->ch_type], sapi);
2389
2390 switch (channel)
2391 {
2392 case C_DCCH0:
2393 switch (pcch->vtx)
2394 {
2395 case UA_CMD:
2396 ret = pcch->f_bit ? UPLINK_UA_F : UPLINK_UA;
2397 break;
2398 case DM_CMD:
2399 com_build_DM_response (pcch->ch_type, sapi, pcch->f_bit);
2400 break;
2401 default:
2402 ret = UPLINK_EMPTY;/* no SAPI=3 frame if DCCH0 is idle */
2403 break;
2404 }
2405 break;
2406
2407 case C_DCCH3:
2408 switch (pcch->vtx)
2409 {
2410 case UA_CMD:
2411 ua_response = TRUE;
2412 ret = pcch->f_bit ? UPLINK_UA_F : UPLINK_UA;
2413 break;
2414 case DM_CMD:
2415 com_build_DM_response (pcch->ch_type, PS_SAPI_3, 1);
2416 ret = UPLINK_NORMAL;
2417 break;
2418 default:
2419 ret = UPLINK_EMPTY;
2420 break;
2421 }
2422 break;
2423 }/* endswitch channel */
2424
2425 if (ua_response AND (ret EQ UPLINK_UA_F))
2426 {
2427 drr_dl_establish_ind (pcch->ch_type, sapi,
2428 (UBYTE)(com_queue_awaiting_transmission (sapi) ? DL_UNSERVED : DL_ALL_DONE));
2429 set_channel_state (channel, STATE_MULTIPLE_FRAME_ESTABLISHED);
2430 }
2431
2432 return ret;
2433 }/* endfunc uplink_idle */
2434
2435 static int uplink_awaiting_establishment (UBYTE channel, UBYTE sapi,
2436 UBYTE no_signalling_mode)
2437 {
2438 GET_INSTANCE_DATA;
2439 T_CCH* pcch = &dl_data->cch[channel];
2440 int ret = UPLINK_NORMAL;
2441 int ua_response = FALSE;
2442 int sabm_command = 0;
2443
2444 TRACE_EVENT_WIN_P3 ("uplink_awaiting_establishment(): %s %s SAPI=%d",
2445 PROCESS_NAME[channel], CH_TYPE_NAME[pcch->ch_type], sapi);
2446
2447 if (pcch->time_flag)
2448 set_T200_counter (pcch, sapi);
2449
2450 switch (channel)
2451 {
2452 case C_DCCH0:
2453 if (pcch->vtx EQ SABM_CMD)
2454 {
2455 if (pcch->contention_resolution)
2456 sabm_command = 2; /* com_build_SABM with L3 */
2457 else
2458 sabm_command = 1; /* com_build_SABM without L3 */
2459 }
2460 else
2461 {
2462 ret = UPLINK_EMPTY;/* no SAPI=0 frame is waiting transmission */
2463 }
2464 break;
2465
2466 case C_DCCH3:
2467 switch (pcch->vtx)
2468 {
2469 case SABM_CMD:
2470 sabm_command = 1; /* com_build_SABM without L3 */
2471 break;
2472 case UA_CMD:
2473 ua_response = TRUE;
2474 break;
2475 case DM_CMD:
2476 com_build_DM_response (pcch->ch_type, sapi, pcch->f_bit);
2477 break;
2478 default:
2479 ret = UPLINK_EMPTY;
2480 break;
2481 }
2482
2483 break;
2484 }
2485
2486 if (ua_response)
2487 {
2488 drr_dl_establish_cnf (pcch->ch_type, sapi);
2489 set_channel_state (channel, STATE_MULTIPLE_FRAME_ESTABLISHED);
2490
2491 ret = pcch->f_bit ? UPLINK_UA_F : UPLINK_UA;
2492 }
2493 else if (sabm_command)
2494 {
2495 com_build_SABM(pcch->ch_type, sapi, sabm_command EQ 2);
2496 }
2497
2498 return ret;
2499 }/* endfunc uplink_awaiting_establishment */
2500
2501 static int uplink_mfe (UBYTE channel, UBYTE sapi, UBYTE no_signalling_mode)
2502 {
2503 GET_INSTANCE_DATA;
2504 T_CCH* pcch = &dl_data->cch[channel];
2505 int ret = UPLINK_NORMAL;
2506
2507 TRACE_EVENT_WIN_P6 ("uplink_mfe(): %s:%s SAPI=%d vtx=%s (vs=%u va+1=%u)",
2508 PROCESS_NAME[channel], CH_TYPE_NAME[pcch->ch_type], sapi,
2509 VTX_NAME[pcch->vtx], pcch->vs, (pcch->va + 1)&7 );
2510
2511 if (pcch->time_flag)
2512 set_T200_counter (pcch, sapi);
2513
2514 switch (pcch->vtx)
2515 {
2516 case RR_CMD:
2517 if (pcch->f_bit_flag)
2518 {
2519 ret = UPLINK_RR_F;
2520 pcch->f_bit_flag = 0;
2521 }
2522 else
2523 {
2524 if (!com_queue_awaiting_transmission (sapi))
2525 ret = UPLINK_RR;
2526 else
2527 {
2528 if (pcch->vs EQ ((pcch->va + 1)&7))
2529 ret = UPLINK_RR;
2530 else
2531 ret = UPLINK_IFRAME;
2532 }
2533 }
2534 break;
2535
2536 case UA_CMD:
2537 ret = pcch->f_bit ? UPLINK_UA_F : UPLINK_UA;
2538 break;
2539
2540 case RR_RSP:
2541 ret = pcch->f_bit ? UPLINK_RR_F : UPLINK_RR;
2542 pcch->f_bit_flag = 0;
2543 break;
2544
2545 case REJ_CMD:
2546 ret = pcch->f_bit ? UPLINK_REJ_F : UPLINK_REJ;
2547 pcch->f_bit_flag = 0;
2548 break;
2549
2550 default: /* vtx = ELSE */
2551 switch (channel)
2552 {
2553 case C_DCCH0:
2554 if (com_queue_awaiting_transmission (PS_SAPI_0)
2555 AND
2556 (pcch->vs NEQ ((pcch->va + 1)&7)))
2557 ret = UPLINK_IFRAME;
2558 else
2559 {
2560 ret = UPLINK_EMPTY;/* no SAPI=0 frame is waiting transmission */
2561 }
2562 break;
2563
2564 case C_DCCH3:
2565 if (com_queue_awaiting_transmission (PS_SAPI_3))
2566 {
2567 if (pcch->vs EQ ((pcch->va + 1)&7))
2568 ret = UPLINK_EMPTY;
2569 else
2570 ret = UPLINK_IFRAME;
2571 }
2572 else
2573 {
2574 ret = dcch3_check_disc (UPLINK_EMPTY);/* no SAPI=3 frame is waiting transmission */
2575 }
2576 break;
2577 }/* endswitch channel */
2578 break;
2579 }/* endswitch vtx */
2580
2581
2582 return ret;
2583 }/* endfunc uplink_mfe */
2584
2585 static int uplink_timer_recovery (UBYTE channel, UBYTE sapi, UBYTE no_signalling_mode)
2586 {
2587 GET_INSTANCE_DATA;
2588 T_CCH* pcch = &dl_data->cch[channel];
2589 int ret = UPLINK_NORMAL;
2590
2591 TRACE_EVENT_WIN_P3 ("uplink_timer_recovery(): %s %s SAPI=%d",
2592 PROCESS_NAME[channel], CH_TYPE_NAME[pcch->ch_type], sapi);
2593
2594 if (pcch->time_flag)
2595 set_T200_counter (pcch, sapi);
2596
2597 switch (pcch->vtx)
2598 {
2599 case RR_CMD:
2600 if (pcch->f_bit_flag)
2601 {
2602 ret = UPLINK_RR_F;
2603 pcch->f_bit_flag = 0;
2604 }
2605 else
2606 {
2607 if (pcch->p_bit_flag)
2608 ret = UPLINK_IFRAME_P;
2609 else
2610 ret = UPLINK_RR;
2611 }
2612 break;
2613
2614 case UA_CMD:
2615 ret = pcch->f_bit ? UPLINK_UA_F : UPLINK_UA;
2616 break;
2617
2618 case RR_RSP:
2619 ret = pcch->f_bit ? UPLINK_RR_F : UPLINK_RR;
2620 pcch->f_bit_flag = 0;
2621 break;
2622
2623 case REJ_CMD:
2624 ret = pcch->f_bit ? UPLINK_REJ_F : UPLINK_REJ;
2625 pcch->f_bit_flag = 0;
2626 break;
2627
2628 default: /* vtx = ELSE */
2629 TRACE_EVENT_WIN_P3 ("%s SAPI=%u vtx=%s",
2630 CH_TYPE_NAME[pcch->ch_type], sapi, VTX_NAME[pcch->vtx]);
2631
2632 if (pcch->p_bit_flag)
2633 ret = UPLINK_IFRAME_P;
2634 else
2635 switch (channel)
2636 {
2637 case C_DCCH0:
2638 ret = UPLINK_EMPTY;/* no SAPI=0 frame is waiting transmission */
2639 break;
2640
2641 case C_DCCH3:
2642 ret = dcch3_check_disc (UPLINK_EMPTY);/* no SAPI=3 frame is waiting transmission */
2643 break;
2644 }
2645 break;
2646 }
2647
2648 #if 0 /* decrement first short before sending the frame */
2649 if (ret EQ UPLINK_IFRAME_P)
2650 {
2651 pcch->vs--;
2652 pcch->vs &= 7;
2653 pcch->p_bit_flag = 0;
2654 }
2655 #endif /* 0 */
2656 return ret;
2657 }/* endfunc uplink_timer_recovery */
2658
2659 GLOBAL int uplink_awaiting_release (UBYTE channel, UBYTE sapi)
2660 {
2661 GET_INSTANCE_DATA;
2662 T_CCH* pcch = &dl_data->cch[channel];
2663 int ret = UPLINK_NORMAL;
2664
2665 TRACE_EVENT_WIN_P3 ("uplink_awaiting_release(): %s %s SAPI=%d",
2666 PROCESS_NAME[channel], CH_TYPE_NAME[pcch->ch_type], sapi);
2667
2668 if (pcch->time_flag)
2669 set_T200_counter (pcch, sapi);
2670
2671 switch (pcch->vtx)
2672 {
2673 case DISC_CMD:
2674 /* DL_OFFLINE_TRACE (TRACE_DL_EVENT, channel, pcch->ch_type, "UL:Send DISC"); */
2675 com_build_DISC_command (pcch->ch_type, sapi, 1);
2676 break;
2677 case UA_CMD:
2678 set_channel_state (channel, STATE_IDLE_DL);
2679
2680 #if defined(DELAYED_RELEASE_IND)
2681 switch (pcch->ch_type)
2682 {
2683 #if defined(DL_FACCH_RELEASE_DELAY_VALUE) && (DL_FACCH_RELEASE_DELAY_VALUE > 0)
2684 case L2_CHANNEL_FACCH_F:
2685 case L2_CHANNEL_FACCH_H:
2686 /* delay DL RELEASE IND to RR for testcase 25.2.3 */
2687 dl_data->release_ind_ch_type = pcch->ch_type;
2688 dl_data->release_ind_sapi = sapi;
2689 if (dl_data->release_ind_delay EQ 0)
2690 {
2691 dl_data->release_ind_delay = DL_FACCH_RELEASE_DELAY_VALUE;
2692 DL_OFFLINE_TRACE (TRACE_DL_EVENT, C_DCCH0, pcch->ch_type, "delay REL IND on FACCH");
2693 }
2694 break;
2695 #endif /* DL_FACCH_RELEASE_DELAY_VALUE */
2696 #if defined(DL_SDCCH_RELEASE_DELAY_VALUE) && (DL_SDCCH_RELEASE_DELAY_VALUE > 0)
2697 case L2_CHANNEL_SDCCH:
2698 /* delay DL RELEASE IND to RR for testcase 25.2.3 */
2699 dl_data->release_ind_ch_type = pcch->ch_type;
2700 dl_data->release_ind_sapi = sapi;
2701 if (dl_data->release_ind_delay EQ 0)
2702 {
2703 dl_data->release_ind_delay = DL_SDCCH_RELEASE_DELAY_VALUE;
2704 DL_OFFLINE_TRACE (TRACE_DL_EVENT, channel, pcch->ch_type, "delay REL IND on SDCCH");
2705 }
2706 break;
2707 #endif /* DL_SDCCH_RELEASE_DELAY_VALUE */
2708 default:
2709 drr_dl_release_ind (pcch->ch_type, sapi, NOT_PRESENT_8BIT, TRUE);
2710 break;
2711 }
2712 #else /* DELAYED_RELEASE_IND */
2713 drr_dl_release_ind (pcch->ch_type, sapi, NOT_PRESENT_8BIT, TRUE);
2714 #endif /* DELAYED_RELEASE_IND */
2715
2716 #if defined(LATE_LEAVING_DEDICATED)
2717 com_leave_dedicated (pcch->ch_type);
2718 #endif /* LATE_LEAVING_DEDICATED */
2719 ret = UPLINK_UA_F;
2720 break;
2721
2722 default:
2723 switch (pcch->ch_type)
2724 {
2725 case L2_CHANNEL_SACCH:
2726 if (channel EQ C_DCCH0)
2727 ret = UPLINK_REPORT;
2728 break;
2729 default:
2730 if (channel EQ C_DCCH0)
2731 {
2732 pcch = &dl_data->cch[C_DCCH3];
2733 if (pcch->time_flag)
2734 set_T200_counter (pcch, PS_SAPI_3);
2735 }
2736 ret = UPLINK_EMPTY;
2737 break;
2738 }/* endswitch channel */
2739 }/* endswitch vtx */
2740
2741 return ret;
2742 }/* endfunc uplink_awaiting_release */
2743
2744 #if defined(CHECK_PCCHI)
2745 static void check_pcch_i (T_CCH_INTERN* pcch_i, int line)
2746 {
2747 char buf[23];
2748 int ret = 0;
2749
2750 if (pcch_i EQ NULL)
2751 ret = -1;
2752 else if (pcch_i->pcch EQ NULL)
2753 ret = -2;
2754
2755 if (ret)
2756 {
2757 sprintf (buf, "#%d pcch=NULL %d", line, -ret);
2758 DL_OFFLINE_TRACE (TRACE_DL_EVENT, TRACE_CH_UNKNOWN, 0,buf);
2759 }
2760
2761 return ret;
2762 }/* endfunc check_pcch_i */
2763 #endif /* CHECK_PCCHI */
2764
2765 #endif /* DL_C */