FreeCalypso > hg > fc-tourmaline
comparison src/g23m-fad/t30/t30_bcsf.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-F&D (8411) | |
4 | Modul : t30_bcsf | |
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 procedures and functions for | |
18 | the component T30 of the mobile station | |
19 +----------------------------------------------------------------------------- | |
20 */ | |
21 | |
22 #ifndef T30_BCSF_C | |
23 #define T30_BCSF_C | |
24 #endif | |
25 | |
26 #define ENTITY_T30 | |
27 | |
28 /*==== INCLUDES ===================================================*/ | |
29 | |
30 #include <string.h> | |
31 #include <stdlib.h> | |
32 #include <stddef.h> | |
33 #include "typedefs.h" | |
34 #include "pcm.h" | |
35 #include "vsi.h" | |
36 #include "macdef.h" | |
37 #include "pconst.cdg" | |
38 #include "mconst.cdg" | |
39 #include "message.h" | |
40 #include "ccdapi.h" | |
41 #include "custom.h" | |
42 #include "gsm.h" | |
43 #include "prim.h" | |
44 #include "cnf_t30.h" | |
45 #include "mon_t30.h" | |
46 #include "pei.h" | |
47 #include "tok.h" | |
48 #include "dti.h" /* functionality of the dti library */ | |
49 #include "t30.h" | |
50 | |
51 /*==== CONST =======================================================*/ | |
52 | |
53 /*==== TYPES =======================================================*/ | |
54 | |
55 /*==== VAR EXPORT ==================================================*/ | |
56 | |
57 /*==== VAR LOCAL ===================================================*/ | |
58 | |
59 | |
60 LOCAL const USHORT crctab[256] = | |
61 { | |
62 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, | |
63 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, | |
64 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, | |
65 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, | |
66 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, | |
67 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, | |
68 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, | |
69 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, | |
70 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, | |
71 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, | |
72 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, | |
73 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, | |
74 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, | |
75 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, | |
76 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, | |
77 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, | |
78 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, | |
79 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, | |
80 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, | |
81 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, | |
82 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, | |
83 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, | |
84 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, | |
85 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, | |
86 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, | |
87 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, | |
88 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, | |
89 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, | |
90 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, | |
91 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, | |
92 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, | |
93 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 | |
94 }; | |
95 | |
96 /*==== FUNCTIONS ===================================================*/ | |
97 | |
98 /* | |
99 +--------------------------------------------------------------------+ | |
100 | PROJECT : GSM-F&D (8411) MODULE : T30_BCSF | | |
101 | STATE : code ROUTINE : bcs_build_report | | |
102 +--------------------------------------------------------------------+ | |
103 | |
104 PURPOSE : build the T30_REPORT_IND primitive out of a send/rec. frame | |
105 | |
106 */ | |
107 | |
108 LOCAL void bcs_build_report(UBYTE *frame, USHORT len, T_T30_REPORT_IND *t30_report_ind) | |
109 { | |
110 if (t30_data->bitorder & FBO_REV_STATUS) /* reverse the bitorder of each byte */ | |
111 { | |
112 memcpy(t30_report_ind->sdu.buf, frame, len); | |
113 } | |
114 else | |
115 { | |
116 USHORT i; | |
117 for (i=0; i<len; i++) | |
118 t30_report_ind->sdu.buf[i] = BIT_MIRROR[frame[i]]; | |
119 } | |
120 | |
121 t30_report_ind->sdu.l_buf = (len << 3); | |
122 t30_report_ind->sdu.o_buf = 0; | |
123 } | |
124 | |
125 /* | |
126 +--------------------------------------------------------------------+ | |
127 | PROJECT : GSM-F&D (8411) MODULE : T30_BCSF | | |
128 | STATE : code ROUTINE : bcs_init | | |
129 +--------------------------------------------------------------------+ | |
130 | |
131 PURPOSE : initialize BCS formatter | |
132 | |
133 */ | |
134 | |
135 GLOBAL void bcs_init(T_T30_DATA *pt30_data) | |
136 { | |
137 TRACE_FUNCTION ("bcs_init()"); | |
138 memset (pt30_data->bcs_frm, 0, BCS_FRM_SIZE); | |
139 } | |
140 | |
141 /* | |
142 +--------------------------------------------------------------------+ | |
143 | PROJECT : GSM-F&D (8411) MODULE : T30_BCSF | | |
144 | STATE : code ROUTINE : bcs_check_frames | | |
145 +--------------------------------------------------------------------+ | |
146 | |
147 PURPOSE : This function checks the final flag and the frame checking sequence. | |
148 */ | |
149 | |
150 LOCAL UBYTE bcs_check_frames(UBYTE *idx_max) | |
151 { | |
152 | |
153 T_sdu *sdu = (T_sdu*)t30_data->bcs_frm; | |
154 UBYTE idx; | |
155 | |
156 for (idx = 0; idx < *idx_max; idx++) | |
157 { | |
158 #ifdef _SIMULATION_ /* FCS generating/checking off */ | |
159 if (t30_data->test_mode & TST_FCS) | |
160 { | |
161 } | |
162 else | |
163 #endif | |
164 { | |
165 USHORT crctt = 0xffff; /* initialize crc */ | |
166 | |
167 /* shift each bit through polynomial */ | |
168 USHORT pos; | |
169 for (pos = t30_data->frm[idx].beg; pos <= t30_data->frm[idx].end; pos++) | |
170 { | |
171 SHORT tmp = (crctt >> 8) ^ sdu->buf[pos]; | |
172 crctt = ((crctt << 8) ^ crctab[tmp & 0xff]) & 0xffff; | |
173 } | |
174 if (crctt NEQ 0x1D0F) /* check remainder */ | |
175 return CHK_FCS_ERR; | |
176 } | |
177 #if defined _SIMULATION_ || defined KER_DEBUG_BCS | |
178 ker_debug ("BCS_DATA_IND", (UBYTE*)&sdu->buf[t30_data->frm[idx].beg], (USHORT)(t30_data->frm[idx].end-t30_data->frm[idx].beg)); | |
179 #endif | |
180 /* count final flags */ | |
181 if (sdu->buf[t30_data->frm[idx].beg + 1] & 0x08) | |
182 { | |
183 *idx_max = (UBYTE)idx + 1; | |
184 return CHK_OK; | |
185 } | |
186 } | |
187 #ifdef _SIMULATION_ /* Control checking OFF */ | |
188 if (t30_data->test_mode & TST_CTRL) | |
189 return CHK_OK; | |
190 #endif | |
191 return CHK_FIN_ERR; | |
192 } | |
193 | |
194 /* | |
195 +--------------------------------------------------------------------+ | |
196 | PROJECT : GSM-F&D (8411) MODULE : T30_BCSF | | |
197 | STATE : code ROUTINE : bcs_frame_pos | | |
198 +--------------------------------------------------------------------+ | |
199 | |
200 PURPOSE : This function extracts | |
201 the beginning, the end and the length of each frame. | |
202 */ | |
203 | |
204 LOCAL UBYTE bcs_frame_pos(UBYTE *flag_vector, UBYTE *idx_max) | |
205 { | |
206 USHORT idx = 0; | |
207 T_sdu *sdu = (T_sdu*)t30_data->bcs_frm; | |
208 | |
209 *idx_max = 0; | |
210 while (idx < sdu->l_buf) | |
211 { | |
212 /* skip flags */ | |
213 while (idx < sdu->l_buf AND flag_vector[idx]) | |
214 idx++; | |
215 | |
216 /* ready if last byte is a flag */ | |
217 if (idx EQ sdu->l_buf) | |
218 return FRM_OK; | |
219 | |
220 /* save begin of frame */ | |
221 t30_data->frm[*idx_max].beg = idx; | |
222 | |
223 /* search flag */ | |
224 while (idx < sdu->l_buf AND !flag_vector[idx]) | |
225 idx++; | |
226 | |
227 /* error if no flag found */ | |
228 if (idx EQ sdu->l_buf) | |
229 { | |
230 t30_data->frm[*idx_max].beg = 0; | |
231 return FRM_OK; /* return FRM_ERR_NO_FLAG; ??? */ | |
232 } | |
233 | |
234 /* save end of fame and length of frame */ | |
235 t30_data->frm[*idx_max].end = idx - 1; | |
236 t30_data->frm[*idx_max].len = idx - t30_data->frm[*idx_max].beg; | |
237 | |
238 /* error if too many frames received */ | |
239 if (++(*idx_max) EQ FRAMES_MAX) | |
240 return FRM_ERR_TOO_MANY_FRAMES; | |
241 | |
242 /* next frame */ | |
243 idx++; | |
244 } | |
245 return FRM_OK; | |
246 } | |
247 | |
248 /* | |
249 +--------------------------------------------------------------------+ | |
250 | PROJECT : GSM-F&D (8411) MODULE : T30_BCSF | | |
251 | STATE : code ROUTINE : bcs_report_rcv | | |
252 +--------------------------------------------------------------------+ | |
253 | |
254 PURPOSE : This function reports the received HDLC frames to MMI | |
255 if desired. | |
256 */ | |
257 | |
258 LOCAL void bcs_report_rcv(UBYTE idx_max) | |
259 { | |
260 T_sdu *sdu = (T_sdu*)t30_data->bcs_frm; | |
261 USHORT idx; | |
262 | |
263 for (idx = 0 ; idx < idx_max ; idx++) | |
264 { | |
265 if (t30_data->frm[idx].len >= 2) | |
266 { | |
267 PALLOC_SDU (t30_report_ind, T30_REPORT_IND, REPORT_SIZE_BITS); | |
268 bcs_build_report (&sdu->buf[t30_data->frm[idx].beg], (USHORT)(t30_data->frm[idx].len - 2), t30_report_ind); | |
269 t30_report_ind->dir = DIR_RCV; | |
270 PSENDX (MMI, t30_report_ind); | |
271 } | |
272 } | |
273 } | |
274 | |
275 /* | |
276 +--------------------------------------------------------------------+ | |
277 | PROJECT : GSM-F&D (8411) MODULE : T30_BCSF | | |
278 | STATE : code ROUTINE : bcs_decode | | |
279 +--------------------------------------------------------------------+ | |
280 | |
281 PURPOSE : This function decodes each hdlc frame and sends the | |
282 decoded data to the kernel. | |
283 */ | |
284 | |
285 /* this function is only necessary because of an iarm compiler failure */ | |
286 LOCAL void bcs_clear_flag (UBYTE *ptr) | |
287 { | |
288 if (*ptr & 0x70) | |
289 *ptr &= 0x7F; | |
290 } | |
291 | |
292 LOCAL UBYTE bcs_decode(UBYTE idx_max) | |
293 { | |
294 T_sdu *sdu = (T_sdu*)t30_data->bcs_frm; | |
295 UBYTE idx; | |
296 | |
297 for (idx = 0; idx < idx_max; idx++) | |
298 { | |
299 USHORT begin = t30_data->frm[idx].beg + 2; | |
300 | |
301 /* set direction flag to zero for CCD decoding */ | |
302 bcs_clear_flag (sdu->buf + begin); | |
303 | |
304 /* set offset and length of current frame */ | |
305 sdu->o_buf = begin << 3; | |
306 sdu->l_buf = ((USHORT)(t30_data->frm[idx].len - 4) << 3); | |
307 | |
308 #ifdef _SIMULATION_ /* show contents of buffer */ | |
309 if (t30_data->test_mode /* & TST_BUF */) | |
310 { | |
311 ker_debug ("ccd_decode", &sdu->buf[begin], (USHORT)(sdu->l_buf >> 3)); | |
312 } | |
313 #endif | |
314 | |
315 if (ccd_decodeMsg(CCDENT_T30, DOWNLINK, (T_MSGBUF*)sdu, _decodedMsg, HDLC_ADDR) EQ ccdError) | |
316 { | |
317 TRACE_EVENT ("ERROR: ccd_decode"); | |
318 return CCD_ERR; | |
319 } | |
320 sig_bcs_ker_bdat_ind(); /* send signal to kernel */ | |
321 } | |
322 return CCD_OK; | |
323 } | |
324 | |
325 /* | |
326 +--------------------------------------------------------------------+ | |
327 | PROJECT : GSM-F&D (8411) MODULE : T30_BCSF | | |
328 | STATE : code ROUTINE : bcs_destuff | | |
329 +--------------------------------------------------------------------+ | |
330 | |
331 PURPOSE : This function de-stuffs the received BCS data. | |
332 */ | |
333 | |
334 LOCAL void bcs_destuff(UBYTE *flag_vector) | |
335 { | |
336 T_sdu *sdu = (T_sdu*)t30_data->bcs_frm; | |
337 SHORT bcs_tmp_len = 0; | |
338 SHORT ones = 0; | |
339 SHORT bits = 8; | |
340 UBYTE flag = 0; | |
341 UBYTE *bcs_tmp; | |
342 SHORT i; | |
343 | |
344 #ifdef _SIMULATION_ /* bit stuffing/destuffing OFF */ | |
345 if (t30_data->test_mode & TST_STUFF) | |
346 { | |
347 for (i = 0; i < sdu->l_buf; i++) | |
348 { | |
349 if (sdu->buf[i] EQ HDLC_FLAG) | |
350 flag_vector[i] = 1; | |
351 } | |
352 if (flag_vector[sdu->l_buf-1] NEQ 1) // trailing HDLC_FLAG is missed | |
353 { | |
354 sdu->l_buf++; | |
355 sdu->buf[sdu->l_buf-1] = HDLC_FLAG; | |
356 flag_vector[sdu->l_buf-1] = 1; | |
357 } | |
358 return; | |
359 } | |
360 #endif | |
361 | |
362 MALLOC(bcs_tmp, sdu->l_buf); | |
363 | |
364 for (i = 0 ; i < sdu->l_buf ; i++) | |
365 { | |
366 UBYTE bit_ptr = 0x80; /* points initially to MSB */ | |
367 | |
368 do /* check each byte for destuffing */ | |
369 { | |
370 if (sdu->buf[i] & bit_ptr) /* bit pointed to is 1 */ | |
371 { | |
372 ones++; | |
373 bcs_tmp[bcs_tmp_len] = (bcs_tmp[bcs_tmp_len] << 1) | 1; | |
374 flag = (flag << 1) | 1; | |
375 | |
376 if (! --bits) /* counter of byte's bits*/ | |
377 { | |
378 bcs_tmp_len++; | |
379 bits = 8; | |
380 } | |
381 } | |
382 else /* bit is 0 */ | |
383 { | |
384 if (ones != 5) | |
385 { | |
386 bcs_tmp[bcs_tmp_len] <<= 1; | |
387 flag <<= 1; | |
388 | |
389 if (ones EQ 6 && flag EQ HDLC_FLAG) | |
390 flag_vector[bcs_tmp_len] = 1; | |
391 | |
392 if (! --bits) /* whole byte is scanned */ | |
393 { | |
394 bcs_tmp_len++; | |
395 bits = 8; | |
396 } | |
397 } | |
398 ones = 0; | |
399 } | |
400 bit_ptr >>= 1; | |
401 } | |
402 while (bit_ptr); | |
403 } | |
404 /* copy destuffed BCS frame back to sdu */ | |
405 memcpy (sdu->buf, bcs_tmp, bcs_tmp_len); | |
406 MFREE(bcs_tmp); | |
407 | |
408 sdu->l_buf = bcs_tmp_len; /* adjust buffer length */ | |
409 if (flag_vector[sdu->l_buf-1] NEQ 1) // trailing HDLC_FLAG is missed | |
410 { | |
411 sdu->l_buf++; | |
412 sdu->buf[sdu->l_buf-1] = HDLC_FLAG; | |
413 flag_vector[sdu->l_buf-1] = 1; | |
414 } | |
415 } | |
416 | |
417 /* | |
418 +--------------------------------------------------------------------+ | |
419 | PROJECT : GSM-F&D (8411) MODULE : T30_BCSF | | |
420 | STATE : code ROUTINE : bcs_bcs_decode | | |
421 +--------------------------------------------------------------------+ | |
422 | |
423 PURPOSE : This function gets the frame positions, | |
424 checks the frames, | |
425 reports the contents to MMI if desired, | |
426 decodes the contents and sends the contents to the kernel. | |
427 */ | |
428 | |
429 GLOBAL void bcs_bcs_decode(void) | |
430 { | |
431 UBYTE *flag_vector, idx_max, ret; | |
432 | |
433 MALLOC(flag_vector, BCS_FRM_SIZE); | |
434 memset(flag_vector, 0, BCS_FRM_SIZE); | |
435 bcs_destuff(flag_vector); | |
436 ret = bcs_frame_pos(flag_vector, &idx_max); /* determines "idx_max" */ | |
437 MFREE(flag_vector); | |
438 | |
439 switch (ret) | |
440 { | |
441 case FRM_OK: | |
442 ret = bcs_check_frames(&idx_max); | |
443 if (t30_data->hdlc_report) | |
444 { | |
445 bcs_report_rcv(idx_max); | |
446 } | |
447 switch (ret) | |
448 { | |
449 case CHK_OK: | |
450 switch (bcs_decode(idx_max)) | |
451 { | |
452 case CCD_OK: | |
453 return; | |
454 | |
455 case CCD_ERR: | |
456 sig_bcs_ker_err_ind(ERR_CCD_DEC); | |
457 return; | |
458 } | |
459 break; /* dummy */ | |
460 | |
461 case CHK_FCS_ERR: | |
462 sig_bcs_ker_err_ind(ERR_FCS); | |
463 return; | |
464 | |
465 case CHK_FIN_ERR: | |
466 sig_bcs_ker_err_ind(ERR_FINAL); | |
467 return; | |
468 } | |
469 break; | |
470 | |
471 case FRM_ERR_NO_FLAG: | |
472 sig_bcs_ker_err_ind(ERR_FRAME_NO_FLAG); | |
473 return; | |
474 | |
475 case FRM_ERR_TOO_MANY_FRAMES: | |
476 sig_bcs_ker_err_ind(ERR_FRAME_TOO_MANY_FRAMES); | |
477 return; | |
478 } | |
479 } | |
480 | |
481 /* | |
482 +--------------------------------------------------------------------+ | |
483 | PROJECT : GSM-F&D (8411) MODULE : T30_BCSF | | |
484 | STATE : code ROUTINE : bcs_report_snd | | |
485 +--------------------------------------------------------------------+ | |
486 | |
487 PURPOSE : This function reports the sent HDLC frames to MMI | |
488 if desired. | |
489 */ | |
490 | |
491 LOCAL void bcs_report_snd(void) | |
492 { | |
493 T_sdu *BCI_stream = (T_sdu*)t30_data->BCI_stream; // Binary Coded Information | |
494 | |
495 PALLOC_SDU(t30_report_ind, T30_REPORT_IND, REPORT_SIZE_BITS); | |
496 | |
497 bcs_build_report(&BCI_stream->buf[0], (USHORT)((BCI_stream->l_buf >> 3) + 2), t30_report_ind); | |
498 t30_report_ind->dir = DIR_SND; | |
499 PSENDX (MMI, t30_report_ind); | |
500 } | |
501 | |
502 /* | |
503 +--------------------------------------------------------------------+ | |
504 | PROJECT : GSM-F&D (8411) MODULE : T30_BCSF | | |
505 | STATE : code ROUTINE : bcs_fcs_gen | | |
506 +--------------------------------------------------------------------+ | |
507 | |
508 PURPOSE : This function generates the frame checking sequence | |
509 for one HDLC frame. | |
510 */ | |
511 | |
512 LOCAL void bcs_fcs_gen (void) | |
513 { | |
514 T_sdu *sdu = (T_sdu*)t30_data->BCI_stream; | |
515 USHORT end = (sdu->l_buf >> 3) + 2; | |
516 USHORT pos; | |
517 UBYTE i; | |
518 | |
519 #ifdef _SIMULATION_ /* FCS generating/checking OFF */ | |
520 if (t30_data->test_mode & TST_FCS) | |
521 { | |
522 pos = end; | |
523 sdu->buf[pos++] = 0x12; | |
524 sdu->buf[pos++] = 0xEF; | |
525 } | |
526 else | |
527 #endif | |
528 { | |
529 USHORT crctt = 0xffff; | |
530 for (pos = 0; pos < end; pos++) | |
531 { | |
532 SHORT tmp = (crctt >> 8) ^ sdu->buf[pos]; | |
533 crctt = ((crctt << 8) ^ crctab[tmp & 0xff]) & 0xffff; | |
534 } | |
535 sdu->buf[pos++] = (~(crctt & 0xffff) & 0xffff) >> 8;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer)*/ | |
536 sdu->buf[pos++] = (~(crctt & 0xffff) & 0xff);/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer)*/ | |
537 } | |
538 | |
539 sdu->l_buf += 32; /* 4 bytes more */ | |
540 | |
541 for (i = 0; i < HDLC_FLAGS; i++) | |
542 { | |
543 sdu->buf[pos++] = HDLC_FLAG;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer)*/ | |
544 sdu->l_buf += 8; | |
545 } | |
546 sdu->o_buf = 0; | |
547 } | |
548 | |
549 /* | |
550 +--------------------------------------------------------------------+ | |
551 | PROJECT : GSM-F&D (8411) MODULE : T30_BCSF | | |
552 | STATE : code ROUTINE : bcs_stuff | | |
553 +--------------------------------------------------------------------+ | |
554 | |
555 PURPOSE : This function stuffs the BCS data. | |
556 */ | |
557 | |
558 LOCAL void bcs_stuff (UBYTE final) | |
559 { | |
560 T_sdu *sdu_inp = (T_sdu*)t30_data->BCI_stream; | |
561 T_sdu *sdu_out = &t30_data->fad_data_req->sdu; | |
562 | |
563 UBYTE *buf_in = sdu_inp->buf; | |
564 USHORT len_in = sdu_inp->l_buf >> 3; | |
565 UBYTE *buf_out; | |
566 USHORT len_out = sdu_out->l_buf >> 3; | |
567 USHORT i; | |
568 | |
569 #ifdef _SIMULATION_ /* bit stuffing/destuffing OFF */ | |
570 if (t30_data->test_mode & TST_STUFF) | |
571 { | |
572 buf_out = &sdu_out->buf[len_out]; | |
573 memcpy (buf_out, buf_in, len_in); | |
574 sdu_out->l_buf = (len_out + len_in) << 3; | |
575 return; | |
576 } | |
577 #endif | |
578 | |
579 buf_out = sdu_out->buf; | |
580 | |
581 for (i = 0; i < len_in; i++) | |
582 { | |
583 USHORT bit_ptr = 0x80; | |
584 UBYTE stuff = 1; | |
585 /* | |
586 check HDLC_FLAGS | |
587 */ | |
588 if (buf_in[i] EQ HDLC_FLAG) | |
589 { | |
590 USHORT k; | |
591 for (k = 0; k < HDLC_FLAGS; k++) | |
592 { | |
593 if (i EQ len_in - k - 1) | |
594 { | |
595 stuff = 0; | |
596 break; | |
597 } | |
598 } | |
599 } | |
600 do | |
601 { | |
602 switch (buf_in[i] & bit_ptr) | |
603 { | |
604 default: | |
605 buf_out[len_out] = (buf_out[len_out] << 1) | 1; | |
606 if (! --t30_data->stuff_bits) | |
607 { | |
608 len_out++; | |
609 t30_data->stuff_bits = 8; | |
610 } | |
611 if (!stuff) | |
612 { | |
613 t30_data->stuff_ones = 0; | |
614 break; | |
615 } | |
616 if (++t30_data->stuff_ones != 5) | |
617 break; | |
618 /* | |
619 * otherwise fall through | |
620 */ | |
621 | |
622 case 0: | |
623 buf_out[len_out] <<= 1; | |
624 t30_data->stuff_ones = 0; | |
625 | |
626 if (! --t30_data->stuff_bits) | |
627 { | |
628 len_out++; | |
629 t30_data->stuff_bits = 8; | |
630 } | |
631 break; | |
632 } | |
633 bit_ptr >>= 1; | |
634 } while (bit_ptr); | |
635 } | |
636 | |
637 if (final EQ FINAL_YES AND t30_data->stuff_bits NEQ 8) | |
638 { | |
639 buf_out[len_out] <<= t30_data->stuff_bits; | |
640 len_out++; | |
641 } | |
642 | |
643 sdu_out->l_buf = len_out << 3; | |
644 | |
645 if (final EQ FINAL_YES) | |
646 { | |
647 t30_data->stuff_ones = 0; | |
648 t30_data->stuff_bits = 8; | |
649 } | |
650 } | |
651 | |
652 /* | |
653 +--------------------------------------------------------------------+ | |
654 | PROJECT : GSM-F&D (8411) MODULE : T30_BCSF | | |
655 | STATE : code ROUTINE : bcs_bcs_encode | | |
656 +--------------------------------------------------------------------+ | |
657 | |
658 PURPOSE : This function encodes the HDLC frames, | |
659 reports the HDLC frames to MMI if desired, | |
660 generates the frame checking sequence and stuffs the bits. | |
661 */ | |
662 | |
663 GLOBAL void bcs_bcs_encode(UBYTE ctrl, UBYTE final) | |
664 { | |
665 T_sdu *sdu = (T_sdu*)t30_data->BCI_stream; | |
666 | |
667 switch (sdu->buf[2])/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
668 { | |
669 case BCS_DIS: | |
670 TRACE_EVENT ("Send BCS_DIS"); | |
671 break; | |
672 case BCS_CSI: | |
673 TRACE_EVENT ("Send BCS_CSI"); | |
674 break; | |
675 case BCS_NSF: | |
676 TRACE_EVENT ("Send BCS_NSF"); | |
677 break; | |
678 case BCS_DTC: | |
679 TRACE_EVENT ("Send BCS_DTC"); | |
680 break; | |
681 case BCS_CIG: | |
682 TRACE_EVENT ("Send BCS_CIG"); | |
683 break; | |
684 case BCS_NSC: | |
685 TRACE_EVENT ("Send BCS_NSC"); | |
686 break; | |
687 case BCS_PWD_POLL: | |
688 TRACE_EVENT ("Send BCS_PWD_POLL"); | |
689 break; | |
690 case BCS_SEP: | |
691 TRACE_EVENT ("Send BCS_SEP"); | |
692 break; | |
693 | |
694 case BCS_CFR: | |
695 TRACE_EVENT ("Send BCS_CFR"); | |
696 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
697 break; | |
698 case BCS_CRP: | |
699 TRACE_EVENT ("Send BCS_CRP"); | |
700 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
701 break; | |
702 case BCS_DCN: | |
703 TRACE_EVENT ("Send BCS_DCN"); | |
704 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
705 break; | |
706 case BCS_DCS: | |
707 TRACE_EVENT ("Send BCS_DCS"); | |
708 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
709 break; | |
710 case BCS_EOM: | |
711 TRACE_EVENT ("Send BCS_EOM"); | |
712 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
713 break; | |
714 case BCS_EOP: | |
715 TRACE_EVENT ("Send BCS_EOP"); | |
716 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
717 break; | |
718 case BCS_FTT: | |
719 TRACE_EVENT ("Send BCS_FTT"); | |
720 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
721 break; | |
722 case BCS_MCF: | |
723 TRACE_EVENT ("Send BCS_MCF"); | |
724 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
725 break; | |
726 case BCS_MPS: | |
727 TRACE_EVENT ("Send BCS_MPS"); | |
728 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
729 break; | |
730 case BCS_NSS: | |
731 TRACE_EVENT ("Send BCS_NSS"); | |
732 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
733 break; | |
734 case BCS_PIN: | |
735 TRACE_EVENT ("Send BCS_PIN"); | |
736 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
737 break; | |
738 case BCS_PIP: | |
739 TRACE_EVENT ("Send BCS_PIP"); | |
740 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
741 break; | |
742 case BCS_PRI_EOM: | |
743 TRACE_EVENT ("Send BCS_PRI_EOM"); | |
744 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
745 break; | |
746 case BCS_PRI_EOP: | |
747 TRACE_EVENT ("Send BCS_PRI_EOP"); | |
748 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
749 break; | |
750 case BCS_PRI_MPS: | |
751 TRACE_EVENT ("Send BCS_PRI_MPS"); | |
752 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
753 break; | |
754 case BCS_PWD_SND: | |
755 TRACE_EVENT ("Send BCS_PWD_SND"); | |
756 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
757 break; | |
758 case BCS_RTN: | |
759 TRACE_EVENT ("Send BCS_RTN"); | |
760 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
761 break; | |
762 case BCS_RTP: | |
763 TRACE_EVENT ("Send BCS_RTP"); | |
764 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
765 break; | |
766 case BCS_SUB: | |
767 TRACE_EVENT ("Send BCS_SUB"); | |
768 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
769 break; | |
770 case BCS_TSI: | |
771 TRACE_EVENT ("Send BCS_TSI"); | |
772 sdu->buf[2] |= t30_data->dir;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer)*/ | |
773 break; | |
774 } | |
775 | |
776 sdu->buf[0] = HDLC_ADDR; | |
777 sdu->buf[1] = ctrl;/*lint !e415 (Warning -- access of out-of-bounds pointer)*/ | |
778 | |
779 if (t30_data->hdlc_report) | |
780 { | |
781 bcs_report_snd(); | |
782 } | |
783 bcs_fcs_gen(); | |
784 bcs_stuff(final); | |
785 } | |
786 | |
787 /* | |
788 +--------------------------------------------------------------------+ | |
789 | PROJECT : GSM-F&D (8411) MODULE : T30_BCSF | | |
790 | STATE : code ROUTINE : bcs_fill_bcs_frm | | |
791 +--------------------------------------------------------------------+ | |
792 | |
793 PURPOSE : This function checks if the BCS frame buffer has enough | |
794 space to append the received data. | |
795 If there is enough space the data is appended. | |
796 If not than BCS_FRM_FULL is returned. | |
797 | |
798 */ | |
799 | |
800 GLOBAL UBYTE bcs_fill_bcs_frm (T_FAD_DATA_IND *fad_data_ind) | |
801 { | |
802 USHORT data_len = fad_data_ind->sdu.l_buf >> 3; | |
803 T_sdu *sdu = (T_sdu*)t30_data->bcs_frm; | |
804 | |
805 TRACE_FUNCTION("bcs_fill_bcs_frm()"); | |
806 | |
807 if (sdu->l_buf + data_len < BCS_FRM_SIZE) | |
808 { | |
809 memcpy (&sdu->buf[sdu->l_buf], fad_data_ind->sdu.buf, data_len); | |
810 sdu->l_buf += data_len; | |
811 return ((fad_data_ind->final) ? BCS_FRM_FILLED : BCS_FRM_FILLING); | |
812 } | |
813 else | |
814 { | |
815 sdu->l_buf = BCS_FRM_SIZE; | |
816 return (BCS_FRM_FULL); | |
817 } | |
818 } | |
819 |