comparison src/g23m-fad/t30/t30_bcsf.c @ 1:d393cd9bb723

src/g23m-*: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:40:46 +0000
parents
children
comparison
equal deleted inserted replaced
0:b6a5e36de839 1:d393cd9bb723
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