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_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(struct work_struct *work)
  574. {
  575. struct act2000_card *card =
  576. container_of(work, struct act2000_card, rcv_tq);
  577. struct sk_buff *skb;
  578. actcapi_msg *msg;
  579. __u16 ccmd;
  580. int chan;
  581. int len;
  582. act2000_chan *ctmp;
  583. isdn_ctrl cmd;
  584. char tmp[170];
  585. while ((skb = skb_dequeue(&card->rcvq))) {
  586. actcapi_debug_msg(skb, 0);
  587. msg = (actcapi_msg *)skb->data;
  588. ccmd = ((msg->hdr.cmd.cmd << 8) | msg->hdr.cmd.subcmd);
  589. switch (ccmd) {
  590. case 0x8602:
  591. /* DATA_B3_IND */
  592. if (actcapi_data_b3_ind(card, skb))
  593. return;
  594. break;
  595. case 0x8601:
  596. /* DATA_B3_CONF */
  597. chan = find_ncci(card, msg->msg.data_b3_conf.ncci);
  598. if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_ACTIVE)) {
  599. if (msg->msg.data_b3_conf.info != 0)
  600. printk(KERN_WARNING "act2000: DATA_B3_CONF: %04x\n",
  601. msg->msg.data_b3_conf.info);
  602. len = handle_ack(card, &card->bch[chan],
  603. msg->msg.data_b3_conf.blocknr);
  604. if (len) {
  605. cmd.driver = card->myid;
  606. cmd.command = ISDN_STAT_BSENT;
  607. cmd.arg = chan;
  608. cmd.parm.length = len;
  609. card->interface.statcallb(&cmd);
  610. }
  611. }
  612. break;
  613. case 0x0201:
  614. /* CONNECT_CONF */
  615. chan = find_dialing(card, msg->hdr.msgnum);
  616. if (chan >= 0) {
  617. if (msg->msg.connect_conf.info) {
  618. card->bch[chan].fsm_state = ACT2000_STATE_NULL;
  619. cmd.driver = card->myid;
  620. cmd.command = ISDN_STAT_DHUP;
  621. cmd.arg = chan;
  622. card->interface.statcallb(&cmd);
  623. } else {
  624. card->bch[chan].fsm_state = ACT2000_STATE_OWAIT;
  625. card->bch[chan].plci = msg->msg.connect_conf.plci;
  626. }
  627. }
  628. break;
  629. case 0x0202:
  630. /* CONNECT_IND */
  631. chan = new_plci(card, msg->msg.connect_ind.plci);
  632. if (chan < 0) {
  633. ctmp = (act2000_chan *)tmp;
  634. ctmp->plci = msg->msg.connect_ind.plci;
  635. actcapi_connect_resp(card, ctmp, 0x11); /* All Card-Cannels busy */
  636. } else {
  637. card->bch[chan].fsm_state = ACT2000_STATE_ICALL;
  638. cmd.driver = card->myid;
  639. cmd.command = ISDN_STAT_ICALL;
  640. cmd.arg = chan;
  641. cmd.parm.setup.si1 = msg->msg.connect_ind.si1;
  642. cmd.parm.setup.si2 = msg->msg.connect_ind.si2;
  643. if (card->ptype == ISDN_PTYPE_EURO)
  644. strcpy(cmd.parm.setup.eazmsn,
  645. act2000_find_eaz(card, msg->msg.connect_ind.eaz));
  646. else {
  647. cmd.parm.setup.eazmsn[0] = msg->msg.connect_ind.eaz;
  648. cmd.parm.setup.eazmsn[1] = 0;
  649. }
  650. memset(cmd.parm.setup.phone, 0, sizeof(cmd.parm.setup.phone));
  651. memcpy(cmd.parm.setup.phone, msg->msg.connect_ind.addr.num,
  652. msg->msg.connect_ind.addr.len - 1);
  653. cmd.parm.setup.plan = msg->msg.connect_ind.addr.tnp;
  654. cmd.parm.setup.screen = 0;
  655. if (card->interface.statcallb(&cmd) == 2)
  656. actcapi_connect_resp(card, &card->bch[chan], 0x15); /* Reject Call */
  657. }
  658. break;
  659. case 0x0302:
  660. /* CONNECT_ACTIVE_IND */
  661. chan = find_plci(card, msg->msg.connect_active_ind.plci);
  662. if (chan >= 0)
  663. switch (card->bch[chan].fsm_state) {
  664. case ACT2000_STATE_IWAIT:
  665. actcapi_connect_active_resp(card, &card->bch[chan]);
  666. break;
  667. case ACT2000_STATE_OWAIT:
  668. actcapi_connect_active_resp(card, &card->bch[chan]);
  669. actcapi_select_b2_protocol_req(card, &card->bch[chan]);
  670. break;
  671. }
  672. break;
  673. case 0x8202:
  674. /* CONNECT_B3_IND */
  675. chan = find_plci(card, msg->msg.connect_b3_ind.plci);
  676. if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_IBWAIT)) {
  677. card->bch[chan].ncci = msg->msg.connect_b3_ind.ncci;
  678. actcapi_connect_b3_resp(card, &card->bch[chan], 0);
  679. } else {
  680. ctmp = (act2000_chan *)tmp;
  681. ctmp->ncci = msg->msg.connect_b3_ind.ncci;
  682. actcapi_connect_b3_resp(card, ctmp, 0x11); /* All Card-Cannels busy */
  683. }
  684. break;
  685. case 0x8302:
  686. /* CONNECT_B3_ACTIVE_IND */
  687. chan = find_ncci(card, msg->msg.connect_b3_active_ind.ncci);
  688. if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BWAIT)) {
  689. actcapi_connect_b3_active_resp(card, &card->bch[chan]);
  690. cmd.driver = card->myid;
  691. cmd.command = ISDN_STAT_BCONN;
  692. cmd.arg = chan;
  693. card->interface.statcallb(&cmd);
  694. }
  695. break;
  696. case 0x8402:
  697. /* DISCONNECT_B3_IND */
  698. chan = find_ncci(card, msg->msg.disconnect_b3_ind.ncci);
  699. if (chan >= 0) {
  700. ctmp = &card->bch[chan];
  701. actcapi_disconnect_b3_resp(card, ctmp);
  702. switch (ctmp->fsm_state) {
  703. case ACT2000_STATE_ACTIVE:
  704. ctmp->fsm_state = ACT2000_STATE_DHWAIT2;
  705. cmd.driver = card->myid;
  706. cmd.command = ISDN_STAT_BHUP;
  707. cmd.arg = chan;
  708. card->interface.statcallb(&cmd);
  709. break;
  710. case ACT2000_STATE_BHWAIT2:
  711. actcapi_disconnect_req(card, ctmp);
  712. ctmp->fsm_state = ACT2000_STATE_DHWAIT;
  713. cmd.driver = card->myid;
  714. cmd.command = ISDN_STAT_BHUP;
  715. cmd.arg = chan;
  716. card->interface.statcallb(&cmd);
  717. break;
  718. }
  719. }
  720. break;
  721. case 0x0402:
  722. /* DISCONNECT_IND */
  723. chan = find_plci(card, msg->msg.disconnect_ind.plci);
  724. if (chan >= 0) {
  725. ctmp = &card->bch[chan];
  726. actcapi_disconnect_resp(card, ctmp);
  727. ctmp->fsm_state = ACT2000_STATE_NULL;
  728. cmd.driver = card->myid;
  729. cmd.command = ISDN_STAT_DHUP;
  730. cmd.arg = chan;
  731. card->interface.statcallb(&cmd);
  732. } else {
  733. ctmp = (act2000_chan *)tmp;
  734. ctmp->plci = msg->msg.disconnect_ind.plci;
  735. actcapi_disconnect_resp(card, ctmp);
  736. }
  737. break;
  738. case 0x4001:
  739. /* SELECT_B2_PROTOCOL_CONF */
  740. chan = find_plci(card, msg->msg.select_b2_protocol_conf.plci);
  741. if (chan >= 0)
  742. switch (card->bch[chan].fsm_state) {
  743. case ACT2000_STATE_ICALL:
  744. case ACT2000_STATE_OWAIT:
  745. ctmp = &card->bch[chan];
  746. if (msg->msg.select_b2_protocol_conf.info == 0)
  747. actcapi_select_b3_protocol_req(card, ctmp);
  748. else {
  749. ctmp->fsm_state = ACT2000_STATE_NULL;
  750. cmd.driver = card->myid;
  751. cmd.command = ISDN_STAT_DHUP;
  752. cmd.arg = chan;
  753. card->interface.statcallb(&cmd);
  754. }
  755. break;
  756. }
  757. break;
  758. case 0x8001:
  759. /* SELECT_B3_PROTOCOL_CONF */
  760. chan = find_plci(card, msg->msg.select_b3_protocol_conf.plci);
  761. if (chan >= 0)
  762. switch (card->bch[chan].fsm_state) {
  763. case ACT2000_STATE_ICALL:
  764. case ACT2000_STATE_OWAIT:
  765. ctmp = &card->bch[chan];
  766. if (msg->msg.select_b3_protocol_conf.info == 0)
  767. actcapi_listen_b3_req(card, ctmp);
  768. else {
  769. ctmp->fsm_state = ACT2000_STATE_NULL;
  770. cmd.driver = card->myid;
  771. cmd.command = ISDN_STAT_DHUP;
  772. cmd.arg = chan;
  773. card->interface.statcallb(&cmd);
  774. }
  775. }
  776. break;
  777. case 0x8101:
  778. /* LISTEN_B3_CONF */
  779. chan = find_plci(card, msg->msg.listen_b3_conf.plci);
  780. if (chan >= 0)
  781. switch (card->bch[chan].fsm_state) {
  782. case ACT2000_STATE_ICALL:
  783. ctmp = &card->bch[chan];
  784. if (msg->msg.listen_b3_conf.info == 0)
  785. actcapi_connect_resp(card, ctmp, 0);
  786. else {
  787. ctmp->fsm_state = ACT2000_STATE_NULL;
  788. cmd.driver = card->myid;
  789. cmd.command = ISDN_STAT_DHUP;
  790. cmd.arg = chan;
  791. card->interface.statcallb(&cmd);
  792. }
  793. break;
  794. case ACT2000_STATE_OWAIT:
  795. ctmp = &card->bch[chan];
  796. if (msg->msg.listen_b3_conf.info == 0) {
  797. actcapi_connect_b3_req(card, ctmp);
  798. ctmp->fsm_state = ACT2000_STATE_OBWAIT;
  799. cmd.driver = card->myid;
  800. cmd.command = ISDN_STAT_DCONN;
  801. cmd.arg = chan;
  802. card->interface.statcallb(&cmd);
  803. } else {
  804. ctmp->fsm_state = ACT2000_STATE_NULL;
  805. cmd.driver = card->myid;
  806. cmd.command = ISDN_STAT_DHUP;
  807. cmd.arg = chan;
  808. card->interface.statcallb(&cmd);
  809. }
  810. break;
  811. }
  812. break;
  813. case 0x8201:
  814. /* CONNECT_B3_CONF */
  815. chan = find_plci(card, msg->msg.connect_b3_conf.plci);
  816. if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_OBWAIT)) {
  817. ctmp = &card->bch[chan];
  818. if (msg->msg.connect_b3_conf.info) {
  819. ctmp->fsm_state = ACT2000_STATE_NULL;
  820. cmd.driver = card->myid;
  821. cmd.command = ISDN_STAT_DHUP;
  822. cmd.arg = chan;
  823. card->interface.statcallb(&cmd);
  824. } else {
  825. ctmp->ncci = msg->msg.connect_b3_conf.ncci;
  826. ctmp->fsm_state = ACT2000_STATE_BWAIT;
  827. }
  828. }
  829. break;
  830. case 0x8401:
  831. /* DISCONNECT_B3_CONF */
  832. chan = find_ncci(card, msg->msg.disconnect_b3_conf.ncci);
  833. if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BHWAIT))
  834. card->bch[chan].fsm_state = ACT2000_STATE_BHWAIT2;
  835. break;
  836. case 0x0702:
  837. /* INFO_IND */
  838. chan = find_plci(card, msg->msg.info_ind.plci);
  839. if (chan >= 0)
  840. /* TODO: Eval Charging info / cause */
  841. actcapi_info_resp(card, &card->bch[chan]);
  842. break;
  843. case 0x0401:
  844. /* LISTEN_CONF */
  845. case 0x0501:
  846. /* LISTEN_CONF */
  847. case 0xff01:
  848. /* MANUFACTURER_CONF */
  849. break;
  850. case 0xff02:
  851. /* MANUFACTURER_IND */
  852. if (msg->msg.manuf_msg == 3) {
  853. memset(tmp, 0, sizeof(tmp));
  854. strncpy(tmp,
  855. &msg->msg.manufacturer_ind_err.errstring,
  856. msg->hdr.len - 16);
  857. if (msg->msg.manufacturer_ind_err.errcode)
  858. printk(KERN_WARNING "act2000: %s\n", tmp);
  859. else {
  860. printk(KERN_DEBUG "act2000: %s\n", tmp);
  861. if ((!strncmp(tmp, "INFO: Trace buffer con", 22)) ||
  862. (!strncmp(tmp, "INFO: Compile Date/Tim", 22))) {
  863. card->flags |= ACT2000_FLAGS_RUNNING;
  864. cmd.command = ISDN_STAT_RUN;
  865. cmd.driver = card->myid;
  866. cmd.arg = 0;
  867. actcapi_manufacturer_req_net(card);
  868. actcapi_manufacturer_req_msn(card);
  869. actcapi_listen_req(card);
  870. card->interface.statcallb(&cmd);
  871. }
  872. }
  873. }
  874. break;
  875. default:
  876. printk(KERN_WARNING "act2000: UNHANDLED Message %04x\n", ccmd);
  877. break;
  878. }
  879. dev_kfree_skb(skb);
  880. }
  881. }
  882. #ifdef DEBUG_MSG
  883. static void
  884. actcapi_debug_caddr(actcapi_addr *addr)
  885. {
  886. char tmp[30];
  887. printk(KERN_DEBUG " Alen = %d\n", addr->len);
  888. if (addr->len > 0)
  889. printk(KERN_DEBUG " Atnp = 0x%02x\n", addr->tnp);
  890. if (addr->len > 1) {
  891. memset(tmp, 0, 30);
  892. memcpy(tmp, addr->num, addr->len - 1);
  893. printk(KERN_DEBUG " Anum = '%s'\n", tmp);
  894. }
  895. }
  896. static void
  897. actcapi_debug_ncpi(actcapi_ncpi *ncpi)
  898. {
  899. printk(KERN_DEBUG " ncpi.len = %d\n", ncpi->len);
  900. if (ncpi->len >= 2)
  901. printk(KERN_DEBUG " ncpi.lic = 0x%04x\n", ncpi->lic);
  902. if (ncpi->len >= 4)
  903. printk(KERN_DEBUG " ncpi.hic = 0x%04x\n", ncpi->hic);
  904. if (ncpi->len >= 6)
  905. printk(KERN_DEBUG " ncpi.ltc = 0x%04x\n", ncpi->ltc);
  906. if (ncpi->len >= 8)
  907. printk(KERN_DEBUG " ncpi.htc = 0x%04x\n", ncpi->htc);
  908. if (ncpi->len >= 10)
  909. printk(KERN_DEBUG " ncpi.loc = 0x%04x\n", ncpi->loc);
  910. if (ncpi->len >= 12)
  911. printk(KERN_DEBUG " ncpi.hoc = 0x%04x\n", ncpi->hoc);
  912. if (ncpi->len >= 13)
  913. printk(KERN_DEBUG " ncpi.mod = %d\n", ncpi->modulo);
  914. }
  915. static void
  916. actcapi_debug_dlpd(actcapi_dlpd *dlpd)
  917. {
  918. printk(KERN_DEBUG " dlpd.len = %d\n", dlpd->len);
  919. if (dlpd->len >= 2)
  920. printk(KERN_DEBUG " dlpd.dlen = 0x%04x\n", dlpd->dlen);
  921. if (dlpd->len >= 3)
  922. printk(KERN_DEBUG " dlpd.laa = 0x%02x\n", dlpd->laa);
  923. if (dlpd->len >= 4)
  924. printk(KERN_DEBUG " dlpd.lab = 0x%02x\n", dlpd->lab);
  925. if (dlpd->len >= 5)
  926. printk(KERN_DEBUG " dlpd.modulo = %d\n", dlpd->modulo);
  927. if (dlpd->len >= 6)
  928. printk(KERN_DEBUG " dlpd.win = %d\n", dlpd->win);
  929. }
  930. #ifdef DEBUG_DUMP_SKB
  931. static void dump_skb(struct sk_buff *skb) {
  932. char tmp[80];
  933. char *p = skb->data;
  934. char *t = tmp;
  935. int i;
  936. for (i = 0; i < skb->len; i++) {
  937. t += sprintf(t, "%02x ", *p++ & 0xff);
  938. if ((i & 0x0f) == 8) {
  939. printk(KERN_DEBUG "dump: %s\n", tmp);
  940. t = tmp;
  941. }
  942. }
  943. if (i & 0x07)
  944. printk(KERN_DEBUG "dump: %s\n", tmp);
  945. }
  946. #endif
  947. void
  948. actcapi_debug_msg(struct sk_buff *skb, int direction)
  949. {
  950. actcapi_msg *msg = (actcapi_msg *)skb->data;
  951. char *descr;
  952. int i;
  953. char tmp[170];
  954. #ifndef DEBUG_DATA_MSG
  955. if (msg->hdr.cmd.cmd == 0x86)
  956. return;
  957. #endif
  958. descr = "INVALID";
  959. #ifdef DEBUG_DUMP_SKB
  960. dump_skb(skb);
  961. #endif
  962. for (i = 0; i < num_valid_msg; i++)
  963. if ((msg->hdr.cmd.cmd == valid_msg[i].cmd.cmd) &&
  964. (msg->hdr.cmd.subcmd == valid_msg[i].cmd.subcmd)) {
  965. descr = valid_msg[i].description;
  966. break;
  967. }
  968. printk(KERN_DEBUG "%s %s msg\n", direction?"Outgoing":"Incoming", descr);
  969. printk(KERN_DEBUG " ApplID = %d\n", msg->hdr.applicationID);
  970. printk(KERN_DEBUG " Len = %d\n", msg->hdr.len);
  971. printk(KERN_DEBUG " MsgNum = 0x%04x\n", msg->hdr.msgnum);
  972. printk(KERN_DEBUG " Cmd = 0x%02x\n", msg->hdr.cmd.cmd);
  973. printk(KERN_DEBUG " SubCmd = 0x%02x\n", msg->hdr.cmd.subcmd);
  974. switch (i) {
  975. case 0:
  976. /* DATA B3 IND */
  977. printk(KERN_DEBUG " BLOCK = 0x%02x\n",
  978. msg->msg.data_b3_ind.blocknr);
  979. break;
  980. case 2:
  981. /* CONNECT CONF */
  982. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  983. msg->msg.connect_conf.plci);
  984. printk(KERN_DEBUG " Info = 0x%04x\n",
  985. msg->msg.connect_conf.info);
  986. break;
  987. case 3:
  988. /* CONNECT IND */
  989. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  990. msg->msg.connect_ind.plci);
  991. printk(KERN_DEBUG " Contr = %d\n",
  992. msg->msg.connect_ind.controller);
  993. printk(KERN_DEBUG " SI1 = %d\n",
  994. msg->msg.connect_ind.si1);
  995. printk(KERN_DEBUG " SI2 = %d\n",
  996. msg->msg.connect_ind.si2);
  997. printk(KERN_DEBUG " EAZ = '%c'\n",
  998. msg->msg.connect_ind.eaz);
  999. actcapi_debug_caddr(&msg->msg.connect_ind.addr);
  1000. break;
  1001. case 5:
  1002. /* CONNECT ACTIVE IND */
  1003. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1004. msg->msg.connect_active_ind.plci);
  1005. actcapi_debug_caddr(&msg->msg.connect_active_ind.addr);
  1006. break;
  1007. case 8:
  1008. /* LISTEN CONF */
  1009. printk(KERN_DEBUG " Contr = %d\n",
  1010. msg->msg.listen_conf.controller);
  1011. printk(KERN_DEBUG " Info = 0x%04x\n",
  1012. msg->msg.listen_conf.info);
  1013. break;
  1014. case 11:
  1015. /* INFO IND */
  1016. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1017. msg->msg.info_ind.plci);
  1018. printk(KERN_DEBUG " Imsk = 0x%04x\n",
  1019. msg->msg.info_ind.nr.mask);
  1020. if (msg->hdr.len > 12) {
  1021. int l = msg->hdr.len - 12;
  1022. int j;
  1023. char *p = tmp;
  1024. for (j = 0; j < l ; j++)
  1025. p += sprintf(p, "%02x ", msg->msg.info_ind.el.display[j]);
  1026. printk(KERN_DEBUG " D = '%s'\n", tmp);
  1027. }
  1028. break;
  1029. case 14:
  1030. /* SELECT B2 PROTOCOL CONF */
  1031. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1032. msg->msg.select_b2_protocol_conf.plci);
  1033. printk(KERN_DEBUG " Info = 0x%04x\n",
  1034. msg->msg.select_b2_protocol_conf.info);
  1035. break;
  1036. case 15:
  1037. /* SELECT B3 PROTOCOL CONF */
  1038. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1039. msg->msg.select_b3_protocol_conf.plci);
  1040. printk(KERN_DEBUG " Info = 0x%04x\n",
  1041. msg->msg.select_b3_protocol_conf.info);
  1042. break;
  1043. case 16:
  1044. /* LISTEN B3 CONF */
  1045. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1046. msg->msg.listen_b3_conf.plci);
  1047. printk(KERN_DEBUG " Info = 0x%04x\n",
  1048. msg->msg.listen_b3_conf.info);
  1049. break;
  1050. case 18:
  1051. /* CONNECT B3 IND */
  1052. printk(KERN_DEBUG " NCCI = 0x%04x\n",
  1053. msg->msg.connect_b3_ind.ncci);
  1054. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1055. msg->msg.connect_b3_ind.plci);
  1056. actcapi_debug_ncpi(&msg->msg.connect_b3_ind.ncpi);
  1057. break;
  1058. case 19:
  1059. /* CONNECT B3 ACTIVE IND */
  1060. printk(KERN_DEBUG " NCCI = 0x%04x\n",
  1061. msg->msg.connect_b3_active_ind.ncci);
  1062. actcapi_debug_ncpi(&msg->msg.connect_b3_active_ind.ncpi);
  1063. break;
  1064. case 26:
  1065. /* MANUFACTURER IND */
  1066. printk(KERN_DEBUG " Mmsg = 0x%02x\n",
  1067. msg->msg.manufacturer_ind_err.manuf_msg);
  1068. switch (msg->msg.manufacturer_ind_err.manuf_msg) {
  1069. case 3:
  1070. printk(KERN_DEBUG " Contr = %d\n",
  1071. msg->msg.manufacturer_ind_err.controller);
  1072. printk(KERN_DEBUG " Code = 0x%08x\n",
  1073. msg->msg.manufacturer_ind_err.errcode);
  1074. memset(tmp, 0, sizeof(tmp));
  1075. strncpy(tmp, &msg->msg.manufacturer_ind_err.errstring,
  1076. msg->hdr.len - 16);
  1077. printk(KERN_DEBUG " Emsg = '%s'\n", tmp);
  1078. break;
  1079. }
  1080. break;
  1081. case 30:
  1082. /* LISTEN REQ */
  1083. printk(KERN_DEBUG " Imsk = 0x%08x\n",
  1084. msg->msg.listen_req.infomask);
  1085. printk(KERN_DEBUG " Emsk = 0x%04x\n",
  1086. msg->msg.listen_req.eazmask);
  1087. printk(KERN_DEBUG " Smsk = 0x%04x\n",
  1088. msg->msg.listen_req.simask);
  1089. break;
  1090. case 35:
  1091. /* SELECT_B2_PROTOCOL_REQ */
  1092. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1093. msg->msg.select_b2_protocol_req.plci);
  1094. printk(KERN_DEBUG " prot = 0x%02x\n",
  1095. msg->msg.select_b2_protocol_req.protocol);
  1096. if (msg->hdr.len >= 11)
  1097. printk(KERN_DEBUG "No dlpd\n");
  1098. else
  1099. actcapi_debug_dlpd(&msg->msg.select_b2_protocol_req.dlpd);
  1100. break;
  1101. case 44:
  1102. /* CONNECT RESP */
  1103. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1104. msg->msg.connect_resp.plci);
  1105. printk(KERN_DEBUG " CAUSE = 0x%02x\n",
  1106. msg->msg.connect_resp.rejectcause);
  1107. break;
  1108. case 45:
  1109. /* CONNECT ACTIVE RESP */
  1110. printk(KERN_DEBUG " PLCI = 0x%04x\n",
  1111. msg->msg.connect_active_resp.plci);
  1112. break;
  1113. }
  1114. }
  1115. #endif