comparison spandsp-0.0.3/spandsp-0.0.3/src/hdlc.c @ 5:f762bf195c4b

import spandsp-0.0.3
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 16:00:21 +0200
parents
children
comparison
equal deleted inserted replaced
4:26cd8f1ef0b1 5:f762bf195c4b
1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * hdlc.c
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2003 Steve Underwood
9 *
10 * All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2, as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * $Id: hdlc.c,v 1.44 2006/11/28 16:59:56 steveu Exp $
26 */
27
28 /*! \file */
29
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33
34 #include <inttypes.h>
35 #include <stdio.h>
36 #include <string.h>
37
38 #include "spandsp/telephony.h"
39 #include "spandsp/power_meter.h"
40 #include "spandsp/async.h"
41 #include "spandsp/hdlc.h"
42 #include "spandsp/fsk.h"
43 #include "spandsp/bit_operations.h"
44
45 #include "spandsp/timing.h"
46
47 static const uint32_t crc_itu32_table[] =
48 {
49 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
50 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
51 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
52 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
53 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
54 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
55 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
56 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
57 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
58 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
59 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
60 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
61 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
62 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
63 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
64 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
65 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
66 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
67 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
68 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
69 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
70 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
71 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
72 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
73 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
74 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
75 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
76 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
77 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
78 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
79 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
80 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
81 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
82 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
83 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
84 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
85 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
86 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
87 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
88 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
89 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
90 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
91 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
92 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
93 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
94 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
95 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
96 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
97 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
98 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
99 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
100 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
101 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
102 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
103 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
104 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
105 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
106 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
107 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
108 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
109 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
110 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
111 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
112 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
113 };
114
115 uint32_t crc_itu32_calc(const uint8_t *buf, int len, uint32_t crc)
116 {
117 int i;
118
119 for (i = 0; i < len; i++)
120 crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_itu32_table[(crc ^ buf[i]) & 0xFF];
121 return crc;
122 }
123 /*- End of function --------------------------------------------------------*/
124
125 int crc_itu32_append(uint8_t *buf, int len)
126 {
127 uint32_t crc;
128 int new_len;
129 int i;
130
131 crc = 0xFFFFFFFF;
132 new_len = len + 4;
133 for (i = 0; i < len; i++)
134 crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_itu32_table[(crc ^ buf[i]) & 0xFF];
135 crc ^= 0xFFFFFFFF;
136 buf[i++] = (uint8_t) crc;
137 buf[i++] = (uint8_t) (crc >> 8);
138 buf[i++] = (uint8_t) (crc >> 16);
139 buf[i++] = (uint8_t) (crc >> 24);
140 return new_len;
141 }
142 /*- End of function --------------------------------------------------------*/
143
144 int crc_itu32_check(const uint8_t *buf, int len)
145 {
146 uint32_t crc;
147 int i;
148
149 crc = 0xFFFFFFFF;
150 for (i = 0; i < len; i++)
151 crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_itu32_table[(crc ^ buf[i]) & 0xFF];
152 return (crc == 0xDEBB20E3);
153 }
154 /*- End of function --------------------------------------------------------*/
155
156 static const uint16_t crc_itu16_table[] =
157 {
158 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
159 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
160 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
161 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
162 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
163 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
164 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
165 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
166 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
167 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
168 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
169 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
170 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
171 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
172 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
173 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
174 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
175 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
176 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
177 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
178 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
179 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
180 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
181 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
182 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
183 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
184 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
185 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
186 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
187 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
188 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
189 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
190 };
191
192 uint16_t crc_itu16_calc(const uint8_t *buf, int len, uint16_t crc)
193 {
194 int i;
195
196 for (i = 0; i < len; i++)
197 crc = (crc >> 8) ^ crc_itu16_table[(crc ^ buf[i]) & 0xFF];
198 return crc;
199 }
200 /*- End of function --------------------------------------------------------*/
201
202 int crc_itu16_append(uint8_t *buf, int len)
203 {
204 uint16_t crc;
205 int new_len;
206 int i;
207
208 crc = 0xFFFF;
209 new_len = len + 2;
210 for (i = 0; i < len; i++)
211 crc = (crc >> 8) ^ crc_itu16_table[(crc ^ buf[i]) & 0xFF];
212 crc ^= 0xFFFF;
213 buf[i++] = (uint8_t) crc;
214 buf[i++] = (uint8_t) (crc >> 8);
215 return new_len;
216 }
217 /*- End of function --------------------------------------------------------*/
218
219 int crc_itu16_check(const uint8_t *buf, int len)
220 {
221 uint16_t crc;
222 int i;
223
224 crc = 0xFFFF;
225 for (i = 0; i < len; i++)
226 crc = (crc >> 8) ^ crc_itu16_table[(crc ^ buf[i]) & 0xFF];
227 return (crc & 0xFFFF) == 0xF0B8;
228 }
229 /*- End of function --------------------------------------------------------*/
230
231 static void rx_special_condition(hdlc_rx_state_t *s, int condition)
232 {
233 /* Special conditions */
234 switch (condition)
235 {
236 case PUTBIT_CARRIER_UP:
237 case PUTBIT_TRAINING_SUCCEEDED:
238 /* Reset the HDLC receiver. */
239 s->len = 0;
240 s->num_bits = 0;
241 s->flags_seen = 0;
242 s->framing_ok_announced = FALSE;
243 /* Fall through */
244 case PUTBIT_CARRIER_DOWN:
245 case PUTBIT_TRAINING_FAILED:
246 case PUTBIT_END_OF_DATA:
247 s->frame_handler(s->user_data, TRUE, NULL, condition);
248 break;
249 default:
250 //printf("Eh!\n");
251 break;
252 }
253 }
254 /*- End of function --------------------------------------------------------*/
255
256 static void rx_flag_or_abort(hdlc_rx_state_t *s)
257 {
258 if ((s->raw_bit_stream & 0x8000))
259 {
260 /* Hit HDLC abort */
261 s->rx_aborts++;
262 s->frame_handler(s->user_data, TRUE, NULL, PUTBIT_ABORT);
263 if (s->flags_seen < s->framing_ok_threshold)
264 s->flags_seen = 0;
265 }
266 else
267 {
268 /* Hit HDLC flag */
269 if (s->flags_seen >= s->framing_ok_threshold)
270 {
271 /* Announce framing OK between frames. */
272 if (!s->framing_ok_announced)
273 {
274 s->frame_handler(s->user_data, TRUE, NULL, PUTBIT_FRAMING_OK);
275 s->framing_ok_announced = TRUE;
276 }
277 /* We may have a frame, or we may have back to back flags */
278 if (s->len)
279 {
280 if (s->len >= s->crc_bytes && s->len <= (int) sizeof(s->buffer))
281 {
282 if ((s->crc_bytes == 2 && crc_itu16_check(s->buffer, s->len))
283 ||
284 (s->crc_bytes != 2 && crc_itu32_check(s->buffer, s->len)))
285 {
286 s->rx_frames++;
287 s->rx_bytes += s->len - s->crc_bytes;
288 s->frame_handler(s->user_data,
289 TRUE,
290 s->buffer,
291 s->len - s->crc_bytes);
292 }
293 else
294 {
295 s->rx_crc_errors++;
296 if (s->report_bad_frames)
297 {
298 s->frame_handler(s->user_data,
299 FALSE,
300 s->buffer,
301 s->len - s->crc_bytes);
302 }
303 }
304 s->framing_ok_announced = FALSE;
305 }
306 else
307 {
308 /* Frame too short or too long */
309 if (s->report_bad_frames)
310 {
311 s->frame_handler(s->user_data,
312 FALSE,
313 s->buffer,
314 s->len - s->crc_bytes);
315 }
316 s->rx_length_errors++;
317 }
318 }
319 }
320 else
321 {
322 /* Check the flags are back-to-back when testing for valid preamble. This
323 greatly reduces the chances of false preamble detection, and anything
324 which doesn't send them back-to-back is badly broken. */
325 if (s->flags_seen && s->num_bits != 7)
326 s->flags_seen = 0;
327 if (++s->flags_seen == s->framing_ok_threshold && !s->framing_ok_announced)
328 {
329 s->frame_handler(s->user_data, TRUE, NULL, PUTBIT_FRAMING_OK);
330 s->framing_ok_announced = TRUE;
331 }
332 }
333 }
334 s->len = 0;
335 s->num_bits = 0;
336 }
337 /*- End of function --------------------------------------------------------*/
338
339 void hdlc_rx_put_bit(hdlc_rx_state_t *s, int new_bit)
340 {
341 if (new_bit < 0)
342 {
343 rx_special_condition(s, new_bit);
344 return;
345 }
346 s->raw_bit_stream = (s->raw_bit_stream << 1) | ((new_bit << 8) & 0x100);
347 if ((s->raw_bit_stream & 0x3F00) == 0x3E00)
348 {
349 if ((s->raw_bit_stream & 0x4000))
350 {
351 rx_flag_or_abort(s);
352 }
353 else
354 {
355 if (s->flags_seen < s->framing_ok_threshold)
356 s->num_bits++;
357 }
358 }
359 else
360 {
361 s->num_bits++;
362 if (s->flags_seen >= s->framing_ok_threshold)
363 {
364 s->byte_in_progress = (s->byte_in_progress | (s->raw_bit_stream & 0x100)) >> 1;
365 if (s->num_bits == 8)
366 {
367 /* Ensure we do not overflow our buffer */
368 if (s->len < (int) sizeof(s->buffer))
369 s->buffer[s->len++] = (uint8_t) s->byte_in_progress;
370 else
371 s->len = (int) sizeof(s->buffer) + 1;
372 s->num_bits = 0;
373 }
374 }
375 }
376 }
377 /*- End of function --------------------------------------------------------*/
378
379 void hdlc_rx_put_byte(hdlc_rx_state_t *s, int new_byte)
380 {
381 int i;
382
383 if (new_byte < 0)
384 {
385 rx_special_condition(s, new_byte);
386 return;
387 }
388 s->raw_bit_stream |= new_byte;
389
390 i = 0;
391 if (s->flags_seen < s->framing_ok_threshold)
392 {
393 for ( ; i < 8; i++)
394 {
395 s->raw_bit_stream <<= 1;
396 if ((s->raw_bit_stream & 0x7F00) == 0x7E00)
397 {
398 rx_flag_or_abort(s);
399 if (s->flags_seen >= s->framing_ok_threshold)
400 {
401 i++;
402 break;
403 }
404 }
405 else
406 {
407 s->num_bits++;
408 }
409 }
410 }
411 for ( ; i < 8; i++)
412 {
413 s->raw_bit_stream <<= 1;
414 if ((s->raw_bit_stream & 0x3F00) == 0x3E00)
415 {
416 if ((s->raw_bit_stream & 0x4000))
417 rx_flag_or_abort(s);
418 }
419 else
420 {
421 s->byte_in_progress = (s->byte_in_progress | (s->raw_bit_stream & 0x100)) >> 1;
422 if (++s->num_bits == 8)
423 {
424 /* Ensure we do not overflow our buffer */
425 if (s->len < (int) sizeof(s->buffer))
426 s->buffer[s->len++] = (uint8_t) s->byte_in_progress;
427 else
428 s->len = (int) sizeof(s->buffer) + 1;
429 s->num_bits = 0;
430 }
431 }
432 }
433 }
434 /*- End of function --------------------------------------------------------*/
435
436 int hdlc_tx_frame(hdlc_tx_state_t *s, const uint8_t *frame, int len)
437 {
438 if (len <= 0)
439 {
440 s->tx_end = TRUE;
441 return 0;
442 }
443 if (s->len + len > s->max_frame_len)
444 return -1;
445 if (s->progressive)
446 {
447 /* Only lock out if we are in the CRC section. */
448 if (s->pos >= HDLC_MAXFRAME_LEN)
449 return -1;
450 }
451 else
452 {
453 /* Lock out if there is anything in the buffer. */
454 if (s->len)
455 return -1;
456 }
457 memcpy(s->buffer + s->len, frame, len);
458 if (s->crc_bytes == 2)
459 s->crc = crc_itu16_calc(frame, len, (uint16_t) s->crc);
460 else
461 s->crc = crc_itu32_calc(frame, len, s->crc);
462 if (s->progressive)
463 s->len += len;
464 else
465 s->len = len;
466 s->tx_end = FALSE;
467 return 0;
468 }
469 /*- End of function --------------------------------------------------------*/
470
471 int hdlc_tx_preamble(hdlc_tx_state_t *s, int len)
472 {
473 /* Some HDLC applications require the ability to force a period of HDLC
474 flag words. */
475 if (s->pos)
476 return -1;
477 if (len < 0)
478 s->flag_octets += -len;
479 else
480 s->flag_octets = len;
481 s->report_flag_underflow = TRUE;
482 s->tx_end = FALSE;
483 return 0;
484 }
485 /*- End of function --------------------------------------------------------*/
486
487 int hdlc_tx_corrupt_frame(hdlc_tx_state_t *s)
488 {
489 if (s->len <= 0)
490 return -1;
491 s->crc ^= 0xFFFF;
492 s->buffer[HDLC_MAXFRAME_LEN] ^= 0xFF;
493 s->buffer[HDLC_MAXFRAME_LEN + 1] ^= 0xFF;
494 s->buffer[HDLC_MAXFRAME_LEN + 2] ^= 0xFF;
495 s->buffer[HDLC_MAXFRAME_LEN + 3] ^= 0xFF;
496 return 0;
497 }
498 /*- End of function --------------------------------------------------------*/
499
500 int hdlc_tx_get_byte(hdlc_tx_state_t *s)
501 {
502 int i;
503 int byte_in_progress;
504 int txbyte;
505
506 if (s->flag_octets > 0)
507 {
508 /* We are in a timed flag section (preamble, inter frame gap, etc.) */
509 if (--s->flag_octets <= 0 && s->report_flag_underflow)
510 {
511 if (s->len == 0)
512 {
513 /* The timed preamble has finished, there is nothing else queued to go,
514 and we have been told to report this underflow. */
515 if (s->underflow_handler)
516 s->underflow_handler(s->user_data);
517 }
518 s->report_flag_underflow = FALSE;
519 }
520 return s->idle_octet;
521 }
522 if (s->len)
523 {
524 if (s->num_bits >= 8)
525 {
526 s->num_bits -= 8;
527 return (s->octets_in_progress >> s->num_bits) & 0xFF;
528 }
529 if (s->pos >= s->len)
530 {
531 if (s->pos == s->len)
532 {
533 s->crc ^= 0xFFFFFFFF;
534 s->buffer[HDLC_MAXFRAME_LEN] = (uint8_t) s->crc;
535 s->buffer[HDLC_MAXFRAME_LEN + 1] = (uint8_t) (s->crc >> 8);
536 if (s->crc_bytes == 4)
537 {
538 s->buffer[HDLC_MAXFRAME_LEN + 2] = (uint8_t) (s->crc >> 16);
539 s->buffer[HDLC_MAXFRAME_LEN + 3] = (uint8_t) (s->crc >> 24);
540 }
541 s->pos = HDLC_MAXFRAME_LEN;
542 }
543 else if (s->pos == HDLC_MAXFRAME_LEN + s->crc_bytes)
544 {
545 /* Finish off the current byte with some flag bits. If we are at the
546 start of a byte we need a at least one whole byte of flag to ensure
547 we cannot end up with back to back frames, and no flag octet at all */
548 txbyte = (uint8_t) ((s->octets_in_progress << (8 - s->num_bits)) | (0x7E >> s->num_bits));
549 /* Create a rotated octet of flag for idling... */
550 s->idle_octet = (0x7E7E >> s->num_bits) & 0xFF;
551 /* ...and the partial flag octet needed to start off the next message. */
552 s->octets_in_progress = s->idle_octet >> (8 - s->num_bits);
553 s->flag_octets = s->inter_frame_flags - 1;
554 s->len = 0;
555 s->pos = 0;
556 if (s->crc_bytes == 2)
557 s->crc = 0xFFFF;
558 else
559 s->crc = 0xFFFFFFFF;
560 /* Report the underflow now. If there is a timed preamble still in progress, loading the
561 next frame right now will be harmless. */
562 s->report_flag_underflow = FALSE;
563 if (s->underflow_handler)
564 s->underflow_handler(s->user_data);
565 /* Make sure we finish off with at least one flag octet, if the underflow report did not result
566 in a new frame being sent. */
567 if (s->len == 0 && s->flag_octets < 2)
568 s->flag_octets = 2;
569 return txbyte;
570 }
571 }
572 byte_in_progress = s->buffer[s->pos++];
573 i = bottom_bit(byte_in_progress | 0x100);
574 s->octets_in_progress <<= i;
575 byte_in_progress >>= i;
576 for ( ; i < 8; i++)
577 {
578 s->octets_in_progress = (s->octets_in_progress << 1) | (byte_in_progress & 0x01);
579 byte_in_progress >>= 1;
580 if ((s->octets_in_progress & 0x1F) == 0x1F)
581 {
582 /* There are 5 ones - stuff */
583 s->octets_in_progress <<= 1;
584 s->num_bits++;
585 }
586 }
587 /* An input byte will generate between 8 and 10 output bits */
588 return (s->octets_in_progress >> s->num_bits) & 0xFF;
589 }
590 /* Untimed idling on flags */
591 if (s->tx_end)
592 {
593 s->tx_end = FALSE;
594 return PUTBIT_END_OF_DATA;
595 }
596 return s->idle_octet;
597 }
598 /*- End of function --------------------------------------------------------*/
599
600 int hdlc_tx_get_bit(hdlc_tx_state_t *s)
601 {
602 int txbit;
603
604 if (s->bits == 0)
605 {
606 if ((s->byte = hdlc_tx_get_byte(s)) < 0)
607 return s->byte;
608 s->bits = 8;
609 }
610 s->bits--;
611 txbit = (s->byte >> s->bits) & 0x01;
612 return txbit;
613 }
614 /*- End of function --------------------------------------------------------*/
615
616 hdlc_rx_state_t *hdlc_rx_init(hdlc_rx_state_t *s,
617 int crc32,
618 int report_bad_frames,
619 int framing_ok_threshold,
620 hdlc_frame_handler_t handler,
621 void *user_data)
622 {
623 memset(s, 0, sizeof(*s));
624 s->frame_handler = handler;
625 s->user_data = user_data;
626 s->crc_bytes = (crc32) ? 4 : 2;
627 s->report_bad_frames = report_bad_frames;
628 s->framing_ok_threshold = (framing_ok_threshold < 1) ? 1 : framing_ok_threshold;
629 return s;
630 }
631 /*- End of function --------------------------------------------------------*/
632
633 int hdlc_rx_get_stats(hdlc_rx_state_t *s,
634 hdlc_rx_stats_t *t)
635 {
636 t->bytes = s->rx_bytes;
637 t->good_frames = s->rx_frames;
638 t->crc_errors = s->rx_crc_errors;
639 t->length_errors = s->rx_length_errors;
640 t->aborts = s->rx_aborts;
641 return 0;
642 }
643 /*- End of function --------------------------------------------------------*/
644
645 void hdlc_tx_set_max_frame_len(hdlc_tx_state_t *s, int max_len)
646 {
647 s->max_frame_len = (max_len <= HDLC_MAXFRAME_LEN) ? max_len : HDLC_MAXFRAME_LEN;
648 }
649 /*- End of function --------------------------------------------------------*/
650
651 hdlc_tx_state_t *hdlc_tx_init(hdlc_tx_state_t *s,
652 int crc32,
653 int inter_frame_flags,
654 int progressive,
655 hdlc_underflow_handler_t handler,
656 void *user_data)
657 {
658 memset(s, 0, sizeof(*s));
659 s->idle_octet = 0x7E;
660 s->underflow_handler = handler;
661 s->user_data = user_data;
662 s->inter_frame_flags = (inter_frame_flags < 1) ? 1 : inter_frame_flags;
663 if (crc32)
664 {
665 s->crc_bytes = 4;
666 s->crc = 0xFFFFFFFF;
667 }
668 else
669 {
670 s->crc_bytes = 2;
671 s->crc = 0xFFFF;
672 }
673 s->progressive = progressive;
674 s->max_frame_len = HDLC_MAXFRAME_LEN;
675 return s;
676 }
677 /*- End of function --------------------------------------------------------*/
678 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.