📄 isdnhdlc.c
字号:
hdlc->dstpos = 0; } } hdlc->cbin <<= 1; hdlc->bit_shift--; break; case HDLC_FAST_FLAG: if(hdlc->cbin==hdlc->ffvalue){ hdlc->bit_shift = 0; break; } else { if(hdlc->cbin == 0xff){ hdlc->state = HDLC_FAST_IDLE; hdlc->bit_shift=0; } else if(hdlc->ffbit_shift==8){ hdlc->state = HDLC_GETFLAG_B7; break; } else { hdlc->shift_reg = fast_abort[hdlc->ffbit_shift-1]; hdlc->hdlc_bits1 = hdlc->ffbit_shift-2; if(hdlc->hdlc_bits1<0)hdlc->hdlc_bits1 = 0; hdlc->data_bits = hdlc->ffbit_shift-1; hdlc->state = HDLC_GET_DATA; hdlc->data_received = 0; } } break; default: break; } } *count -= slen; return 0;}/* isdnhdlc_encode - encodes HDLC frames to a transparent bit stream. The bit stream starts with a beginning flag (01111110). After that each byte is added to the bit stream with bit stuffing added (0 after 5 1's). When the last byte has been removed from the source buffer, the CRC (2 bytes is added) and the frame terminates with the ending flag. For the dchannel, the idle character (all 1's) is also added at the end. If this function is called with empty source buffer (slen=0), flags or idle character will be generated. src - source buffer slen - source buffer length count - number of bytes removed (encoded) from source buffer dst _ destination buffer dsize - destination buffer size returns - number of encoded bytes in the destination buffer*/int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src, unsigned short slen, int *count, unsigned char *dst, int dsize){ static const unsigned char xfast_flag_value[] = { 0x7e,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0x7e }; int len = 0; *count = slen; while (dsize > 0) { if(hdlc->bit_shift==0){ if(slen && !hdlc->do_closing){ hdlc->shift_reg = *src++; slen--; if (slen == 0) hdlc->do_closing = 1; /* closing sequence, CRC + flag(s) */ hdlc->bit_shift = 8; } else { if(hdlc->state == HDLC_SEND_DATA){ if(hdlc->data_received){ hdlc->state = HDLC_SEND_CRC1; hdlc->crc ^= 0xffff; hdlc->bit_shift = 8; hdlc->shift_reg = hdlc->crc & 0xff; } else if(!hdlc->do_adapt56){ hdlc->state = HDLC_SEND_FAST_FLAG; } else { hdlc->state = HDLC_SENDFLAG_B0; } } } } switch(hdlc->state){ case STOPPED: while (dsize--) *dst++ = 0xff; return dsize; case HDLC_SEND_FAST_FLAG: hdlc->do_closing = 0; if(slen == 0){ *dst++ = hdlc->ffvalue; len++; dsize--; break; } if(hdlc->bit_shift==8){ hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits); hdlc->state = HDLC_SEND_DATA; hdlc->crc = 0xffff; hdlc->hdlc_bits1 = 0; hdlc->data_received = 1; } break; case HDLC_SENDFLAG_B0: hdlc->do_closing = 0; hdlc->cbin <<= 1; hdlc->data_bits++; hdlc->hdlc_bits1 = 0; hdlc->state = HDLC_SENDFLAG_B1A6; break; case HDLC_SENDFLAG_B1A6: hdlc->cbin <<= 1; hdlc->data_bits++; hdlc->cbin++; if(++hdlc->hdlc_bits1 == 6) hdlc->state = HDLC_SENDFLAG_B7; break; case HDLC_SENDFLAG_B7: hdlc->cbin <<= 1; hdlc->data_bits++; if(slen == 0){ hdlc->state = HDLC_SENDFLAG_B0; break; } if(hdlc->bit_shift==8){ hdlc->state = HDLC_SEND_DATA; hdlc->crc = 0xffff; hdlc->hdlc_bits1 = 0; hdlc->data_received = 1; } break; case HDLC_SEND_FIRST_FLAG: hdlc->data_received = 1; if(hdlc->data_bits==8){ hdlc->state = HDLC_SEND_DATA; hdlc->crc = 0xffff; hdlc->hdlc_bits1 = 0; break; } hdlc->cbin <<= 1; hdlc->data_bits++; if(hdlc->shift_reg & 0x01) hdlc->cbin++; hdlc->shift_reg >>= 1; hdlc->bit_shift--; if(hdlc->bit_shift==0){ hdlc->state = HDLC_SEND_DATA; hdlc->crc = 0xffff; hdlc->hdlc_bits1 = 0; } break; case HDLC_SEND_DATA: hdlc->cbin <<= 1; hdlc->data_bits++; if(hdlc->hdlc_bits1 == 5){ hdlc->hdlc_bits1 = 0; break; } if(hdlc->bit_shift==8){ hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg); } if(hdlc->shift_reg & 0x01){ hdlc->hdlc_bits1++; hdlc->cbin++; hdlc->shift_reg >>= 1; hdlc->bit_shift--; } else { hdlc->hdlc_bits1 = 0; hdlc->shift_reg >>= 1; hdlc->bit_shift--; } break; case HDLC_SEND_CRC1: hdlc->cbin <<= 1; hdlc->data_bits++; if(hdlc->hdlc_bits1 == 5){ hdlc->hdlc_bits1 = 0; break; } if(hdlc->shift_reg & 0x01){ hdlc->hdlc_bits1++; hdlc->cbin++; hdlc->shift_reg >>= 1; hdlc->bit_shift--; } else { hdlc->hdlc_bits1 = 0; hdlc->shift_reg >>= 1; hdlc->bit_shift--; } if(hdlc->bit_shift==0){ hdlc->shift_reg = (hdlc->crc >> 8); hdlc->state = HDLC_SEND_CRC2; hdlc->bit_shift = 8; } break; case HDLC_SEND_CRC2: hdlc->cbin <<= 1; hdlc->data_bits++; if(hdlc->hdlc_bits1 == 5){ hdlc->hdlc_bits1 = 0; break; } if(hdlc->shift_reg & 0x01){ hdlc->hdlc_bits1++; hdlc->cbin++; hdlc->shift_reg >>= 1; hdlc->bit_shift--; } else { hdlc->hdlc_bits1 = 0; hdlc->shift_reg >>= 1; hdlc->bit_shift--; } if(hdlc->bit_shift==0){ hdlc->shift_reg = 0x7e; hdlc->state = HDLC_SEND_CLOSING_FLAG; hdlc->bit_shift = 8; } break; case HDLC_SEND_CLOSING_FLAG: hdlc->cbin <<= 1; hdlc->data_bits++; if(hdlc->hdlc_bits1 == 5){ hdlc->hdlc_bits1 = 0; break; } if(hdlc->shift_reg & 0x01){ hdlc->cbin++; } hdlc->shift_reg >>= 1; hdlc->bit_shift--; if(hdlc->bit_shift==0){ hdlc->ffvalue = xfast_flag_value[hdlc->data_bits]; if(hdlc->dchannel){ hdlc->ffvalue = 0x7e; hdlc->state = HDLC_SEND_IDLE1; hdlc->bit_shift = 8-hdlc->data_bits; if(hdlc->bit_shift==0) hdlc->state = HDLC_SEND_FAST_IDLE; } else { if(!hdlc->do_adapt56){ hdlc->state = HDLC_SEND_FAST_FLAG; hdlc->data_received = 0; } else { hdlc->state = HDLC_SENDFLAG_B0; hdlc->data_received = 0; } // Finished with this frame, send flags if (dsize > 1) dsize = 1; } } break; case HDLC_SEND_IDLE1: hdlc->do_closing = 0; hdlc->cbin <<= 1; hdlc->cbin++; hdlc->data_bits++; hdlc->bit_shift--; if(hdlc->bit_shift==0){ hdlc->state = HDLC_SEND_FAST_IDLE; hdlc->bit_shift = 0; } break; case HDLC_SEND_FAST_IDLE: hdlc->do_closing = 0; hdlc->cbin = 0xff; hdlc->data_bits = 8; if(hdlc->bit_shift == 8){ hdlc->cbin = 0x7e; hdlc->state = HDLC_SEND_FIRST_FLAG; } else { *dst++ = hdlc->cbin; hdlc->bit_shift = hdlc->data_bits = 0; len++; dsize = 0; } break; default: break; } if(hdlc->do_adapt56){ if(hdlc->data_bits==7){ hdlc->cbin <<= 1; hdlc->cbin++; hdlc->data_bits++; } } if(hdlc->data_bits==8){ *dst++ = hdlc->cbin; hdlc->data_bits = 0; len++; dsize--; } } *count -= slen; return len;}EXPORT_SYMBOL(isdnhdlc_bit_rev_tab);EXPORT_SYMBOL(isdnhdlc_rcv_init);EXPORT_SYMBOL(isdnhdlc_decode);EXPORT_SYMBOL(isdnhdlc_out_init);EXPORT_SYMBOL(isdnhdlc_encode);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -