capi.c 32 KB

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