capi.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179
  1. /* $Id: capi.c,v 1.9.6.2 2001/09/23 22:24:32 kai Exp $
  2. *
  3. * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
  4. * CAPI encoder/decoder
  5. *
  6. * Author Fritz Elfert
  7. * Copyright by Fritz Elfert <fritz@isdn4linux.de>
  8. *
  9. * This software may be used and distributed according to the terms
  10. * of the GNU General Public License, incorporated herein by reference.
  11. *
  12. * Thanks to Friedemann Baitinger and IBM Germany
  13. *
  14. */
  15. #include "act2000.h"
  16. #include "capi.h"
  17. static actcapi_msgdsc valid_msg[] = {
  18. {{ 0x86, 0x02}, "DATA_B3_IND"}, /* DATA_B3_IND/CONF must be first because of speed!!! */
  19. {{ 0x86, 0x01}, "DATA_B3_CONF"},
  20. {{ 0x02, 0x01}, "CONNECT_CONF"},
  21. {{ 0x02, 0x02}, "CONNECT_IND"},
  22. {{ 0x09, 0x01}, "CONNECT_INFO_CONF"},
  23. {{ 0x03, 0x02}, "CONNECT_ACTIVE_IND"},
  24. {{ 0x04, 0x01}, "DISCONNECT_CONF"},
  25. {{ 0x04, 0x02}, "DISCONNECT_IND"},
  26. {{ 0x05, 0x01}, "LISTEN_CONF"},
  27. {{ 0x06, 0x01}, "GET_PARAMS_CONF"},
  28. {{ 0x07, 0x01}, "INFO_CONF"},
  29. {{ 0x07, 0x02}, "INFO_IND"},
  30. {{ 0x08, 0x01}, "DATA_CONF"},
  31. {{ 0x08, 0x02}, "DATA_IND"},
  32. {{ 0x40, 0x01}, "SELECT_B2_PROTOCOL_CONF"},
  33. {{ 0x80, 0x01}, "SELECT_B3_PROTOCOL_CONF"},
  34. {{ 0x81, 0x01}, "LISTEN_B3_CONF"},
  35. {{ 0x82, 0x01}, "CONNECT_B3_CONF"},
  36. {{ 0x82, 0x02}, "CONNECT_B3_IND"},
  37. {{ 0x83, 0x02}, "CONNECT_B3_ACTIVE_IND"},
  38. {{ 0x84, 0x01}, "DISCONNECT_B3_CONF"},
  39. {{ 0x84, 0x02}, "DISCONNECT_B3_IND"},
  40. {{ 0x85, 0x01}, "GET_B3_PARAMS_CONF"},
  41. {{ 0x01, 0x01}, "RESET_B3_CONF"},
  42. {{ 0x01, 0x02}, "RESET_B3_IND"},
  43. /* {{ 0x87, 0x02, "HANDSET_IND"}, not implemented */
  44. {{ 0xff, 0x01}, "MANUFACTURER_CONF"},
  45. {{ 0xff, 0x02}, "MANUFACTURER_IND"},
  46. #ifdef DEBUG_MSG
  47. /* Requests */
  48. {{ 0x01, 0x00}, "RESET_B3_REQ"},
  49. {{ 0x02, 0x00}, "CONNECT_REQ"},
  50. {{ 0x04, 0x00}, "DISCONNECT_REQ"},
  51. {{ 0x05, 0x00}, "LISTEN_REQ"},
  52. {{ 0x06, 0x00}, "GET_PARAMS_REQ"},
  53. {{ 0x07, 0x00}, "INFO_REQ"},
  54. {{ 0x08, 0x00}, "DATA_REQ"},
  55. {{ 0x09, 0x00}, "CONNECT_INFO_REQ"},
  56. {{ 0x40, 0x00}, "SELECT_B2_PROTOCOL_REQ"},
  57. {{ 0x80, 0x00}, "SELECT_B3_PROTOCOL_REQ"},
  58. {{ 0x81, 0x00}, "LISTEN_B3_REQ"},
  59. {{ 0x82, 0x00}, "CONNECT_B3_REQ"},
  60. {{ 0x84, 0x00}, "DISCONNECT_B3_REQ"},
  61. {{ 0x85, 0x00}, "GET_B3_PARAMS_REQ"},
  62. {{ 0x86, 0x00}, "DATA_B3_REQ"},
  63. {{ 0xff, 0x00}, "MANUFACTURER_REQ"},
  64. /* Responses */
  65. {{ 0x01, 0x03}, "RESET_B3_RESP"},
  66. {{ 0x02, 0x03}, "CONNECT_RESP"},
  67. {{ 0x03, 0x03}, "CONNECT_ACTIVE_RESP"},
  68. {{ 0x04, 0x03}, "DISCONNECT_RESP"},
  69. {{ 0x07, 0x03}, "INFO_RESP"},
  70. {{ 0x08, 0x03}, "DATA_RESP"},
  71. {{ 0x82, 0x03}, "CONNECT_B3_RESP"},
  72. {{ 0x83, 0x03}, "CONNECT_B3_ACTIVE_RESP"},
  73. {{ 0x84, 0x03}, "DISCONNECT_B3_RESP"},
  74. {{ 0x86, 0x03}, "DATA_B3_RESP"},
  75. {{ 0xff, 0x03}, "MANUFACTURER_RESP"},
  76. #endif
  77. {{ 0x00, 0x00}, NULL},
  78. };
  79. #define num_valid_msg (sizeof(valid_msg)/sizeof(actcapi_msgdsc))
  80. #define num_valid_imsg 27 /* MANUFACTURER_IND */
  81. /*
  82. * Check for a valid incoming CAPI message.
  83. * Return:
  84. * 0 = Invalid message
  85. * 1 = Valid message, no B-Channel-data
  86. * 2 = Valid message, B-Channel-data
  87. */
  88. int
  89. actcapi_chkhdr(act2000_card * card, actcapi_msghdr *hdr)
  90. {
  91. int i;
  92. if (hdr->applicationID != 1)
  93. return 0;
  94. if (hdr->len < 9)
  95. return 0;
  96. for (i = 0; i < num_valid_imsg; i++)
  97. if ((hdr->cmd.cmd == valid_msg[i].cmd.cmd) &&
  98. (hdr->cmd.subcmd == valid_msg[i].cmd.subcmd)) {
  99. return (i?1:2);
  100. }
  101. return 0;
  102. }
  103. #define ACTCAPI_MKHDR(l, c, s) { \
  104. skb = alloc_skb(l + 8, GFP_ATOMIC); \
  105. if (skb) { \
  106. m = (actcapi_msg *)skb_put(skb, l + 8); \
  107. m->hdr.len = l + 8; \
  108. m->hdr.applicationID = 1; \
  109. m->hdr.cmd.cmd = c; \
  110. m->hdr.cmd.subcmd = s; \
  111. m->hdr.msgnum = actcapi_nextsmsg(card); \
  112. } else m = NULL;\
  113. }
  114. #define ACTCAPI_CHKSKB if (!skb) { \
  115. printk(KERN_WARNING "actcapi: alloc_skb failed\n"); \
  116. return; \
  117. }
  118. #define ACTCAPI_QUEUE_TX { \
  119. actcapi_debug_msg(skb, 1); \
  120. skb_queue_tail(&card->sndq, skb); \
  121. act2000_schedule_tx(card); \
  122. }
  123. int
  124. actcapi_listen_req(act2000_card *card)
  125. {
  126. __u16 eazmask = 0;
  127. int i;
  128. actcapi_msg *m;
  129. struct sk_buff *skb;
  130. for (i = 0; i < ACT2000_BCH; i++)
  131. eazmask |= card->bch[i].eazmask;
  132. ACTCAPI_MKHDR(9, 0x05, 0x00);
  133. if (!skb) {
  134. printk(KERN_WARNING "actcapi: alloc_skb failed\n");
  135. return -ENOMEM;
  136. }
  137. m->msg.listen_req.controller = 0;
  138. m->msg.listen_req.infomask = 0x3f; /* All information */
  139. m->msg.listen_req.eazmask = eazmask;
  140. m->msg.listen_req.simask = (eazmask)?0x86:0; /* All SI's */
  141. ACTCAPI_QUEUE_TX;
  142. return 0;
  143. }
  144. int
  145. actcapi_connect_req(act2000_card *card, act2000_chan *chan, char *phone,
  146. char eaz, int si1, int si2)
  147. {
  148. actcapi_msg *m;
  149. struct sk_buff *skb;
  150. ACTCAPI_MKHDR((11 + strlen(phone)), 0x02, 0x00);
  151. if (!skb) {
  152. printk(KERN_WARNING "actcapi: alloc_skb failed\n");
  153. chan->fsm_state = ACT2000_STATE_NULL;
  154. return -ENOMEM;
  155. }
  156. m->msg.connect_req.controller = 0;
  157. m->msg.connect_req.bchan = 0x83;
  158. m->msg.connect_req.infomask = 0x3f;
  159. m->msg.connect_req.si1 = si1;
  160. m->msg.connect_req.si2 = si2;
  161. m->msg.connect_req.eaz = eaz?eaz:'0';
  162. m->msg.connect_req.addr.len = strlen(phone) + 1;
  163. m->msg.connect_req.addr.tnp = 0x81;
  164. memcpy(m->msg.connect_req.addr.num, phone, strlen(phone));
  165. chan->callref = m->hdr.msgnum;
  166. ACTCAPI_QUEUE_TX;
  167. return 0;
  168. }
  169. static void
  170. actcapi_connect_b3_req(act2000_card *card, act2000_chan *chan)
  171. {
  172. actcapi_msg *m;
  173. struct sk_buff *skb;
  174. ACTCAPI_MKHDR(17, 0x82, 0x00);
  175. ACTCAPI_CHKSKB;
  176. m->msg.connect_b3_req.plci = chan->plci;
  177. memset(&m->msg.connect_b3_req.ncpi, 0,
  178. sizeof(m->msg.connect_b3_req.ncpi));
  179. m->msg.connect_b3_req.ncpi.len = 13;
  180. m->msg.connect_b3_req.ncpi.modulo = 8;
  181. ACTCAPI_QUEUE_TX;
  182. }
  183. /*
  184. * Set net type (1TR6) or (EDSS1)
  185. */
  186. int
  187. actcapi_manufacturer_req_net(act2000_card *card)
  188. {
  189. actcapi_msg *m;
  190. struct sk_buff *skb;
  191. ACTCAPI_MKHDR(5, 0xff, 0x00);
  192. if (!skb) {
  193. printk(KERN_WARNING "actcapi: alloc_skb failed\n");
  194. return -ENOMEM;
  195. }
  196. m->msg.manufacturer_req_net.manuf_msg = 0x11;
  197. m->msg.manufacturer_req_net.controller = 1;
  198. m->msg.manufacturer_req_net.nettype = (card->ptype == ISDN_PTYPE_EURO)?1:0;
  199. ACTCAPI_QUEUE_TX;
  200. printk(KERN_INFO "act2000 %s: D-channel protocol now %s\n",
  201. card->interface.id, (card->ptype == ISDN_PTYPE_EURO)?"euro":"1tr6");
  202. card->interface.features &=
  203. ~(ISDN_FEATURE_P_UNKNOWN | ISDN_FEATURE_P_EURO | ISDN_FEATURE_P_1TR6);
  204. card->interface.features |=
  205. ((card->ptype == ISDN_PTYPE_EURO)?ISDN_FEATURE_P_EURO:ISDN_FEATURE_P_1TR6);
  206. return 0;
  207. }
  208. /*
  209. * Switch V.42 on or off
  210. */
  211. #if 0
  212. int
  213. actcapi_manufacturer_req_v42(act2000_card *card, ulong arg)
  214. {
  215. actcapi_msg *m;
  216. struct sk_buff *skb;
  217. ACTCAPI_MKHDR(8, 0xff, 0x00);
  218. if (!skb) {
  219. printk(KERN_WARNING "actcapi: alloc_skb failed\n");
  220. return -ENOMEM;
  221. }
  222. m->msg.manufacturer_req_v42.manuf_msg = 0x10;
  223. m->msg.manufacturer_req_v42.controller = 0;
  224. m->msg.manufacturer_req_v42.v42control = (arg?1:0);
  225. ACTCAPI_QUEUE_TX;
  226. return 0;
  227. }
  228. #endif /* 0 */
  229. /*
  230. * Set error-handler
  231. */
  232. int
  233. actcapi_manufacturer_req_errh(act2000_card *card)
  234. {
  235. actcapi_msg *m;
  236. struct sk_buff *skb;
  237. ACTCAPI_MKHDR(4, 0xff, 0x00);
  238. if (!skb) {
  239. printk(KERN_WARNING "actcapi: alloc_skb failed\n");
  240. return -ENOMEM;
  241. }
  242. m->msg.manufacturer_req_err.manuf_msg = 0x03;
  243. m->msg.manufacturer_req_err.controller = 0;
  244. ACTCAPI_QUEUE_TX;
  245. return 0;
  246. }
  247. /*
  248. * Set MSN-Mapping.
  249. */
  250. int
  251. actcapi_manufacturer_req_msn(act2000_card *card)
  252. {
  253. msn_entry *p = card->msn_list;
  254. actcapi_msg *m;
  255. struct sk_buff *skb;
  256. int len;
  257. while (p) {
  258. int i;
  259. len = strlen(p->msn);
  260. for (i = 0; i < 2; i++) {
  261. ACTCAPI_MKHDR(6 + len, 0xff, 0x00);
  262. if (!skb) {
  263. printk(KERN_WARNING "actcapi: alloc_skb failed\n");
  264. return -ENOMEM;
  265. }
  266. m->msg.manufacturer_req_msn.manuf_msg = 0x13 + i;
  267. m->msg.manufacturer_req_msn.controller = 0;
  268. m->msg.manufacturer_req_msn.msnmap.eaz = p->eaz;
  269. m->msg.manufacturer_req_msn.msnmap.len = len;
  270. memcpy(m->msg.manufacturer_req_msn.msnmap.msn, p->msn, len);
  271. ACTCAPI_QUEUE_TX;
  272. }
  273. p = p->next;
  274. }
  275. return 0;
  276. }
  277. void
  278. actcapi_select_b2_protocol_req(act2000_card *card, act2000_chan *chan)
  279. {
  280. actcapi_msg *m;
  281. struct sk_buff *skb;
  282. ACTCAPI_MKHDR(10, 0x40, 0x00);
  283. ACTCAPI_CHKSKB;
  284. m->msg.select_b2_protocol_req.plci = chan->plci;
  285. memset(&m->msg.select_b2_protocol_req.dlpd, 0,
  286. sizeof(m->msg.select_b2_protocol_req.dlpd));
  287. m->msg.select_b2_protocol_req.dlpd.len = 6;
  288. switch (chan->l2prot) {
  289. case ISDN_PROTO_L2_TRANS:
  290. m->msg.select_b2_protocol_req.protocol = 0x03;
  291. m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
  292. break;
  293. case ISDN_PROTO_L2_HDLC:
  294. m->msg.select_b2_protocol_req.protocol = 0x02;
  295. m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
  296. break;
  297. case ISDN_PROTO_L2_X75I:
  298. case ISDN_PROTO_L2_X75UI:
  299. case ISDN_PROTO_L2_X75BUI:
  300. m->msg.select_b2_protocol_req.protocol = 0x01;
  301. m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
  302. m->msg.select_b2_protocol_req.dlpd.laa = 3;
  303. m->msg.select_b2_protocol_req.dlpd.lab = 1;
  304. m->msg.select_b2_protocol_req.dlpd.win = 7;
  305. m->msg.select_b2_protocol_req.dlpd.modulo = 8;
  306. break;
  307. }
  308. ACTCAPI_QUEUE_TX;
  309. }
  310. static void
  311. actcapi_select_b3_protocol_req(act2000_card *card, act2000_chan *chan)
  312. {
  313. actcapi_msg *m;
  314. struct sk_buff *skb;
  315. ACTCAPI_MKHDR(17, 0x80, 0x00);
  316. ACTCAPI_CHKSKB;
  317. m->msg.select_b3_protocol_req.plci = chan->plci;
  318. memset(&m->msg.select_b3_protocol_req.ncpd, 0,
  319. sizeof(m->msg.select_b3_protocol_req.ncpd));
  320. switch (chan->l3prot) {
  321. case ISDN_PROTO_L3_TRANS:
  322. m->msg.select_b3_protocol_req.protocol = 0x04;
  323. m->msg.select_b3_protocol_req.ncpd.len = 13;
  324. m->msg.select_b3_protocol_req.ncpd.modulo = 8;
  325. break;
  326. }
  327. ACTCAPI_QUEUE_TX;
  328. }
  329. static void
  330. actcapi_listen_b3_req(act2000_card *card, act2000_chan *chan)
  331. {
  332. actcapi_msg *m;
  333. struct sk_buff *skb;
  334. ACTCAPI_MKHDR(2, 0x81, 0x00);
  335. ACTCAPI_CHKSKB;
  336. m->msg.listen_b3_req.plci = chan->plci;
  337. ACTCAPI_QUEUE_TX;
  338. }
  339. static void
  340. actcapi_disconnect_req(act2000_card *card, act2000_chan *chan)
  341. {
  342. actcapi_msg *m;
  343. struct sk_buff *skb;
  344. ACTCAPI_MKHDR(3, 0x04, 0x00);
  345. ACTCAPI_CHKSKB;
  346. m->msg.disconnect_req.plci = chan->plci;
  347. m->msg.disconnect_req.cause = 0;
  348. ACTCAPI_QUEUE_TX;
  349. }
  350. void
  351. actcapi_disconnect_b3_req(act2000_card *card, act2000_chan *chan)
  352. {
  353. actcapi_msg *m;
  354. struct sk_buff *skb;
  355. ACTCAPI_MKHDR(17, 0x84, 0x00);
  356. ACTCAPI_CHKSKB;
  357. m->msg.disconnect_b3_req.ncci = chan->ncci;
  358. memset(&m->msg.disconnect_b3_req.ncpi, 0,
  359. sizeof(m->msg.disconnect_b3_req.ncpi));
  360. m->msg.disconnect_b3_req.ncpi.len = 13;
  361. m->msg.disconnect_b3_req.ncpi.modulo = 8;
  362. chan->fsm_state = ACT2000_STATE_BHWAIT;
  363. ACTCAPI_QUEUE_TX;
  364. }
  365. void
  366. actcapi_connect_resp(act2000_card *card, act2000_chan *chan, __u8 cause)
  367. {
  368. actcapi_msg *m;
  369. struct sk_buff *skb;
  370. ACTCAPI_MKHDR(3, 0x02, 0x03);
  371. ACTCAPI_CHKSKB;
  372. m->msg.connect_resp.plci = chan->plci;
  373. m->msg.connect_resp.rejectcause = cause;
  374. if (cause) {
  375. chan->fsm_state = ACT2000_STATE_NULL;
  376. chan->plci = 0x8000;
  377. } else
  378. chan->fsm_state = ACT2000_STATE_IWAIT;
  379. ACTCAPI_QUEUE_TX;
  380. }
  381. static void
  382. actcapi_connect_active_resp(act2000_card *card, act2000_chan *chan)
  383. {
  384. actcapi_msg *m;
  385. struct sk_buff *skb;
  386. ACTCAPI_MKHDR(2, 0x03, 0x03);
  387. ACTCAPI_CHKSKB;
  388. m->msg.connect_resp.plci = chan->plci;
  389. if (chan->fsm_state == ACT2000_STATE_IWAIT)
  390. chan->fsm_state = ACT2000_STATE_IBWAIT;
  391. ACTCAPI_QUEUE_TX;
  392. }
  393. static void
  394. actcapi_connect_b3_resp(act2000_card *card, act2000_chan *chan, __u8 rejectcause)
  395. {
  396. actcapi_msg *m;
  397. struct sk_buff *skb;
  398. ACTCAPI_MKHDR((rejectcause?3:17), 0x82, 0x03);
  399. ACTCAPI_CHKSKB;
  400. m->msg.connect_b3_resp.ncci = chan->ncci;
  401. m->msg.connect_b3_resp.rejectcause = rejectcause;
  402. if (!rejectcause) {
  403. memset(&m->msg.connect_b3_resp.ncpi, 0,
  404. sizeof(m->msg.connect_b3_resp.ncpi));
  405. m->msg.connect_b3_resp.ncpi.len = 13;
  406. m->msg.connect_b3_resp.ncpi.modulo = 8;
  407. chan->fsm_state = ACT2000_STATE_BWAIT;
  408. }
  409. ACTCAPI_QUEUE_TX;
  410. }
  411. static void
  412. actcapi_connect_b3_active_resp(act2000_card *card, act2000_chan *chan)
  413. {
  414. actcapi_msg *m;
  415. struct sk_buff *skb;
  416. ACTCAPI_MKHDR(2, 0x83, 0x03);
  417. ACTCAPI_CHKSKB;
  418. m->msg.connect_b3_active_resp.ncci = chan->ncci;
  419. chan->fsm_state = ACT2000_STATE_ACTIVE;
  420. ACTCAPI_QUEUE_TX;
  421. }
  422. static void
  423. actcapi_info_resp(act2000_card *card, act2000_chan *chan)
  424. {
  425. actcapi_msg *m;
  426. struct sk_buff *skb;
  427. ACTCAPI_MKHDR(2, 0x07, 0x03);
  428. ACTCAPI_CHKSKB;
  429. m->msg.info_resp.plci = chan->plci;
  430. ACTCAPI_QUEUE_TX;
  431. }
  432. static void
  433. actcapi_disconnect_b3_resp(act2000_card *card, act2000_chan *chan)
  434. {
  435. actcapi_msg *m;
  436. struct sk_buff *skb;
  437. ACTCAPI_MKHDR(2, 0x84, 0x03);
  438. ACTCAPI_CHKSKB;
  439. m->msg.disconnect_b3_resp.ncci = chan->ncci;
  440. chan->ncci = 0x8000;
  441. chan->queued = 0;
  442. ACTCAPI_QUEUE_TX;
  443. }
  444. static void
  445. actcapi_disconnect_resp(act2000_card *card, act2000_chan *chan)
  446. {
  447. actcapi_msg *m;
  448. struct sk_buff *skb;
  449. ACTCAPI_MKHDR(2, 0x04, 0x03);
  450. ACTCAPI_CHKSKB;
  451. m->msg.disconnect_resp.plci = chan->plci;
  452. chan->plci = 0x8000;
  453. ACTCAPI_QUEUE_TX;
  454. }
  455. static int
  456. new_plci(act2000_card *card, __u16 plci)
  457. {
  458. int i;
  459. for (i = 0; i < ACT2000_BCH; i++)
  460. if (card->bch[i].plci == 0x8000) {
  461. card->bch[i].plci = plci;
  462. return i;
  463. }
  464. return -1;
  465. }
  466. static int
  467. find_plci(act2000_card *card, __u16 plci)
  468. {
  469. int i;
  470. for (i = 0; i < ACT2000_BCH; i++)
  471. if (card->bch[i].plci == plci)
  472. return i;
  473. return -1;
  474. }
  475. static int
  476. find_ncci(act2000_card *card, __u16 ncci)
  477. {
  478. int i;
  479. for (i = 0; i < ACT2000_BCH; i++)
  480. if (card->bch[i].ncci == ncci)
  481. return i;
  482. return -1;
  483. }
  484. static int
  485. find_dialing(act2000_card *card, __u16 callref)
  486. {
  487. int i;
  488. for (i = 0; i < ACT2000_BCH; i++)
  489. if ((card->bch[i].callref == callref) &&
  490. (card->bch[i].fsm_state == ACT2000_STATE_OCALL))
  491. return i;
  492. return -1;
  493. }
  494. static int
  495. actcapi_data_b3_ind(act2000_card *card, struct sk_buff *skb) {
  496. __u16 plci;
  497. __u16 ncci;
  498. __u16 controller;
  499. __u8 blocknr;
  500. int chan;
  501. actcapi_msg *msg = (actcapi_msg *)skb->data;
  502. EVAL_NCCI(msg->msg.data_b3_ind.fakencci, plci, controller, ncci);
  503. chan = find_ncci(card, ncci);
  504. if (chan < 0)
  505. return 0;
  506. if (card->bch[chan].fsm_state != ACT2000_STATE_ACTIVE)
  507. return 0;
  508. if (card->bch[chan].plci != plci)
  509. return 0;
  510. blocknr = msg->msg.data_b3_ind.blocknr;
  511. skb_pull(skb, 19);
  512. card->interface.rcvcallb_skb(card->myid, chan, skb);
  513. if (!(skb = alloc_skb(11, GFP_ATOMIC))) {
  514. printk(KERN_WARNING "actcapi: alloc_skb failed\n");
  515. return 1;
  516. }
  517. msg = (actcapi_msg *)skb_put(skb, 11);
  518. msg->hdr.len = 11;
  519. msg->hdr.applicationID = 1;
  520. msg->hdr.cmd.cmd = 0x86;
  521. msg->hdr.cmd.subcmd = 0x03;
  522. msg->hdr.msgnum = actcapi_nextsmsg(card);
  523. msg->msg.data_b3_resp.ncci = ncci;
  524. msg->msg.data_b3_resp.blocknr = blocknr;
  525. ACTCAPI_QUEUE_TX;
  526. return 1;
  527. }
  528. /*
  529. * Walk over ackq, unlink DATA_B3_REQ from it, if
  530. * ncci and blocknr are matching.
  531. * Decrement queued-bytes counter.
  532. */
  533. static int
  534. handle_ack(act2000_card *card, act2000_chan *chan, __u8 blocknr) {
  535. unsigned long flags;
  536. struct sk_buff *skb;
  537. struct sk_buff *tmp;
  538. struct actcapi_msg *m;
  539. int ret = 0;
  540. spin_lock_irqsave(&card->lock, flags);
  541. skb = skb_peek(&card->ackq);
  542. spin_unlock_irqrestore(&card->lock, flags);
  543. if (!skb) {
  544. printk(KERN_WARNING "act2000: handle_ack nothing found!\n");
  545. return 0;
  546. }
  547. tmp = skb;
  548. while (1) {
  549. m = (actcapi_msg *)tmp->data;
  550. if ((((m->msg.data_b3_req.fakencci >> 8) & 0xff) == chan->ncci) &&
  551. (m->msg.data_b3_req.blocknr == blocknr)) {
  552. /* found corresponding DATA_B3_REQ */
  553. skb_unlink(tmp, &card->ackq);
  554. chan->queued -= m->msg.data_b3_req.datalen;
  555. if (m->msg.data_b3_req.flags)
  556. ret = m->msg.data_b3_req.datalen;
  557. dev_kfree_skb(tmp);
  558. if (chan->queued < 0)
  559. chan->queued = 0;
  560. return ret;
  561. }
  562. spin_lock_irqsave(&card->lock, flags);
  563. tmp = skb_peek((struct sk_buff_head *)tmp);
  564. spin_unlock_irqrestore(&card->lock, flags);
  565. if ((tmp == skb) || (tmp == NULL)) {
  566. /* reached end of queue */
  567. printk(KERN_WARNING "act2000: handle_ack nothing found!\n");
  568. return 0;
  569. }
  570. }
  571. }
  572. void
  573. actcapi_dispatch(act2000_card *card)
  574. {
  575. struct sk_buff *skb;
  576. actcapi_msg *msg;
  577. __u16 ccmd;
  578. int chan;
  579. int len;
  580. act2000_chan *ctmp;
  581. isdn_ctrl cmd;
  582. char tmp[170];
  583. while ((skb = skb_dequeue(&card->rcvq))) {
  584. actcapi_debug_msg(skb, 0);
  585. msg = (actcapi_msg *)skb->data;
  586. ccmd = ((msg->hdr.cmd.cmd << 8) | msg->hdr.cmd.subcmd);
  587. switch (ccmd) {
  588. case 0x8602:
  589. /* DATA_B3_IND */
  590. if (actcapi_data_b3_ind(card, skb))
  591. return;
  592. break;
  593. case 0x8601:
  594. /* DATA_B3_CONF */
  595. chan = find_ncci(card, msg->msg.data_b3_conf.ncci);
  596. if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_ACTIVE)) {
  597. if (msg->msg.data_b3_conf.info != 0)
  598. printk(KERN_WARNING "act2000: DATA_B3_CONF: %04x\n",
  599. msg->msg.data_b3_conf.info);
  600. len = handle_ack(card, &card->bch[chan],
  601. msg->msg.data_b3_conf.blocknr);
  602. if (len) {
  603. cmd.driver = card->myid;
  604. cmd.command = ISDN_STAT_BSENT;
  605. cmd.arg = chan;
  606. cmd.parm.length = len;
  607. card->interface.statcallb(&cmd);
  608. }
  609. }
  610. break;
  611. case 0x0201:
  612. /* CONNECT_CONF */
  613. chan = find_dialing(card, msg->hdr.msgnum);
  614. if (chan >= 0) {
  615. if (msg->msg.connect_conf.info) {
  616. card->bch[chan].fsm_state = ACT2000_STATE_NULL;
  617. cmd.driver = card->myid;
  618. cmd.command = ISDN_STAT_DHUP;
  619. cmd.arg = chan;
  620. card->interface.statcallb(&cmd);
  621. } else {
  622. card->bch[chan].fsm_state = ACT2000_STATE_OWAIT;
  623. card->bch[chan].plci = msg->msg.connect_conf.plci;
  624. }
  625. }
  626. break;
  627. case 0x0202:
  628. /* CONNECT_IND */
  629. chan = new_plci(card, msg->msg.connect_ind.plci);
  630. if (chan < 0) {
  631. ctmp = (act2000_chan *)tmp;
  632. ctmp->plci = msg->msg.connect_ind.plci;
  633. actcapi_connect_resp(card, ctmp, 0x11); /* All Card-Cannels busy */
  634. } else {
  635. card->bch[chan].fsm_state = ACT2000_STATE_ICALL;
  636. cmd.driver = card->myid;
  637. cmd.command = ISDN_STAT_ICALL;
  638. cmd.arg = chan;
  639. cmd.parm.setup.si1 = msg->msg.connect_ind.si1;
  640. cmd.parm.setup.si2 = msg->msg.connect_ind.si2;
  641. if (card->ptype == ISDN_PTYPE_EURO)
  642. strcpy(cmd.parm.setup.eazmsn,
  643. act2000_find_eaz(card, msg->msg.connect_ind.eaz));
  644. else {
  645. cmd.parm.setup.eazmsn[0] = msg->msg.connect_ind.eaz;
  646. cmd.parm.setup.eazmsn[1] = 0;
  647. }
  648. memset(cmd.parm.setup.phone, 0, sizeof(cmd.parm.setup.phone));
  649. memcpy(cmd.parm.setup.phone, msg->msg.connect_ind.addr.num,
  650. msg->msg.connect_ind.addr.len - 1);
  651. cmd.parm.setup.plan = msg->msg.connect_ind.addr.tnp;
  652. cmd.parm.setup.screen = 0;
  653. if (card->interface.statcallb(&cmd) == 2)
  654. actcapi_connect_resp(card, &card->bch[chan], 0x15); /* Reject Call */
  655. }
  656. break;
  657. case 0x0302:
  658. /* CONNECT_ACTIVE_IND */
  659. chan = find_plci(card, msg->msg.connect_active_ind.plci);
  660. if (chan >= 0)
  661. switch (card->bch[chan].fsm_state) {
  662. case ACT2000_STATE_IWAIT:
  663. actcapi_connect_active_resp(card, &card->bch[chan]);
  664. break;
  665. case ACT2000_STATE_OWAIT:
  666. actcapi_connect_active_resp(card, &card->bch[chan]);
  667. actcapi_select_b2_protocol_req(card, &card->bch[chan]);
  668. break;
  669. }
  670. break;
  671. case 0x8202:
  672. /* CONNECT_B3_IND */
  673. chan = find_plci(card, msg->msg.connect_b3_ind.plci);
  674. if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_IBWAIT)) {
  675. card->bch[chan].ncci = msg->msg.connect_b3_ind.ncci;
  676. actcapi_connect_b3_resp(card, &card->bch[chan], 0);
  677. } else {
  678. ctmp = (act2000_chan *)tmp;
  679. ctmp->ncci = msg->msg.connect_b3_ind.ncci;
  680. actcapi_connect_b3_resp(card, ctmp, 0x11); /* All Card-Cannels busy */
  681. }
  682. break;
  683. case 0x8302:
  684. /* CONNECT_B3_ACTIVE_IND */
  685. chan = find_ncci(card, msg->msg.connect_b3_active_ind.ncci);
  686. if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BWAIT)) {
  687. actcapi_connect_b3_active_resp(card, &card->bch[chan]);
  688. cmd.driver = card->myid;
  689. cmd.command = ISDN_STAT_BCONN;
  690. cmd.arg = chan;
  691. card->interface.statcallb(&cmd);
  692. }
  693. break;
  694. case 0x8402:
  695. /* DISCONNECT_B3_IND */
  696. chan = find_ncci(card, msg->msg.disconnect_b3_ind.ncci);
  697. if (chan >= 0) {
  698. ctmp = &card->bch[chan];
  699. actcapi_disconnect_b3_resp(card, ctmp);
  700. switch (ctmp->fsm_state) {
  701. case ACT2000_STATE_ACTIVE:
  702. ctmp->fsm_state = ACT2000_STATE_DHWAIT2;
  703. cmd.driver = card->myid;
  704. cmd.command = ISDN_STAT_BHUP;
  705. cmd.arg = chan;
  706. card->interface.statcallb(&cmd);
  707. break;
  708. case ACT2000_STATE_BHWAIT2:
  709. actcapi_disconnect_req(card, ctmp);
  710. ctmp->fsm_state = ACT2000_STATE_DHWAIT;
  711. cmd.driver = card->myid;
  712. cmd.command = ISDN_STAT_BHUP;
  713. cmd.arg = chan;
  714. card->interface.statcallb(&cmd);
  715. break;
  716. }
  717. }
  718. break;
  719. case 0x0402:
  720. /* DISCONNECT_IND */
  721. chan = find_plci(card, msg->msg.disconnect_ind.plci);
  722. if (chan >= 0) {
  723. ctmp = &card->bch[chan];
  724. actcapi_disconnect_resp(card, ctmp);
  725. ctmp->fsm_state = ACT2000_STATE_NULL;
  726. cmd.driver = card->myid;
  727. cmd.command = ISDN_STAT_DHUP;
  728. cmd.arg = chan;
  729. card->interface.statcallb(&cmd);
  730. } else {
  731. ctmp = (act2000_chan *)tmp;
  732. ctmp->plci = msg->msg.disconnect_ind.plci;
  733. actcapi_disconnect_resp(card, ctmp);
  734. }
  735. break;
  736. case 0x4001:
  737. /* SELECT_B2_PROTOCOL_CONF */
  738. chan = find_plci(card, msg->msg.select_b2_protocol_conf.plci);
  739. if (chan >= 0)
  740. switch (card->bch[chan].fsm_state) {
  741. case ACT2000_STATE_ICALL:
  742. case ACT2000_STATE_OWAIT:
  743. ctmp = &card->bch[chan];
  744. if (msg->msg.select_b2_protocol_conf.info == 0)
  745. actcapi_select_b3_protocol_req(card, ctmp);
  746. else {
  747. ctmp->fsm_state = ACT2000_STATE_NULL;
  748. cmd.driver = card->myid;
  749. cmd.command = ISDN_STAT_DHUP;
  750. cmd.arg = chan;
  751. card->interface.statcallb(&cmd);
  752. }
  753. break;
  754. }
  755. break;
  756. case 0x8001:
  757. /* SELECT_B3_PROTOCOL_CONF */
  758. chan = find_plci(card, msg->msg.select_b3_protocol_conf.plci);
  759. if (chan >= 0)
  760. switch (card->bch[chan].fsm_state) {
  761. case ACT2000_STATE_ICALL:
  762. case ACT2000_STATE_OWAIT:
  763. ctmp = &card->bch[chan];
  764. if (msg->msg.select_b3_protocol_conf.info == 0)
  765. actcapi_listen_b3_req(card, ctmp);
  766. else {
  767. ctmp->fsm_state = ACT2000_STATE_NULL;
  768. cmd.driver = card->myid;
  769. cmd.command = ISDN_STAT_DHUP;
  770. cmd.arg = chan;
  771. card->interface.statcallb(&cmd);
  772. }
  773. }
  774. break;
  775. case 0x8101:
  776. /* LISTEN_B3_CONF */
  777. chan = find_plci(card, msg->msg.listen_b3_conf.plci);
  778. if (chan >= 0)
  779. switch (card->bch[chan].fsm_state) {
  780. case ACT2000_STATE_ICALL:
  781. ctmp = &card->bch[chan];
  782. if (msg->msg.listen_b3_conf.info == 0)
  783. actcapi_connect_resp(card, ctmp, 0);
  784. else {
  785. ctmp->fsm_state = ACT2000_STATE_NULL;
  786. cmd.driver = card->myid;
  787. cmd.command = ISDN_STAT_DHUP;
  788. cmd.arg = chan;
  789. card->interface.statcallb(&cmd);
  790. }
  791. break;
  792. case ACT2000_STATE_OWAIT:
  793. ctmp = &card->bch[chan];
  794. if (msg->msg.listen_b3_conf.info == 0) {
  795. actcapi_connect_b3_req(card, ctmp);
  796. ctmp->fsm_state = ACT2000_STATE_OBWAIT;
  797. cmd.driver = card->myid;
  798. cmd.command = ISDN_STAT_DCONN;
  799. cmd.arg = chan;
  800. card->interface.statcallb(&cmd);
  801. } else {
  802. ctmp->fsm_state = ACT2000_STATE_NULL;
  803. cmd.driver = card->myid;
  804. cmd.command = ISDN_STAT_DHUP;
  805. cmd.arg = chan;
  806. card->interface.statcallb(&cmd);
  807. }
  808. break;
  809. }
  810. break;
  811. case 0x8201:
  812. /* CONNECT_B3_CONF */
  813. chan = find_plci(card, msg->msg.connect_b3_conf.plci);
  814. if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_OBWAIT)) {
  815. ctmp = &card->bch[chan];
  816. if (msg->msg.connect_b3_conf.info) {
  817. ctmp->fsm_state = ACT2000_STATE_NULL;
  818. cmd.driver = card->myid;
  819. cmd.command = ISDN_STAT_DHUP;
  820. cmd.arg = chan;
  821. card->interface.statcallb(&cmd);
  822. } else {
  823. ctmp->ncci = msg->msg.connect_b3_conf.ncci;
  824. ctmp->fsm_state = ACT2000_STATE_BWAIT;
  825. }
  826. }
  827. break;
  828. case 0x8401:
  829. /* DISCONNECT_B3_CONF */
  830. chan = find_ncci(card, msg->msg.disconnect_b3_conf.ncci);
  831. if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BHWAIT))
  832. card->bch[chan].fsm_state = ACT2000_STATE_BHWAIT2;
  833. break;
  834. case 0x0702:
  835. /* INFO_IND */
  836. chan = find_plci(card, msg->msg.info_ind.plci);
  837. if (chan >= 0)
  838. /* TODO: Eval Charging info / cause */
  839. actcapi_info_resp(card, &card->bch[chan]);
  840. break;
  841. case 0x0401:
  842. /* LISTEN_CONF */
  843. case 0x0501:
  844. /* LISTEN_CONF */
  845. case 0xff01:
  846. /* MANUFACTURER_CONF */
  847. break;
  848. case 0xff02:
  849. /* MANUFACTURER_IND */
  850. if (msg->msg.manuf_msg == 3) {
  851. memset(tmp, 0, sizeof(tmp));
  852. strncpy(tmp,
  853. &msg->msg.manufacturer_ind_err.errstring,
  854. msg->hdr.len - 16);
  855. if (msg->msg.manufacturer_ind_err.errcode)
  856. printk(KERN_WARNING "act2000: %s\n", tmp);
  857. else {
  858. printk(KERN_DEBUG "act2000: %s\n", tmp);
  859. if ((!strncmp(tmp, "INFO: Trace buffer con", 22)) ||
  860. (!strncmp(tmp, "INFO: Compile Date/Tim", 22))) {
  861. card->flags |= ACT2000_FLAGS_RUNNING;
  862. cmd.command = ISDN_STAT_RUN;
  863. cmd.driver = card->myid;
  864. cmd.arg = 0;
  865. actcapi_manufacturer_req_net(card);
  866. actcapi_manufacturer_req_msn(card);
  867. actcapi_listen_req(card);
  868. card->interface.statcallb(&cmd);
  869. }
  870. }
  871. }
  872. break;
  873. default:
  874. printk(KERN_WARNING "act2000: UNHANDLED Message %04x\n", ccmd);
  875. break;
  876. }
  877. dev_kfree_skb(skb);
  878. }
  879. }
  880. #ifdef DEBUG_MSG
  881. static void
  882. actcapi_debug_caddr(actcapi_addr *addr)
  883. {
  884. char tmp[30];
  885. printk(KERN_DEBUG " Alen = %d\n", addr->len);
  886. if (addr->len > 0)
  887. printk(KERN_DEBUG " Atnp = 0x%02x\n", addr->tnp);
  888. if (addr->len > 1) {
  889. memset(tmp, 0, 30);
  890. memcpy(tmp, addr->num, addr->len - 1);
  891. printk(KERN_DEBUG " Anum = '%s'\n", tmp);
  892. }
  893. }
  894. static void
  895. actcapi_debug_ncpi(actcapi_ncpi *ncpi)
  896. {
  897. printk(KERN_DEBUG " ncpi.len = %d\n", ncpi->len);
  898. if (ncpi->len >= 2)
  899. printk(KERN_DEBUG " ncpi.lic = 0x%04x\n", ncpi->lic);
  900. if (ncpi->len >= 4)
  901. printk(KERN_DEBUG " ncpi.hic = 0x%04x\n", ncpi->hic);
  902. if (ncpi->len >= 6)
  903. printk(KERN_DEBUG " ncpi.ltc = 0x%04x\n", ncpi->ltc);
  904. if (ncpi->len >= 8)
  905. printk(KERN_DEBUG " ncpi.htc = 0x%04x\n", ncpi->htc);
  906. if (ncpi->len >= 10)
  907. printk(KERN_DEBUG " ncpi.loc = 0x%04x\n", ncpi->loc);
  908. if (ncpi->len >= 12)
  909. printk(KERN_DEBUG " ncpi.hoc = 0x%04x\n", ncpi->hoc);
  910. if (ncpi->len >= 13)
  911. printk(KERN_DEBUG " ncpi.mod = %d\n", ncpi->modulo);
  912. }
  913. static void
  914. actcapi_debug_dlpd(actcapi_dlpd *dlpd)
  915. {
  916. printk(KERN_DEBUG " dlpd.len = %d\n", dlpd->len);
  917. if (dlpd->len >= 2)
  918. printk(KERN_DEBUG " dlpd.dlen = 0x%04x\n", dlpd->dlen);
  919. if (dlpd->len >= 3)
  920. printk(KERN_DEBUG " dlpd.laa = 0x%02x\n", dlpd->laa);
  921. if (dlpd->len >= 4)
  922. printk(KERN_DEBUG " dlpd.lab = 0x%02x\n", dlpd->lab);
  923. if (dlpd->len >= 5)
  924. printk(KERN_DEBUG " dlpd.modulo = %d\n", dlpd->modulo);
  925. if (dlpd->len >= 6)
  926. printk(KERN_DEBUG " dlpd.win = %d\n", dlpd->win);
  927. }
  928. #ifdef DEBUG_DUMP_SKB
  929. static void dump_skb(struct sk_buff *skb) {
  930. char tmp[80];
  931. char *p = skb->data;
  932. char *t = tmp;
  933. int i;
  934. for (i = 0; i < skb->len; i++) {
  935. t += sprintf(t, "%02x ", *p++ & 0xff);
  936. if ((i & 0x0f) == 8) {
  937. printk(KERN_DEBUG "dump: %s\n", tmp);
  938. t = tmp;
  939. }
  940. }
  941. if (i & 0x07)
  942. printk(KERN_DEBUG "dump: %s\n", tmp);
  943. }
  944. #endif
  945. void
  946. actcapi_debug_msg(struct sk_buff *skb, int direction)
  947. {
  948. actcapi_msg *msg = (actcapi_msg *)skb->data;
  949. char *descr;
  950. int i;
  951. char tmp[170];
  952. #ifndef DEBUG_DATA_MSG
  953. if (msg->hdr.cmd.cmd == 0x86)
  954. return;
  955. #endif
  956. descr = "INVALID";
  957. #ifdef DEBUG_DUMP_SKB
  958. dump_skb(skb);
  959. #endif
  960. for (i = 0; i < num_valid_msg; i++)
  961. if ((msg->hdr.cmd.cmd == valid_msg[i].cmd.cmd) &&
  962. (msg->hdr.cmd.subcmd == valid_msg[i].cmd.subcmd)) {
  963. descr = valid_msg[i].description;
  964. break;
  965. }
  966. printk(KERN_DEBUG "%s %s msg\n", direction?"Outgoing":"Incoming", descr);
  967. printk(KERN_DEBUG " ApplID = %d\n", msg->hdr.applicationID);
  968. printk(KERN_DEBUG " Len = %d\n", msg->hdr.len);
  969. printk(KERN_DEBUG " MsgNum = 0x%04x\n", msg->hdr.msgnum);
  970. printk(KERN_DEBUG " Cmd = 0x%02x\n", msg->hdr.cmd.cmd);
  971. printk(KERN_DEBUG " SubCmd = 0x%02x\n", msg->hdr.cmd.subcmd);
  972. switch (i) {
  973. case 0:
  974. /* DATA B3 IND */
  975. printk(KERN_DEBUG " BLOCK = 0x%02x\n",
  976. msg->msg.data_b3_ind.blocknr);
  977. break;
  978. case 2:
  979. /* CONNECT CONF */
  980. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  981. msg->msg.connect_conf.plci);
  982. printk(KERN_DEBUG " Info = 0x%04x\n",
  983. msg->msg.connect_conf.info);
  984. break;
  985. case 3:
  986. /* CONNECT IND */
  987. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  988. msg->msg.connect_ind.plci);
  989. printk(KERN_DEBUG " Contr = %d\n",
  990. msg->msg.connect_ind.controller);
  991. printk(KERN_DEBUG " SI1 = %d\n",
  992. msg->msg.connect_ind.si1);
  993. printk(KERN_DEBUG " SI2 = %d\n",
  994. msg->msg.connect_ind.si2);
  995. printk(KERN_DEBUG " EAZ = '%c'\n",
  996. msg->msg.connect_ind.eaz);
  997. actcapi_debug_caddr(&msg->msg.connect_ind.addr);
  998. break;
  999. case 5:
  1000. /* CONNECT ACTIVE IND */
  1001. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1002. msg->msg.connect_active_ind.plci);
  1003. actcapi_debug_caddr(&msg->msg.connect_active_ind.addr);
  1004. break;
  1005. case 8:
  1006. /* LISTEN CONF */
  1007. printk(KERN_DEBUG " Contr = %d\n",
  1008. msg->msg.listen_conf.controller);
  1009. printk(KERN_DEBUG " Info = 0x%04x\n",
  1010. msg->msg.listen_conf.info);
  1011. break;
  1012. case 11:
  1013. /* INFO IND */
  1014. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1015. msg->msg.info_ind.plci);
  1016. printk(KERN_DEBUG " Imsk = 0x%04x\n",
  1017. msg->msg.info_ind.nr.mask);
  1018. if (msg->hdr.len > 12) {
  1019. int l = msg->hdr.len - 12;
  1020. int j;
  1021. char *p = tmp;
  1022. for (j = 0; j < l ; j++)
  1023. p += sprintf(p, "%02x ", msg->msg.info_ind.el.display[j]);
  1024. printk(KERN_DEBUG " D = '%s'\n", tmp);
  1025. }
  1026. break;
  1027. case 14:
  1028. /* SELECT B2 PROTOCOL CONF */
  1029. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1030. msg->msg.select_b2_protocol_conf.plci);
  1031. printk(KERN_DEBUG " Info = 0x%04x\n",
  1032. msg->msg.select_b2_protocol_conf.info);
  1033. break;
  1034. case 15:
  1035. /* SELECT B3 PROTOCOL CONF */
  1036. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1037. msg->msg.select_b3_protocol_conf.plci);
  1038. printk(KERN_DEBUG " Info = 0x%04x\n",
  1039. msg->msg.select_b3_protocol_conf.info);
  1040. break;
  1041. case 16:
  1042. /* LISTEN B3 CONF */
  1043. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1044. msg->msg.listen_b3_conf.plci);
  1045. printk(KERN_DEBUG " Info = 0x%04x\n",
  1046. msg->msg.listen_b3_conf.info);
  1047. break;
  1048. case 18:
  1049. /* CONNECT B3 IND */
  1050. printk(KERN_DEBUG " NCCI = 0x%04x\n",
  1051. msg->msg.connect_b3_ind.ncci);
  1052. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1053. msg->msg.connect_b3_ind.plci);
  1054. actcapi_debug_ncpi(&msg->msg.connect_b3_ind.ncpi);
  1055. break;
  1056. case 19:
  1057. /* CONNECT B3 ACTIVE IND */
  1058. printk(KERN_DEBUG " NCCI = 0x%04x\n",
  1059. msg->msg.connect_b3_active_ind.ncci);
  1060. actcapi_debug_ncpi(&msg->msg.connect_b3_active_ind.ncpi);
  1061. break;
  1062. case 26:
  1063. /* MANUFACTURER IND */
  1064. printk(KERN_DEBUG " Mmsg = 0x%02x\n",
  1065. msg->msg.manufacturer_ind_err.manuf_msg);
  1066. switch (msg->msg.manufacturer_ind_err.manuf_msg) {
  1067. case 3:
  1068. printk(KERN_DEBUG " Contr = %d\n",
  1069. msg->msg.manufacturer_ind_err.controller);
  1070. printk(KERN_DEBUG " Code = 0x%08x\n",
  1071. msg->msg.manufacturer_ind_err.errcode);
  1072. memset(tmp, 0, sizeof(tmp));
  1073. strncpy(tmp, &msg->msg.manufacturer_ind_err.errstring,
  1074. msg->hdr.len - 16);
  1075. printk(KERN_DEBUG " Emsg = '%s'\n", tmp);
  1076. break;
  1077. }
  1078. break;
  1079. case 30:
  1080. /* LISTEN REQ */
  1081. printk(KERN_DEBUG " Imsk = 0x%08x\n",
  1082. msg->msg.listen_req.infomask);
  1083. printk(KERN_DEBUG " Emsk = 0x%04x\n",
  1084. msg->msg.listen_req.eazmask);
  1085. printk(KERN_DEBUG " Smsk = 0x%04x\n",
  1086. msg->msg.listen_req.simask);
  1087. break;
  1088. case 35:
  1089. /* SELECT_B2_PROTOCOL_REQ */
  1090. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1091. msg->msg.select_b2_protocol_req.plci);
  1092. printk(KERN_DEBUG " prot = 0x%02x\n",
  1093. msg->msg.select_b2_protocol_req.protocol);
  1094. if (msg->hdr.len >= 11)
  1095. printk(KERN_DEBUG "No dlpd\n");
  1096. else
  1097. actcapi_debug_dlpd(&msg->msg.select_b2_protocol_req.dlpd);
  1098. break;
  1099. case 44:
  1100. /* CONNECT RESP */
  1101. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1102. msg->msg.connect_resp.plci);
  1103. printk(KERN_DEBUG " CAUSE = 0x%02x\n",
  1104. msg->msg.connect_resp.rejectcause);
  1105. break;
  1106. case 45:
  1107. /* CONNECT ACTIVE RESP */
  1108. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1109. msg->msg.connect_active_resp.plci);
  1110. break;
  1111. }
  1112. }
  1113. #endif