isdnhdlc.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. /*
  2. * isdnhdlc.c -- General purpose ISDN HDLC decoder.
  3. *
  4. *Copyright (C) 2002 Wolfgang Mües <wolfgang@iksw-muees.de>
  5. * 2001 Frode Isaksen <fisaksen@bewan.com>
  6. * 2001 Kai Germaschewski <kai.germaschewski@gmx.de>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. */
  22. #include <linux/module.h>
  23. #include <linux/init.h>
  24. #include <linux/crc-ccitt.h>
  25. #include "isdnhdlc.h"
  26. /*-------------------------------------------------------------------*/
  27. MODULE_AUTHOR("Wolfgang Mües <wolfgang@iksw-muees.de>, "
  28. "Frode Isaksen <fisaksen@bewan.com>, "
  29. "Kai Germaschewski <kai.germaschewski@gmx.de>");
  30. MODULE_DESCRIPTION("General purpose ISDN HDLC decoder");
  31. MODULE_LICENSE("GPL");
  32. /*-------------------------------------------------------------------*/
  33. /* bit swap table.
  34. * Very handy for devices with different bit order,
  35. * and neccessary for each transparent B-channel access for all
  36. * devices which works with this HDLC decoder without bit reversal.
  37. */
  38. const unsigned char isdnhdlc_bit_rev_tab[256] = {
  39. 0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
  40. 0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
  41. 0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
  42. 0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
  43. 0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
  44. 0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
  45. 0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
  46. 0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
  47. 0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
  48. 0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
  49. 0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
  50. 0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
  51. 0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
  52. 0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
  53. 0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
  54. 0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF
  55. };
  56. enum {
  57. HDLC_FAST_IDLE,HDLC_GET_FLAG_B0,HDLC_GETFLAG_B1A6,HDLC_GETFLAG_B7,
  58. HDLC_GET_DATA,HDLC_FAST_FLAG
  59. };
  60. enum {
  61. HDLC_SEND_DATA,HDLC_SEND_CRC1,HDLC_SEND_FAST_FLAG,
  62. HDLC_SEND_FIRST_FLAG,HDLC_SEND_CRC2,HDLC_SEND_CLOSING_FLAG,
  63. HDLC_SEND_IDLE1,HDLC_SEND_FAST_IDLE,HDLC_SENDFLAG_B0,
  64. HDLC_SENDFLAG_B1A6,HDLC_SENDFLAG_B7,STOPPED
  65. };
  66. void isdnhdlc_rcv_init (struct isdnhdlc_vars *hdlc, int do_adapt56)
  67. {
  68. hdlc->bit_shift = 0;
  69. hdlc->hdlc_bits1 = 0;
  70. hdlc->data_bits = 0;
  71. hdlc->ffbit_shift = 0;
  72. hdlc->data_received = 0;
  73. hdlc->state = HDLC_GET_DATA;
  74. hdlc->do_adapt56 = do_adapt56;
  75. hdlc->dchannel = 0;
  76. hdlc->crc = 0;
  77. hdlc->cbin = 0;
  78. hdlc->shift_reg = 0;
  79. hdlc->ffvalue = 0;
  80. hdlc->dstpos = 0;
  81. }
  82. void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_adapt56)
  83. {
  84. hdlc->bit_shift = 0;
  85. hdlc->hdlc_bits1 = 0;
  86. hdlc->data_bits = 0;
  87. hdlc->ffbit_shift = 0;
  88. hdlc->data_received = 0;
  89. hdlc->do_closing = 0;
  90. hdlc->ffvalue = 0;
  91. if (is_d_channel) {
  92. hdlc->dchannel = 1;
  93. hdlc->state = HDLC_SEND_FIRST_FLAG;
  94. } else {
  95. hdlc->dchannel = 0;
  96. hdlc->state = HDLC_SEND_FAST_FLAG;
  97. hdlc->ffvalue = 0x7e;
  98. }
  99. hdlc->cbin = 0x7e;
  100. hdlc->bit_shift = 0;
  101. if(do_adapt56){
  102. hdlc->do_adapt56 = 1;
  103. hdlc->data_bits = 0;
  104. hdlc->state = HDLC_SENDFLAG_B0;
  105. } else {
  106. hdlc->do_adapt56 = 0;
  107. hdlc->data_bits = 8;
  108. }
  109. hdlc->shift_reg = 0;
  110. }
  111. /*
  112. isdnhdlc_decode - decodes HDLC frames from a transparent bit stream.
  113. The source buffer is scanned for valid HDLC frames looking for
  114. flags (01111110) to indicate the start of a frame. If the start of
  115. the frame is found, the bit stuffing is removed (0 after 5 1's).
  116. When a new flag is found, the complete frame has been received
  117. and the CRC is checked.
  118. If a valid frame is found, the function returns the frame length
  119. excluding the CRC with the bit HDLC_END_OF_FRAME set.
  120. If the beginning of a valid frame is found, the function returns
  121. the length.
  122. If a framing error is found (too many 1s and not a flag) the function
  123. returns the length with the bit HDLC_FRAMING_ERROR set.
  124. If a CRC error is found the function returns the length with the
  125. bit HDLC_CRC_ERROR set.
  126. If the frame length exceeds the destination buffer size, the function
  127. returns the length with the bit HDLC_LENGTH_ERROR set.
  128. src - source buffer
  129. slen - source buffer length
  130. count - number of bytes removed (decoded) from the source buffer
  131. dst _ destination buffer
  132. dsize - destination buffer size
  133. returns - number of decoded bytes in the destination buffer and status
  134. flag.
  135. */
  136. int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
  137. int slen, int *count, unsigned char *dst, int dsize)
  138. {
  139. int status=0;
  140. static const unsigned char fast_flag[]={
  141. 0x00,0x00,0x00,0x20,0x30,0x38,0x3c,0x3e,0x3f
  142. };
  143. static const unsigned char fast_flag_value[]={
  144. 0x00,0x7e,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f
  145. };
  146. static const unsigned char fast_abort[]={
  147. 0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff
  148. };
  149. *count = slen;
  150. while(slen > 0){
  151. if(hdlc->bit_shift==0){
  152. hdlc->cbin = *src++;
  153. slen--;
  154. hdlc->bit_shift = 8;
  155. if(hdlc->do_adapt56){
  156. hdlc->bit_shift --;
  157. }
  158. }
  159. switch(hdlc->state){
  160. case STOPPED:
  161. return 0;
  162. case HDLC_FAST_IDLE:
  163. if(hdlc->cbin == 0xff){
  164. hdlc->bit_shift = 0;
  165. break;
  166. }
  167. hdlc->state = HDLC_GET_FLAG_B0;
  168. hdlc->hdlc_bits1 = 0;
  169. hdlc->bit_shift = 8;
  170. break;
  171. case HDLC_GET_FLAG_B0:
  172. if(!(hdlc->cbin & 0x80)) {
  173. hdlc->state = HDLC_GETFLAG_B1A6;
  174. hdlc->hdlc_bits1 = 0;
  175. } else {
  176. if(!hdlc->do_adapt56){
  177. if(++hdlc->hdlc_bits1 >=8 ) if(hdlc->bit_shift==1)
  178. hdlc->state = HDLC_FAST_IDLE;
  179. }
  180. }
  181. hdlc->cbin<<=1;
  182. hdlc->bit_shift --;
  183. break;
  184. case HDLC_GETFLAG_B1A6:
  185. if(hdlc->cbin & 0x80){
  186. hdlc->hdlc_bits1++;
  187. if(hdlc->hdlc_bits1==6){
  188. hdlc->state = HDLC_GETFLAG_B7;
  189. }
  190. } else {
  191. hdlc->hdlc_bits1 = 0;
  192. }
  193. hdlc->cbin<<=1;
  194. hdlc->bit_shift --;
  195. break;
  196. case HDLC_GETFLAG_B7:
  197. if(hdlc->cbin & 0x80) {
  198. hdlc->state = HDLC_GET_FLAG_B0;
  199. } else {
  200. hdlc->state = HDLC_GET_DATA;
  201. hdlc->crc = 0xffff;
  202. hdlc->shift_reg = 0;
  203. hdlc->hdlc_bits1 = 0;
  204. hdlc->data_bits = 0;
  205. hdlc->data_received = 0;
  206. }
  207. hdlc->cbin<<=1;
  208. hdlc->bit_shift --;
  209. break;
  210. case HDLC_GET_DATA:
  211. if(hdlc->cbin & 0x80){
  212. hdlc->hdlc_bits1++;
  213. switch(hdlc->hdlc_bits1){
  214. case 6:
  215. break;
  216. case 7:
  217. if(hdlc->data_received) {
  218. // bad frame
  219. status = -HDLC_FRAMING_ERROR;
  220. }
  221. if(!hdlc->do_adapt56){
  222. if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){
  223. hdlc->state = HDLC_FAST_IDLE;
  224. hdlc->bit_shift=1;
  225. break;
  226. }
  227. } else {
  228. hdlc->state = HDLC_GET_FLAG_B0;
  229. }
  230. break;
  231. default:
  232. hdlc->shift_reg>>=1;
  233. hdlc->shift_reg |= 0x80;
  234. hdlc->data_bits++;
  235. break;
  236. }
  237. } else {
  238. switch(hdlc->hdlc_bits1){
  239. case 5:
  240. break;
  241. case 6:
  242. if(hdlc->data_received){
  243. if (hdlc->dstpos < 2) {
  244. status = -HDLC_FRAMING_ERROR;
  245. } else if (hdlc->crc != 0xf0b8){
  246. // crc error
  247. status = -HDLC_CRC_ERROR;
  248. } else {
  249. // remove CRC
  250. hdlc->dstpos -= 2;
  251. // good frame
  252. status = hdlc->dstpos;
  253. }
  254. }
  255. hdlc->crc = 0xffff;
  256. hdlc->shift_reg = 0;
  257. hdlc->data_bits = 0;
  258. if(!hdlc->do_adapt56){
  259. if(hdlc->cbin==fast_flag[hdlc->bit_shift]){
  260. hdlc->ffvalue = fast_flag_value[hdlc->bit_shift];
  261. hdlc->state = HDLC_FAST_FLAG;
  262. hdlc->ffbit_shift = hdlc->bit_shift;
  263. hdlc->bit_shift = 1;
  264. } else {
  265. hdlc->state = HDLC_GET_DATA;
  266. hdlc->data_received = 0;
  267. }
  268. } else {
  269. hdlc->state = HDLC_GET_DATA;
  270. hdlc->data_received = 0;
  271. }
  272. break;
  273. default:
  274. hdlc->shift_reg>>=1;
  275. hdlc->data_bits++;
  276. break;
  277. }
  278. hdlc->hdlc_bits1 = 0;
  279. }
  280. if (status) {
  281. hdlc->dstpos = 0;
  282. *count -= slen;
  283. hdlc->cbin <<= 1;
  284. hdlc->bit_shift--;
  285. return status;
  286. }
  287. if(hdlc->data_bits==8){
  288. hdlc->data_bits = 0;
  289. hdlc->data_received = 1;
  290. hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
  291. // good byte received
  292. if (hdlc->dstpos < dsize) {
  293. dst[hdlc->dstpos++] = hdlc->shift_reg;
  294. } else {
  295. // frame too long
  296. status = -HDLC_LENGTH_ERROR;
  297. hdlc->dstpos = 0;
  298. }
  299. }
  300. hdlc->cbin <<= 1;
  301. hdlc->bit_shift--;
  302. break;
  303. case HDLC_FAST_FLAG:
  304. if(hdlc->cbin==hdlc->ffvalue){
  305. hdlc->bit_shift = 0;
  306. break;
  307. } else {
  308. if(hdlc->cbin == 0xff){
  309. hdlc->state = HDLC_FAST_IDLE;
  310. hdlc->bit_shift=0;
  311. } else if(hdlc->ffbit_shift==8){
  312. hdlc->state = HDLC_GETFLAG_B7;
  313. break;
  314. } else {
  315. hdlc->shift_reg = fast_abort[hdlc->ffbit_shift-1];
  316. hdlc->hdlc_bits1 = hdlc->ffbit_shift-2;
  317. if(hdlc->hdlc_bits1<0)hdlc->hdlc_bits1 = 0;
  318. hdlc->data_bits = hdlc->ffbit_shift-1;
  319. hdlc->state = HDLC_GET_DATA;
  320. hdlc->data_received = 0;
  321. }
  322. }
  323. break;
  324. default:
  325. break;
  326. }
  327. }
  328. *count -= slen;
  329. return 0;
  330. }
  331. /*
  332. isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.
  333. The bit stream starts with a beginning flag (01111110). After
  334. that each byte is added to the bit stream with bit stuffing added
  335. (0 after 5 1's).
  336. When the last byte has been removed from the source buffer, the
  337. CRC (2 bytes is added) and the frame terminates with the ending flag.
  338. For the dchannel, the idle character (all 1's) is also added at the end.
  339. If this function is called with empty source buffer (slen=0), flags or
  340. idle character will be generated.
  341. src - source buffer
  342. slen - source buffer length
  343. count - number of bytes removed (encoded) from source buffer
  344. dst _ destination buffer
  345. dsize - destination buffer size
  346. returns - number of encoded bytes in the destination buffer
  347. */
  348. int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
  349. unsigned short slen, int *count,
  350. unsigned char *dst, int dsize)
  351. {
  352. static const unsigned char xfast_flag_value[] = {
  353. 0x7e,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0x7e
  354. };
  355. int len = 0;
  356. *count = slen;
  357. while (dsize > 0) {
  358. if(hdlc->bit_shift==0){
  359. if(slen && !hdlc->do_closing){
  360. hdlc->shift_reg = *src++;
  361. slen--;
  362. if (slen == 0)
  363. hdlc->do_closing = 1; /* closing sequence, CRC + flag(s) */
  364. hdlc->bit_shift = 8;
  365. } else {
  366. if(hdlc->state == HDLC_SEND_DATA){
  367. if(hdlc->data_received){
  368. hdlc->state = HDLC_SEND_CRC1;
  369. hdlc->crc ^= 0xffff;
  370. hdlc->bit_shift = 8;
  371. hdlc->shift_reg = hdlc->crc & 0xff;
  372. } else if(!hdlc->do_adapt56){
  373. hdlc->state = HDLC_SEND_FAST_FLAG;
  374. } else {
  375. hdlc->state = HDLC_SENDFLAG_B0;
  376. }
  377. }
  378. }
  379. }
  380. switch(hdlc->state){
  381. case STOPPED:
  382. while (dsize--)
  383. *dst++ = 0xff;
  384. return dsize;
  385. case HDLC_SEND_FAST_FLAG:
  386. hdlc->do_closing = 0;
  387. if(slen == 0){
  388. *dst++ = hdlc->ffvalue;
  389. len++;
  390. dsize--;
  391. break;
  392. }
  393. if(hdlc->bit_shift==8){
  394. hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits);
  395. hdlc->state = HDLC_SEND_DATA;
  396. hdlc->crc = 0xffff;
  397. hdlc->hdlc_bits1 = 0;
  398. hdlc->data_received = 1;
  399. }
  400. break;
  401. case HDLC_SENDFLAG_B0:
  402. hdlc->do_closing = 0;
  403. hdlc->cbin <<= 1;
  404. hdlc->data_bits++;
  405. hdlc->hdlc_bits1 = 0;
  406. hdlc->state = HDLC_SENDFLAG_B1A6;
  407. break;
  408. case HDLC_SENDFLAG_B1A6:
  409. hdlc->cbin <<= 1;
  410. hdlc->data_bits++;
  411. hdlc->cbin++;
  412. if(++hdlc->hdlc_bits1 == 6)
  413. hdlc->state = HDLC_SENDFLAG_B7;
  414. break;
  415. case HDLC_SENDFLAG_B7:
  416. hdlc->cbin <<= 1;
  417. hdlc->data_bits++;
  418. if(slen == 0){
  419. hdlc->state = HDLC_SENDFLAG_B0;
  420. break;
  421. }
  422. if(hdlc->bit_shift==8){
  423. hdlc->state = HDLC_SEND_DATA;
  424. hdlc->crc = 0xffff;
  425. hdlc->hdlc_bits1 = 0;
  426. hdlc->data_received = 1;
  427. }
  428. break;
  429. case HDLC_SEND_FIRST_FLAG:
  430. hdlc->data_received = 1;
  431. if(hdlc->data_bits==8){
  432. hdlc->state = HDLC_SEND_DATA;
  433. hdlc->crc = 0xffff;
  434. hdlc->hdlc_bits1 = 0;
  435. break;
  436. }
  437. hdlc->cbin <<= 1;
  438. hdlc->data_bits++;
  439. if(hdlc->shift_reg & 0x01)
  440. hdlc->cbin++;
  441. hdlc->shift_reg >>= 1;
  442. hdlc->bit_shift--;
  443. if(hdlc->bit_shift==0){
  444. hdlc->state = HDLC_SEND_DATA;
  445. hdlc->crc = 0xffff;
  446. hdlc->hdlc_bits1 = 0;
  447. }
  448. break;
  449. case HDLC_SEND_DATA:
  450. hdlc->cbin <<= 1;
  451. hdlc->data_bits++;
  452. if(hdlc->hdlc_bits1 == 5){
  453. hdlc->hdlc_bits1 = 0;
  454. break;
  455. }
  456. if(hdlc->bit_shift==8){
  457. hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
  458. }
  459. if(hdlc->shift_reg & 0x01){
  460. hdlc->hdlc_bits1++;
  461. hdlc->cbin++;
  462. hdlc->shift_reg >>= 1;
  463. hdlc->bit_shift--;
  464. } else {
  465. hdlc->hdlc_bits1 = 0;
  466. hdlc->shift_reg >>= 1;
  467. hdlc->bit_shift--;
  468. }
  469. break;
  470. case HDLC_SEND_CRC1:
  471. hdlc->cbin <<= 1;
  472. hdlc->data_bits++;
  473. if(hdlc->hdlc_bits1 == 5){
  474. hdlc->hdlc_bits1 = 0;
  475. break;
  476. }
  477. if(hdlc->shift_reg & 0x01){
  478. hdlc->hdlc_bits1++;
  479. hdlc->cbin++;
  480. hdlc->shift_reg >>= 1;
  481. hdlc->bit_shift--;
  482. } else {
  483. hdlc->hdlc_bits1 = 0;
  484. hdlc->shift_reg >>= 1;
  485. hdlc->bit_shift--;
  486. }
  487. if(hdlc->bit_shift==0){
  488. hdlc->shift_reg = (hdlc->crc >> 8);
  489. hdlc->state = HDLC_SEND_CRC2;
  490. hdlc->bit_shift = 8;
  491. }
  492. break;
  493. case HDLC_SEND_CRC2:
  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 = 0x7e;
  512. hdlc->state = HDLC_SEND_CLOSING_FLAG;
  513. hdlc->bit_shift = 8;
  514. }
  515. break;
  516. case HDLC_SEND_CLOSING_FLAG:
  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->cbin++;
  525. }
  526. hdlc->shift_reg >>= 1;
  527. hdlc->bit_shift--;
  528. if(hdlc->bit_shift==0){
  529. hdlc->ffvalue = xfast_flag_value[hdlc->data_bits];
  530. if(hdlc->dchannel){
  531. hdlc->ffvalue = 0x7e;
  532. hdlc->state = HDLC_SEND_IDLE1;
  533. hdlc->bit_shift = 8-hdlc->data_bits;
  534. if(hdlc->bit_shift==0)
  535. hdlc->state = HDLC_SEND_FAST_IDLE;
  536. } else {
  537. if(!hdlc->do_adapt56){
  538. hdlc->state = HDLC_SEND_FAST_FLAG;
  539. hdlc->data_received = 0;
  540. } else {
  541. hdlc->state = HDLC_SENDFLAG_B0;
  542. hdlc->data_received = 0;
  543. }
  544. // Finished with this frame, send flags
  545. if (dsize > 1) dsize = 1;
  546. }
  547. }
  548. break;
  549. case HDLC_SEND_IDLE1:
  550. hdlc->do_closing = 0;
  551. hdlc->cbin <<= 1;
  552. hdlc->cbin++;
  553. hdlc->data_bits++;
  554. hdlc->bit_shift--;
  555. if(hdlc->bit_shift==0){
  556. hdlc->state = HDLC_SEND_FAST_IDLE;
  557. hdlc->bit_shift = 0;
  558. }
  559. break;
  560. case HDLC_SEND_FAST_IDLE:
  561. hdlc->do_closing = 0;
  562. hdlc->cbin = 0xff;
  563. hdlc->data_bits = 8;
  564. if(hdlc->bit_shift == 8){
  565. hdlc->cbin = 0x7e;
  566. hdlc->state = HDLC_SEND_FIRST_FLAG;
  567. } else {
  568. *dst++ = hdlc->cbin;
  569. hdlc->bit_shift = hdlc->data_bits = 0;
  570. len++;
  571. dsize = 0;
  572. }
  573. break;
  574. default:
  575. break;
  576. }
  577. if(hdlc->do_adapt56){
  578. if(hdlc->data_bits==7){
  579. hdlc->cbin <<= 1;
  580. hdlc->cbin++;
  581. hdlc->data_bits++;
  582. }
  583. }
  584. if(hdlc->data_bits==8){
  585. *dst++ = hdlc->cbin;
  586. hdlc->data_bits = 0;
  587. len++;
  588. dsize--;
  589. }
  590. }
  591. *count -= slen;
  592. return len;
  593. }
  594. EXPORT_SYMBOL(isdnhdlc_bit_rev_tab);
  595. EXPORT_SYMBOL(isdnhdlc_rcv_init);
  596. EXPORT_SYMBOL(isdnhdlc_decode);
  597. EXPORT_SYMBOL(isdnhdlc_out_init);
  598. EXPORT_SYMBOL(isdnhdlc_encode);