FreeCalypso > hg > fc-magnetite
comparison src/g23m-gprs/llc/llc_irxl.c @ 183:219afcfc6250
src/g23m-gprs: initial import from TCS3.2/LoCosto
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 13 Oct 2016 04:24:13 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
182:f02d0a0e1849 | 183:219afcfc6250 |
---|---|
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 is part of the entity LLC and implements all labels | |
18 | in the SDL-documentation (IRX-statemachine) that are called from | |
19 | more than one diagram/place. | |
20 +----------------------------------------------------------------------------- | |
21 */ | |
22 | |
23 #ifndef LLC_IRXL_C | |
24 #define LLC_IRXL_C | |
25 #endif | |
26 | |
27 #define ENTITY_LLC | |
28 | |
29 /*==== INCLUDES =============================================================*/ | |
30 | |
31 #include "typedefs.h" /* to get Condat data types */ | |
32 #include "vsi.h" /* to get a lot of macros */ | |
33 #include "macdef.h" | |
34 #include "gprs.h" | |
35 #include "gsm.h" /* to get a lot of macros */ | |
36 #include "cnf_llc.h" /* to get cnf-definitions */ | |
37 #include "mon_llc.h" /* to get mon-definitions */ | |
38 #include "prim.h" /* to get the definitions of used SAP and directions */ | |
39 #include "llc.h" /* to get the global entity definitions */ | |
40 | |
41 #include "llc_irxf.h" /* to get local IRX functions */ | |
42 #include "llc_irxl.h" /* to get local IRX labels */ | |
43 #include "llc_llmes.h" /* to get signal interface to LLME */ | |
44 #include "llc_txs.h" /* to get signal interface to TX */ | |
45 | |
46 /*==== CONST ================================================================*/ | |
47 | |
48 /*==== LOCAL VARS ===========================================================*/ | |
49 | |
50 /*==== PRIVATE FUNCTIONS ====================================================*/ | |
51 | |
52 | |
53 /* | |
54 +------------------------------------------------------------------------------ | |
55 | Function : irx_get_next_gap | |
56 +------------------------------------------------------------------------------ | |
57 | Description : Searches queue with already received frames. | |
58 | | |
59 | Parameters : next_free - pointer to T_FRAME_NUM, number of the next | |
60 | frame that has not been received yet. | |
61 | If queue is empty, this parameter will be | |
62 | set to (llc_data->sapi->vr + 1) % | |
63 | (MAX_SEQUENCE_NUMBER + 1). | |
64 | gap_size - pointer to T_FRAME_NUM, 0, 1 or bigger | |
65 | Preconditions: llc_data->sapi points to the affected sapi. | |
66 | There is 1 entry in the queue with vr==ns. | |
67 | | |
68 +------------------------------------------------------------------------------ | |
69 */ | |
70 GLOBAL void irx_get_next_gap (T_FRAME_NUM* next_free, | |
71 T_FRAME_NUM* gap_size) | |
72 { | |
73 | |
74 T_IRX_QUEUE* entry = llc_data->irx->queue; | |
75 BOOL gap_found = FALSE; | |
76 | |
77 TRACE_FUNCTION("irx_get_next_gap"); | |
78 | |
79 *next_free = (llc_data->sapi->vr + 1) % (MAX_SEQUENCE_NUMBER + 1); | |
80 *gap_size = 0; | |
81 | |
82 TRACE_EVENT_P1("*next_free: %d", *next_free); | |
83 | |
84 | |
85 while ((entry != NULL) && | |
86 FRAME_NUM_VALID( entry->ns, | |
87 llc_data->sapi->vr, | |
88 llc_data->sapi->vr + *(llc_data->ku)) ) | |
89 { | |
90 entry = entry->next; | |
91 } | |
92 | |
93 /* | |
94 * If rest of queue is empty, values of next_free and gap_size are ok. | |
95 */ | |
96 if (entry == NULL) | |
97 { | |
98 return; | |
99 } /* if (entry == NULL) */ | |
100 | |
101 /* | |
102 * Queue is not empty. Find the first gap. | |
103 */ | |
104 while ((entry != NULL) && !gap_found) | |
105 { | |
106 T_FRAME_NUM num = entry->ns; | |
107 | |
108 if (num == *next_free) | |
109 { | |
110 entry = entry->next; | |
111 *next_free = (*next_free + 1) % (MAX_SEQUENCE_NUMBER + 1); | |
112 } | |
113 else | |
114 { | |
115 gap_found = TRUE; | |
116 *gap_size = (num - *next_free) % (MAX_SEQUENCE_NUMBER + 1); | |
117 } | |
118 } /* while ((entry != NULL) && !gap_found) */ | |
119 | |
120 TRACE_EVENT_P2("*next_free: %u *gap_size: %u ", *next_free, *gap_size); | |
121 | |
122 | |
123 } /* irx_get_next_gap() */ | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 /*==== PUBLIC FUNCTIONS =====================================================*/ | |
132 | |
133 | |
134 /* | |
135 +------------------------------------------------------------------------------ | |
136 | Function : irx_label_if | |
137 +------------------------------------------------------------------------------ | |
138 | Description : Describes label IRX_IF | |
139 | | |
140 | Parameters : ll_unitdata_ind - a valid pointer to an LL_UNITDATA_IND | |
141 | primitive | |
142 | ns - N(S) of received frame | |
143 | a_bit - A bit of received frame | |
144 | state - current state of IRX | |
145 | | |
146 +------------------------------------------------------------------------------ | |
147 */ | |
148 GLOBAL void irx_label_if (T_LL_UNITDATA_IND *ll_unitdata_ind, | |
149 T_FRAME_NUM ns, | |
150 T_BIT a_bit, | |
151 UBYTE state) | |
152 { | |
153 BOOL is_busy; | |
154 T_FRAME_NUM vsi; | |
155 BOOL vsi_found; | |
156 | |
157 | |
158 TRACE_FUNCTION( "irx_label_if" ); | |
159 | |
160 if (state == IRX_ABM) | |
161 { | |
162 /* | |
163 * Label IRX_IF_ABM | |
164 */ | |
165 if ( ns == llc_data->sapi->vr ) | |
166 { | |
167 BOOL found = FALSE; | |
168 T_FRAME_NUM num = 0; | |
169 irx_get_last_queued_ns(&found, &num); | |
170 if (!found) | |
171 { | |
172 /* | |
173 * Store N(S)/V(R) condition | |
174 */ | |
175 llc_data->irx->last_ns = NS_EQUAL_VR; | |
176 /* | |
177 * If N(s) = V(r) increment V(r), handle OC(rx) | |
178 */ | |
179 llc_data->sapi->vr++; | |
180 | |
181 if (llc_data->sapi->vr > MAX_SEQUENCE_NUMBER) | |
182 { | |
183 llc_data->sapi->oc_i_rx += (MAX_SEQUENCE_NUMBER+1); | |
184 llc_data->sapi->vr = 0; | |
185 } | |
186 } | |
187 else | |
188 { | |
189 | |
190 T_FRAME_NUM next_free = 0; | |
191 T_FRAME_NUM gap_size = 0; | |
192 | |
193 irx_get_next_gap (&next_free, &gap_size); | |
194 | |
195 /* | |
196 * vr will be set to next_free. If MAX_SEQUENCE_NUMBER is passed, | |
197 * increment overflow counter. | |
198 */ | |
199 if (llc_data->sapi->vr > next_free) | |
200 { | |
201 llc_data->sapi->oc_i_rx += (MAX_SEQUENCE_NUMBER + 1); | |
202 } | |
203 | |
204 llc_data->sapi->vr = next_free; | |
205 | |
206 if (gap_size == 0) { | |
207 llc_data->irx->last_ns = NS_EQUAL_VR; | |
208 } else if (gap_size == 1) { | |
209 llc_data->irx->last_ns = NS_EQUAL_VR_PLUS_1; | |
210 } else { | |
211 llc_data->irx->last_ns = NS_NO_SEQUENCE_ERROR; | |
212 } | |
213 | |
214 } | |
215 | |
216 /* | |
217 * Expected next frame received. | |
218 */ | |
219 if ( llc_data->irx->ll_send_ready == TRUE ) | |
220 { | |
221 /* | |
222 * Forward the frame to L3 | |
223 */ | |
224 PPASS (ll_unitdata_ind, ll_data_ind, LL_DATA_IND); | |
225 TRACE_2_OUT_PARA("s:%d len:%d", ll_data_ind->sapi, BYTELEN(ll_data_ind->sdu.l_buf)); | |
226 PSEND (hCommSNDCP, ll_data_ind); | |
227 | |
228 llc_data->irx->ll_send_ready = FALSE; | |
229 | |
230 /* | |
231 * Increment V(f) (= Next frame number to forward to L3) | |
232 */ | |
233 llc_data->irx->vf += 1; | |
234 llc_data->irx->vf %= (MAX_SEQUENCE_NUMBER+1); | |
235 | |
236 /* | |
237 * Update V(R) if we have the next frames already queued | |
238 */ | |
239 irx_update_vr (); | |
240 | |
241 /* | |
242 * Handle the acknowledgement | |
243 */ | |
244 irx_send_ack (a_bit); | |
245 | |
246 /* SET_STATE (IRX, SAME_STATE); */ | |
247 } | |
248 else | |
249 { | |
250 /* | |
251 * store frame and update V(R) if next frames already stored | |
252 */ | |
253 irx_queue_store (ll_unitdata_ind, ns, &is_busy); | |
254 irx_update_vr (); | |
255 | |
256 if ( is_busy == TRUE ) | |
257 { | |
258 irx_send_rnr (); | |
259 SET_STATE (IRX, IRX_ABM_BUSY); | |
260 } | |
261 else | |
262 { | |
263 irx_send_ack (a_bit); | |
264 /* SET_STATE (IRX, SAME_STATE); */ | |
265 } | |
266 } | |
267 } | |
268 else | |
269 { | |
270 /* | |
271 * Not the expected next frame received. Check if it is in receive window. | |
272 */ | |
273 if ( FRAME_NUM_VALID (llc_data->sapi->vr + 1, ns, llc_data->sapi->vr + *(llc_data->ku)) ) | |
274 { | |
275 /* | |
276 * Store N(S)/V(R) condition | |
277 */ | |
278 if (ns == (llc_data->sapi->vr + 1) % (MAX_SEQUENCE_NUMBER+1)) | |
279 { | |
280 llc_data->irx->last_ns = NS_EQUAL_VR_PLUS_1; | |
281 } | |
282 else | |
283 { | |
284 /* | |
285 * Check if we have detect a sequence error or not: If ns equals to | |
286 * ns + 1 of the last queued frame then we have not detect a new error | |
287 */ | |
288 irx_get_last_queued_ns (&vsi_found, &vsi); | |
289 | |
290 if (vsi_found) | |
291 { | |
292 if (ns == (vsi + 1) % (MAX_SEQUENCE_NUMBER+1)) | |
293 { | |
294 /* | |
295 * ok, seems to be in sequence | |
296 */ | |
297 llc_data->irx->last_ns = NS_NO_SEQUENCE_ERROR; | |
298 } | |
299 else | |
300 { | |
301 /* | |
302 * sequence error found | |
303 */ | |
304 llc_data->irx->last_ns = NS_IN_RANGE_VR_KU; | |
305 } | |
306 } | |
307 else | |
308 { | |
309 /* | |
310 * sequence error found | |
311 */ | |
312 llc_data->irx->last_ns = NS_IN_RANGE_VR_KU; | |
313 } | |
314 } | |
315 | |
316 /* | |
317 * store frame and update V(R) | |
318 */ | |
319 irx_queue_store (ll_unitdata_ind, ns, &is_busy); | |
320 | |
321 if ( is_busy == TRUE ) | |
322 { | |
323 irx_send_rnr (); | |
324 SET_STATE (IRX, IRX_ABM_BUSY); | |
325 } | |
326 else | |
327 { | |
328 irx_send_ack (a_bit); | |
329 /* SET_STATE (IRX, SAME_STATE); */ | |
330 } | |
331 } | |
332 else | |
333 { | |
334 /* | |
335 * duplicate frame | |
336 */ | |
337 TRACE_0_INFO ("Duplicated frame received"); | |
338 | |
339 PFREE (ll_unitdata_ind); | |
340 irx_send_ack (a_bit); | |
341 /* SET_STATE (IRX, SAME_STATE); */ | |
342 } | |
343 } | |
344 } | |
345 else | |
346 { | |
347 /* | |
348 * ABM_BUSY | |
349 */ | |
350 irx_send_rnr (); | |
351 | |
352 /* | |
353 * ignore I frame in state 'own receiver busy' | |
354 */ | |
355 PFREE (ll_unitdata_ind); | |
356 /* SET_STATE (IRX, SAME_STATE); */ | |
357 } | |
358 | |
359 return; | |
360 } /* irx_label_if() */ | |
361 |