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