root/drivers/isdn/hardware/mISDN/isdnhdlc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. isdnhdlc_rcv_init
  2. isdnhdlc_out_init
  3. check_frame
  4. isdnhdlc_decode
  5. isdnhdlc_encode

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * isdnhdlc.c  --  General purpose ISDN HDLC decoder.
   4  *
   5  * Copyright (C)
   6  *      2009    Karsten Keil            <keil@b1-systems.de>
   7  *      2002    Wolfgang Mües          <wolfgang@iksw-muees.de>
   8  *      2001    Frode Isaksen           <fisaksen@bewan.com>
   9  *      2001    Kai Germaschewski       <kai.germaschewski@gmx.de>
  10  */
  11 
  12 #include <linux/module.h>
  13 #include <linux/init.h>
  14 #include <linux/crc-ccitt.h>
  15 #include <linux/bitrev.h>
  16 #include "isdnhdlc.h"
  17 
  18 /*-------------------------------------------------------------------*/
  19 
  20 MODULE_AUTHOR("Wolfgang Mües <wolfgang@iksw-muees.de>, "
  21               "Frode Isaksen <fisaksen@bewan.com>, "
  22               "Kai Germaschewski <kai.germaschewski@gmx.de>");
  23 MODULE_DESCRIPTION("General purpose ISDN HDLC decoder");
  24 MODULE_LICENSE("GPL");
  25 
  26 /*-------------------------------------------------------------------*/
  27 
  28 enum {
  29         HDLC_FAST_IDLE, HDLC_GET_FLAG_B0, HDLC_GETFLAG_B1A6, HDLC_GETFLAG_B7,
  30         HDLC_GET_DATA, HDLC_FAST_FLAG
  31 };
  32 
  33 enum {
  34         HDLC_SEND_DATA, HDLC_SEND_CRC1, HDLC_SEND_FAST_FLAG,
  35         HDLC_SEND_FIRST_FLAG, HDLC_SEND_CRC2, HDLC_SEND_CLOSING_FLAG,
  36         HDLC_SEND_IDLE1, HDLC_SEND_FAST_IDLE, HDLC_SENDFLAG_B0,
  37         HDLC_SENDFLAG_B1A6, HDLC_SENDFLAG_B7, STOPPED, HDLC_SENDFLAG_ONE
  38 };
  39 
  40 void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features)
  41 {
  42         memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
  43         hdlc->state = HDLC_GET_DATA;
  44         if (features & HDLC_56KBIT)
  45                 hdlc->do_adapt56 = 1;
  46         if (features & HDLC_BITREVERSE)
  47                 hdlc->do_bitreverse = 1;
  48 }
  49 EXPORT_SYMBOL(isdnhdlc_out_init);
  50 
  51 void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features)
  52 {
  53         memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
  54         if (features & HDLC_DCHANNEL) {
  55                 hdlc->dchannel = 1;
  56                 hdlc->state = HDLC_SEND_FIRST_FLAG;
  57         } else {
  58                 hdlc->dchannel = 0;
  59                 hdlc->state = HDLC_SEND_FAST_FLAG;
  60                 hdlc->ffvalue = 0x7e;
  61         }
  62         hdlc->cbin = 0x7e;
  63         if (features & HDLC_56KBIT) {
  64                 hdlc->do_adapt56 = 1;
  65                 hdlc->state = HDLC_SENDFLAG_B0;
  66         } else
  67                 hdlc->data_bits = 8;
  68         if (features & HDLC_BITREVERSE)
  69                 hdlc->do_bitreverse = 1;
  70 }
  71 EXPORT_SYMBOL(isdnhdlc_rcv_init);
  72 
  73 static int
  74 check_frame(struct isdnhdlc_vars *hdlc)
  75 {
  76         int status;
  77 
  78         if (hdlc->dstpos < 2)   /* too small - framing error */
  79                 status = -HDLC_FRAMING_ERROR;
  80         else if (hdlc->crc != 0xf0b8)   /* crc error */
  81                 status = -HDLC_CRC_ERROR;
  82         else {
  83                 /* remove CRC */
  84                 hdlc->dstpos -= 2;
  85                 /* good frame */
  86                 status = hdlc->dstpos;
  87         }
  88         return status;
  89 }
  90 
  91 /*
  92   isdnhdlc_decode - decodes HDLC frames from a transparent bit stream.
  93 
  94   The source buffer is scanned for valid HDLC frames looking for
  95   flags (01111110) to indicate the start of a frame. If the start of
  96   the frame is found, the bit stuffing is removed (0 after 5 1's).
  97   When a new flag is found, the complete frame has been received
  98   and the CRC is checked.
  99   If a valid frame is found, the function returns the frame length
 100   excluding the CRC with the bit HDLC_END_OF_FRAME set.
 101   If the beginning of a valid frame is found, the function returns
 102   the length.
 103   If a framing error is found (too many 1s and not a flag) the function
 104   returns the length with the bit HDLC_FRAMING_ERROR set.
 105   If a CRC error is found the function returns the length with the
 106   bit HDLC_CRC_ERROR set.
 107   If the frame length exceeds the destination buffer size, the function
 108   returns the length with the bit HDLC_LENGTH_ERROR set.
 109 
 110   src - source buffer
 111   slen - source buffer length
 112   count - number of bytes removed (decoded) from the source buffer
 113   dst _ destination buffer
 114   dsize - destination buffer size
 115   returns - number of decoded bytes in the destination buffer and status
 116   flag.
 117 */
 118 int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen,
 119                     int *count, u8 *dst, int dsize)
 120 {
 121         int status = 0;
 122 
 123         static const unsigned char fast_flag[] = {
 124                 0x00, 0x00, 0x00, 0x20, 0x30, 0x38, 0x3c, 0x3e, 0x3f
 125         };
 126 
 127         static const unsigned char fast_flag_value[] = {
 128                 0x00, 0x7e, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f
 129         };
 130 
 131         static const unsigned char fast_abort[] = {
 132                 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
 133         };
 134 
 135 #define handle_fast_flag(h)                                             \
 136         do {                                                            \
 137                 if (h->cbin == fast_flag[h->bit_shift]) {               \
 138                         h->ffvalue = fast_flag_value[h->bit_shift];     \
 139                         h->state = HDLC_FAST_FLAG;                      \
 140                         h->ffbit_shift = h->bit_shift;                  \
 141                         h->bit_shift = 1;                               \
 142                 } else {                                                \
 143                         h->state = HDLC_GET_DATA;                       \
 144                         h->data_received = 0;                           \
 145                 }                                                       \
 146         } while (0)
 147 
 148 #define handle_abort(h)                                         \
 149         do {                                                    \
 150                 h->shift_reg = fast_abort[h->ffbit_shift - 1];  \
 151                 h->hdlc_bits1 = h->ffbit_shift - 2;             \
 152                 if (h->hdlc_bits1 < 0)                          \
 153                         h->hdlc_bits1 = 0;                      \
 154                 h->data_bits = h->ffbit_shift - 1;              \
 155                 h->state = HDLC_GET_DATA;                       \
 156                 h->data_received = 0;                           \
 157         } while (0)
 158 
 159         *count = slen;
 160 
 161         while (slen > 0) {
 162                 if (hdlc->bit_shift == 0) {
 163                         /* the code is for bitreverse streams */
 164                         if (hdlc->do_bitreverse == 0)
 165                                 hdlc->cbin = bitrev8(*src++);
 166                         else
 167                                 hdlc->cbin = *src++;
 168                         slen--;
 169                         hdlc->bit_shift = 8;
 170                         if (hdlc->do_adapt56)
 171                                 hdlc->bit_shift--;
 172                 }
 173 
 174                 switch (hdlc->state) {
 175                 case STOPPED:
 176                         return 0;
 177                 case HDLC_FAST_IDLE:
 178                         if (hdlc->cbin == 0xff) {
 179                                 hdlc->bit_shift = 0;
 180                                 break;
 181                         }
 182                         hdlc->state = HDLC_GET_FLAG_B0;
 183                         hdlc->hdlc_bits1 = 0;
 184                         hdlc->bit_shift = 8;
 185                         break;
 186                 case HDLC_GET_FLAG_B0:
 187                         if (!(hdlc->cbin & 0x80)) {
 188                                 hdlc->state = HDLC_GETFLAG_B1A6;
 189                                 hdlc->hdlc_bits1 = 0;
 190                         } else {
 191                                 if ((!hdlc->do_adapt56) &&
 192                                     (++hdlc->hdlc_bits1 >= 8) &&
 193                                     (hdlc->bit_shift == 1))
 194                                         hdlc->state = HDLC_FAST_IDLE;
 195                         }
 196                         hdlc->cbin <<= 1;
 197                         hdlc->bit_shift--;
 198                         break;
 199                 case HDLC_GETFLAG_B1A6:
 200                         if (hdlc->cbin & 0x80) {
 201                                 hdlc->hdlc_bits1++;
 202                                 if (hdlc->hdlc_bits1 == 6)
 203                                         hdlc->state = HDLC_GETFLAG_B7;
 204                         } else
 205                                 hdlc->hdlc_bits1 = 0;
 206                         hdlc->cbin <<= 1;
 207                         hdlc->bit_shift--;
 208                         break;
 209                 case HDLC_GETFLAG_B7:
 210                         if (hdlc->cbin & 0x80) {
 211                                 hdlc->state = HDLC_GET_FLAG_B0;
 212                         } else {
 213                                 hdlc->state = HDLC_GET_DATA;
 214                                 hdlc->crc = 0xffff;
 215                                 hdlc->shift_reg = 0;
 216                                 hdlc->hdlc_bits1 = 0;
 217                                 hdlc->data_bits = 0;
 218                                 hdlc->data_received = 0;
 219                         }
 220                         hdlc->cbin <<= 1;
 221                         hdlc->bit_shift--;
 222                         break;
 223                 case HDLC_GET_DATA:
 224                         if (hdlc->cbin & 0x80) {
 225                                 hdlc->hdlc_bits1++;
 226                                 switch (hdlc->hdlc_bits1) {
 227                                 case 6:
 228                                         break;
 229                                 case 7:
 230                                         if (hdlc->data_received)
 231                                                 /* bad frame */
 232                                                 status = -HDLC_FRAMING_ERROR;
 233                                         if (!hdlc->do_adapt56) {
 234                                                 if (hdlc->cbin == fast_abort
 235                                                     [hdlc->bit_shift + 1]) {
 236                                                         hdlc->state =
 237                                                                 HDLC_FAST_IDLE;
 238                                                         hdlc->bit_shift = 1;
 239                                                         break;
 240                                                 }
 241                                         } else
 242                                                 hdlc->state = HDLC_GET_FLAG_B0;
 243                                         break;
 244                                 default:
 245                                         hdlc->shift_reg >>= 1;
 246                                         hdlc->shift_reg |= 0x80;
 247                                         hdlc->data_bits++;
 248                                         break;
 249                                 }
 250                         } else {
 251                                 switch (hdlc->hdlc_bits1) {
 252                                 case 5:
 253                                         break;
 254                                 case 6:
 255                                         if (hdlc->data_received)
 256                                                 status = check_frame(hdlc);
 257                                         hdlc->crc = 0xffff;
 258                                         hdlc->shift_reg = 0;
 259                                         hdlc->data_bits = 0;
 260                                         if (!hdlc->do_adapt56)
 261                                                 handle_fast_flag(hdlc);
 262                                         else {
 263                                                 hdlc->state = HDLC_GET_DATA;
 264                                                 hdlc->data_received = 0;
 265                                         }
 266                                         break;
 267                                 default:
 268                                         hdlc->shift_reg >>= 1;
 269                                         hdlc->data_bits++;
 270                                         break;
 271                                 }
 272                                 hdlc->hdlc_bits1 = 0;
 273                         }
 274                         if (status) {
 275                                 hdlc->dstpos = 0;
 276                                 *count -= slen;
 277                                 hdlc->cbin <<= 1;
 278                                 hdlc->bit_shift--;
 279                                 return status;
 280                         }
 281                         if (hdlc->data_bits == 8) {
 282                                 hdlc->data_bits = 0;
 283                                 hdlc->data_received = 1;
 284                                 hdlc->crc = crc_ccitt_byte(hdlc->crc,
 285                                                            hdlc->shift_reg);
 286 
 287                                 /* good byte received */
 288                                 if (hdlc->dstpos < dsize)
 289                                         dst[hdlc->dstpos++] = hdlc->shift_reg;
 290                                 else {
 291                                         /* frame too long */
 292                                         status = -HDLC_LENGTH_ERROR;
 293                                         hdlc->dstpos = 0;
 294                                 }
 295                         }
 296                         hdlc->cbin <<= 1;
 297                         hdlc->bit_shift--;
 298                         break;
 299                 case HDLC_FAST_FLAG:
 300                         if (hdlc->cbin == hdlc->ffvalue) {
 301                                 hdlc->bit_shift = 0;
 302                                 break;
 303                         } else {
 304                                 if (hdlc->cbin == 0xff) {
 305                                         hdlc->state = HDLC_FAST_IDLE;
 306                                         hdlc->bit_shift = 0;
 307                                 } else if (hdlc->ffbit_shift == 8) {
 308                                         hdlc->state = HDLC_GETFLAG_B7;
 309                                         break;
 310                                 } else
 311                                         handle_abort(hdlc);
 312                         }
 313                         break;
 314                 default:
 315                         break;
 316                 }
 317         }
 318         *count -= slen;
 319         return 0;
 320 }
 321 EXPORT_SYMBOL(isdnhdlc_decode);
 322 /*
 323   isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.
 324 
 325   The bit stream starts with a beginning flag (01111110). After
 326   that each byte is added to the bit stream with bit stuffing added
 327   (0 after 5 1's).
 328   When the last byte has been removed from the source buffer, the
 329   CRC (2 bytes is added) and the frame terminates with the ending flag.
 330   For the dchannel, the idle character (all 1's) is also added at the end.
 331   If this function is called with empty source buffer (slen=0), flags or
 332   idle character will be generated.
 333 
 334   src - source buffer
 335   slen - source buffer length
 336   count - number of bytes removed (encoded) from source buffer
 337   dst _ destination buffer
 338   dsize - destination buffer size
 339   returns - number of encoded bytes in the destination buffer
 340 */
 341 int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen,
 342                     int *count, u8 *dst, int dsize)
 343 {
 344         static const unsigned char xfast_flag_value[] = {
 345                 0x7e, 0x3f, 0x9f, 0xcf, 0xe7, 0xf3, 0xf9, 0xfc, 0x7e
 346         };
 347 
 348         int len = 0;
 349 
 350         *count = slen;
 351 
 352         /* special handling for one byte frames */
 353         if ((slen == 1) && (hdlc->state == HDLC_SEND_FAST_FLAG))
 354                 hdlc->state = HDLC_SENDFLAG_ONE;
 355         while (dsize > 0) {
 356                 if (hdlc->bit_shift == 0) {
 357                         if (slen && !hdlc->do_closing) {
 358                                 hdlc->shift_reg = *src++;
 359                                 slen--;
 360                                 if (slen == 0)
 361                                         /* closing sequence, CRC + flag(s) */
 362                                         hdlc->do_closing = 1;
 363                                 hdlc->bit_shift = 8;
 364                         } else {
 365                                 if (hdlc->state == HDLC_SEND_DATA) {
 366                                         if (hdlc->data_received) {
 367                                                 hdlc->state = HDLC_SEND_CRC1;
 368                                                 hdlc->crc ^= 0xffff;
 369                                                 hdlc->bit_shift = 8;
 370                                                 hdlc->shift_reg =
 371                                                         hdlc->crc & 0xff;
 372                                         } else if (!hdlc->do_adapt56)
 373                                                 hdlc->state =
 374                                                         HDLC_SEND_FAST_FLAG;
 375                                         else
 376                                                 hdlc->state =
 377                                                         HDLC_SENDFLAG_B0;
 378                                 }
 379 
 380                         }
 381                 }
 382 
 383                 switch (hdlc->state) {
 384                 case STOPPED:
 385                         while (dsize--)
 386                                 *dst++ = 0xff;
 387                         return dsize;
 388                 case HDLC_SEND_FAST_FLAG:
 389                         hdlc->do_closing = 0;
 390                         if (slen == 0) {
 391                                 /* the code is for bitreverse streams */
 392                                 if (hdlc->do_bitreverse == 0)
 393                                         *dst++ = bitrev8(hdlc->ffvalue);
 394                                 else
 395                                         *dst++ = hdlc->ffvalue;
 396                                 len++;
 397                                 dsize--;
 398                                 break;
 399                         }
 400                         /* fall through */
 401                 case HDLC_SENDFLAG_ONE:
 402                         if (hdlc->bit_shift == 8) {
 403                                 hdlc->cbin = hdlc->ffvalue >>
 404                                         (8 - hdlc->data_bits);
 405                                 hdlc->state = HDLC_SEND_DATA;
 406                                 hdlc->crc = 0xffff;
 407                                 hdlc->hdlc_bits1 = 0;
 408                                 hdlc->data_received = 1;
 409                         }
 410                         break;
 411                 case HDLC_SENDFLAG_B0:
 412                         hdlc->do_closing = 0;
 413                         hdlc->cbin <<= 1;
 414                         hdlc->data_bits++;
 415                         hdlc->hdlc_bits1 = 0;
 416                         hdlc->state = HDLC_SENDFLAG_B1A6;
 417                         break;
 418                 case HDLC_SENDFLAG_B1A6:
 419                         hdlc->cbin <<= 1;
 420                         hdlc->data_bits++;
 421                         hdlc->cbin++;
 422                         if (++hdlc->hdlc_bits1 == 6)
 423                                 hdlc->state = HDLC_SENDFLAG_B7;
 424                         break;
 425                 case HDLC_SENDFLAG_B7:
 426                         hdlc->cbin <<= 1;
 427                         hdlc->data_bits++;
 428                         if (slen == 0) {
 429                                 hdlc->state = HDLC_SENDFLAG_B0;
 430                                 break;
 431                         }
 432                         if (hdlc->bit_shift == 8) {
 433                                 hdlc->state = HDLC_SEND_DATA;
 434                                 hdlc->crc = 0xffff;
 435                                 hdlc->hdlc_bits1 = 0;
 436                                 hdlc->data_received = 1;
 437                         }
 438                         break;
 439                 case HDLC_SEND_FIRST_FLAG:
 440                         hdlc->data_received = 1;
 441                         if (hdlc->data_bits == 8) {
 442                                 hdlc->state = HDLC_SEND_DATA;
 443                                 hdlc->crc = 0xffff;
 444                                 hdlc->hdlc_bits1 = 0;
 445                                 break;
 446                         }
 447                         hdlc->cbin <<= 1;
 448                         hdlc->data_bits++;
 449                         if (hdlc->shift_reg & 0x01)
 450                                 hdlc->cbin++;
 451                         hdlc->shift_reg >>= 1;
 452                         hdlc->bit_shift--;
 453                         if (hdlc->bit_shift == 0) {
 454                                 hdlc->state = HDLC_SEND_DATA;
 455                                 hdlc->crc = 0xffff;
 456                                 hdlc->hdlc_bits1 = 0;
 457                         }
 458                         break;
 459                 case HDLC_SEND_DATA:
 460                         hdlc->cbin <<= 1;
 461                         hdlc->data_bits++;
 462                         if (hdlc->hdlc_bits1 == 5) {
 463                                 hdlc->hdlc_bits1 = 0;
 464                                 break;
 465                         }
 466                         if (hdlc->bit_shift == 8)
 467                                 hdlc->crc = crc_ccitt_byte(hdlc->crc,
 468                                                            hdlc->shift_reg);
 469                         if (hdlc->shift_reg & 0x01) {
 470                                 hdlc->hdlc_bits1++;
 471                                 hdlc->cbin++;
 472                                 hdlc->shift_reg >>= 1;
 473                                 hdlc->bit_shift--;
 474                         } else {
 475                                 hdlc->hdlc_bits1 = 0;
 476                                 hdlc->shift_reg >>= 1;
 477                                 hdlc->bit_shift--;
 478                         }
 479                         break;
 480                 case HDLC_SEND_CRC1:
 481                         hdlc->cbin <<= 1;
 482                         hdlc->data_bits++;
 483                         if (hdlc->hdlc_bits1 == 5) {
 484                                 hdlc->hdlc_bits1 = 0;
 485                                 break;
 486                         }
 487                         if (hdlc->shift_reg & 0x01) {
 488                                 hdlc->hdlc_bits1++;
 489                                 hdlc->cbin++;
 490                                 hdlc->shift_reg >>= 1;
 491                                 hdlc->bit_shift--;
 492                         } else {
 493                                 hdlc->hdlc_bits1 = 0;
 494                                 hdlc->shift_reg >>= 1;
 495                                 hdlc->bit_shift--;
 496                         }
 497                         if (hdlc->bit_shift == 0) {
 498                                 hdlc->shift_reg = (hdlc->crc >> 8);
 499                                 hdlc->state = HDLC_SEND_CRC2;
 500                                 hdlc->bit_shift = 8;
 501                         }
 502                         break;
 503                 case HDLC_SEND_CRC2:
 504                         hdlc->cbin <<= 1;
 505                         hdlc->data_bits++;
 506                         if (hdlc->hdlc_bits1 == 5) {
 507                                 hdlc->hdlc_bits1 = 0;
 508                                 break;
 509                         }
 510                         if (hdlc->shift_reg & 0x01) {
 511                                 hdlc->hdlc_bits1++;
 512                                 hdlc->cbin++;
 513                                 hdlc->shift_reg >>= 1;
 514                                 hdlc->bit_shift--;
 515                         } else {
 516                                 hdlc->hdlc_bits1 = 0;
 517                                 hdlc->shift_reg >>= 1;
 518                                 hdlc->bit_shift--;
 519                         }
 520                         if (hdlc->bit_shift == 0) {
 521                                 hdlc->shift_reg = 0x7e;
 522                                 hdlc->state = HDLC_SEND_CLOSING_FLAG;
 523                                 hdlc->bit_shift = 8;
 524                         }
 525                         break;
 526                 case HDLC_SEND_CLOSING_FLAG:
 527                         hdlc->cbin <<= 1;
 528                         hdlc->data_bits++;
 529                         if (hdlc->hdlc_bits1 == 5) {
 530                                 hdlc->hdlc_bits1 = 0;
 531                                 break;
 532                         }
 533                         if (hdlc->shift_reg & 0x01)
 534                                 hdlc->cbin++;
 535                         hdlc->shift_reg >>= 1;
 536                         hdlc->bit_shift--;
 537                         if (hdlc->bit_shift == 0) {
 538                                 hdlc->ffvalue =
 539                                         xfast_flag_value[hdlc->data_bits];
 540                                 if (hdlc->dchannel) {
 541                                         hdlc->ffvalue = 0x7e;
 542                                         hdlc->state = HDLC_SEND_IDLE1;
 543                                         hdlc->bit_shift = 8-hdlc->data_bits;
 544                                         if (hdlc->bit_shift == 0)
 545                                                 hdlc->state =
 546                                                         HDLC_SEND_FAST_IDLE;
 547                                 } else {
 548                                         if (!hdlc->do_adapt56) {
 549                                                 hdlc->state =
 550                                                         HDLC_SEND_FAST_FLAG;
 551                                                 hdlc->data_received = 0;
 552                                         } else {
 553                                                 hdlc->state = HDLC_SENDFLAG_B0;
 554                                                 hdlc->data_received = 0;
 555                                         }
 556                                         /* Finished this frame, send flags */
 557                                         if (dsize > 1)
 558                                                 dsize = 1;
 559                                 }
 560                         }
 561                         break;
 562                 case HDLC_SEND_IDLE1:
 563                         hdlc->do_closing = 0;
 564                         hdlc->cbin <<= 1;
 565                         hdlc->cbin++;
 566                         hdlc->data_bits++;
 567                         hdlc->bit_shift--;
 568                         if (hdlc->bit_shift == 0) {
 569                                 hdlc->state = HDLC_SEND_FAST_IDLE;
 570                                 hdlc->bit_shift = 0;
 571                         }
 572                         break;
 573                 case HDLC_SEND_FAST_IDLE:
 574                         hdlc->do_closing = 0;
 575                         hdlc->cbin = 0xff;
 576                         hdlc->data_bits = 8;
 577                         if (hdlc->bit_shift == 8) {
 578                                 hdlc->cbin = 0x7e;
 579                                 hdlc->state = HDLC_SEND_FIRST_FLAG;
 580                         } else {
 581                                 /* the code is for bitreverse streams */
 582                                 if (hdlc->do_bitreverse == 0)
 583                                         *dst++ = bitrev8(hdlc->cbin);
 584                                 else
 585                                         *dst++ = hdlc->cbin;
 586                                 hdlc->bit_shift = 0;
 587                                 hdlc->data_bits = 0;
 588                                 len++;
 589                                 dsize = 0;
 590                         }
 591                         break;
 592                 default:
 593                         break;
 594                 }
 595                 if (hdlc->do_adapt56) {
 596                         if (hdlc->data_bits == 7) {
 597                                 hdlc->cbin <<= 1;
 598                                 hdlc->cbin++;
 599                                 hdlc->data_bits++;
 600                         }
 601                 }
 602                 if (hdlc->data_bits == 8) {
 603                         /* the code is for bitreverse streams */
 604                         if (hdlc->do_bitreverse == 0)
 605                                 *dst++ = bitrev8(hdlc->cbin);
 606                         else
 607                                 *dst++ = hdlc->cbin;
 608                         hdlc->data_bits = 0;
 609                         len++;
 610                         dsize--;
 611                 }
 612         }
 613         *count -= slen;
 614 
 615         return len;
 616 }
 617 EXPORT_SYMBOL(isdnhdlc_encode);

/* [<][>][^][v][top][bottom][index][help] */