l3_1tr6.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:22k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: l3_1tr6.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  2.  *
  3.  * German 1TR6 D-channel protocol
  4.  *
  5.  * Author       Karsten Keil
  6.  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
  7.  * 
  8.  * This software may be used and distributed according to the terms
  9.  * of the GNU General Public License, incorporated herein by reference.
  10.  *
  11.  * For changes and modifications please read
  12.  * ../../../Documentation/isdn/HiSax.cert
  13.  *
  14.  */
  15. #define __NO_VERSION__
  16. #include "hisax.h"
  17. #include "l3_1tr6.h"
  18. #include "isdnl3.h"
  19. #include <linux/ctype.h>
  20. extern char *HiSax_getrev(const char *revision);
  21. const char *l3_1tr6_revision = "$Revision: 1.1.4.1 $";
  22. #define MsgHead(ptr, cref, mty, dis) 
  23. *ptr++ = dis; 
  24. *ptr++ = 0x1; 
  25. *ptr++ = cref ^ 0x80; 
  26. *ptr++ = mty
  27. static void
  28. l3_1TR6_message(struct l3_process *pc, u_char mt, u_char pd)
  29. {
  30. struct sk_buff *skb;
  31. u_char *p;
  32. if (!(skb = l3_alloc_skb(4)))
  33. return;
  34. p = skb_put(skb, 4);
  35. MsgHead(p, pc->callref, mt, pd);
  36. l3_msg(pc->st, DL_DATA | REQUEST, skb);
  37. }
  38. static void
  39. l3_1tr6_release_req(struct l3_process *pc, u_char pr, void *arg)
  40. {
  41. StopAllL3Timer(pc);
  42. newl3state(pc, 19);
  43. l3_1TR6_message(pc, MT_N1_REL, PROTO_DIS_N1);
  44. L3AddTimer(&pc->timer, T308, CC_T308_1);
  45. }
  46. static void
  47. l3_1tr6_invalid(struct l3_process *pc, u_char pr, void *arg)
  48. {
  49. struct sk_buff *skb = arg;
  50. dev_kfree_skb(skb);
  51. l3_1tr6_release_req(pc, 0, NULL);
  52. }
  53. static void
  54. l3_1tr6_error(struct l3_process *pc, u_char *msg, struct sk_buff *skb)
  55. {
  56. dev_kfree_skb(skb);
  57. if (pc->st->l3.debug & L3_DEB_WARN)
  58. l3_debug(pc->st, msg);
  59. l3_1tr6_release_req(pc, 0, NULL);
  60. }
  61. static void
  62. l3_1tr6_setup_req(struct l3_process *pc, u_char pr, void *arg)
  63. {
  64. struct sk_buff *skb;
  65. u_char tmp[128];
  66. u_char *p = tmp;
  67. u_char *teln;
  68. u_char *eaz;
  69. u_char channel = 0;
  70. int l;
  71. MsgHead(p, pc->callref, MT_N1_SETUP, PROTO_DIS_N1);
  72. teln = pc->para.setup.phone;
  73. pc->para.spv = 0;
  74. if (!isdigit(*teln)) {
  75. switch (0x5f & *teln) {
  76. case 'S':
  77. pc->para.spv = 1;
  78. break;
  79. case 'C':
  80. channel = 0x08;
  81. case 'P':
  82. channel |= 0x80;
  83. teln++;
  84. if (*teln == '1')
  85. channel |= 0x01;
  86. else
  87. channel |= 0x02;
  88. break;
  89. default:
  90. if (pc->st->l3.debug & L3_DEB_WARN)
  91. l3_debug(pc->st, "Wrong MSN Code");
  92. break;
  93. }
  94. teln++;
  95. }
  96. if (channel) {
  97. *p++ = 0x18; /* channel indicator */
  98. *p++ = 1;
  99. *p++ = channel;
  100. }
  101. if (pc->para.spv) { /* SPV ? */
  102. /* NSF SPV */
  103. *p++ = WE0_netSpecFac;
  104. *p++ = 4; /* Laenge */
  105. *p++ = 0;
  106. *p++ = FAC_SPV; /* SPV */
  107. *p++ = pc->para.setup.si1; /* 0 for all Services */
  108. *p++ = pc->para.setup.si2; /* 0 for all Services */
  109. *p++ = WE0_netSpecFac;
  110. *p++ = 4; /* Laenge */
  111. *p++ = 0;
  112. *p++ = FAC_Activate; /* aktiviere SPV (default) */
  113. *p++ = pc->para.setup.si1; /* 0 for all Services */
  114. *p++ = pc->para.setup.si2; /* 0 for all Services */
  115. }
  116. eaz = pc->para.setup.eazmsn;
  117. if (*eaz) {
  118. *p++ = WE0_origAddr;
  119. *p++ = strlen(eaz) + 1;
  120. /* Classify as AnyPref. */
  121. *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
  122. while (*eaz)
  123. *p++ = *eaz++ & 0x7f;
  124. }
  125. *p++ = WE0_destAddr;
  126. *p++ = strlen(teln) + 1;
  127. /* Classify as AnyPref. */
  128. *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
  129. while (*teln)
  130. *p++ = *teln++ & 0x7f;
  131. *p++ = WE_Shift_F6;
  132. /* Codesatz 6 fuer Service */
  133. *p++ = WE6_serviceInd;
  134. *p++ = 2; /* len=2 info,info2 */
  135. *p++ = pc->para.setup.si1;
  136. *p++ = pc->para.setup.si2;
  137. l = p - tmp;
  138. if (!(skb = l3_alloc_skb(l)))
  139. return;
  140. memcpy(skb_put(skb, l), tmp, l);
  141. L3DelTimer(&pc->timer);
  142. L3AddTimer(&pc->timer, T303, CC_T303);
  143. newl3state(pc, 1);
  144. l3_msg(pc->st, DL_DATA | REQUEST, skb);
  145. }
  146. static void
  147. l3_1tr6_setup(struct l3_process *pc, u_char pr, void *arg)
  148. {
  149. u_char *p;
  150. int bcfound = 0;
  151. char tmp[80];
  152. struct sk_buff *skb = arg;
  153. p = skb->data;
  154. /* Channel Identification */
  155. p = skb->data;
  156. if ((p = findie(p, skb->len, WE0_chanID, 0))) {
  157. if (p[1] != 1) {
  158. l3_1tr6_error(pc, "setup wrong chanID len", skb);
  159. return;
  160. }
  161. if ((p[2] & 0xf4) != 0x80) {
  162. l3_1tr6_error(pc, "setup wrong WE0_chanID", skb);
  163. return;
  164. }
  165. if ((pc->para.bchannel = p[2] & 0x3))
  166. bcfound++;
  167. } else {
  168. l3_1tr6_error(pc, "missing setup chanID", skb);
  169. return;
  170. }
  171. p = skb->data;
  172. if ((p = findie(p, skb->len, WE6_serviceInd, 6))) {
  173. pc->para.setup.si1 = p[2];
  174. pc->para.setup.si2 = p[3];
  175. } else {
  176. l3_1tr6_error(pc, "missing setup SI", skb);
  177. return;
  178. }
  179. p = skb->data;
  180. if ((p = findie(p, skb->len, WE0_destAddr, 0)))
  181. iecpy(pc->para.setup.eazmsn, p, 1);
  182. else
  183. pc->para.setup.eazmsn[0] = 0;
  184. p = skb->data;
  185. if ((p = findie(p, skb->len, WE0_origAddr, 0))) {
  186. iecpy(pc->para.setup.phone, p, 1);
  187. } else
  188. pc->para.setup.phone[0] = 0;
  189. p = skb->data;
  190. pc->para.spv = 0;
  191. if ((p = findie(p, skb->len, WE0_netSpecFac, 0))) {
  192. if ((FAC_SPV == p[3]) || (FAC_Activate == p[3]))
  193. pc->para.spv = 1;
  194. }
  195. dev_kfree_skb(skb);
  196. /* Signal all services, linklevel takes care of Service-Indicator */
  197. if (bcfound) {
  198. if ((pc->para.setup.si1 != 7) && (pc->st->l3.debug & L3_DEB_WARN)) {
  199. sprintf(tmp, "non-digital call: %s -> %s",
  200. pc->para.setup.phone,
  201. pc->para.setup.eazmsn);
  202. l3_debug(pc->st, tmp);
  203. }
  204. newl3state(pc, 6);
  205. pc->st->l3.l3l4(pc->st, CC_SETUP | INDICATION, pc);
  206. } else
  207. release_l3_process(pc);
  208. }
  209. static void
  210. l3_1tr6_setup_ack(struct l3_process *pc, u_char pr, void *arg)
  211. {
  212. u_char *p;
  213. struct sk_buff *skb = arg;
  214. L3DelTimer(&pc->timer);
  215. p = skb->data;
  216. newl3state(pc, 2);
  217. if ((p = findie(p, skb->len, WE0_chanID, 0))) {
  218. if (p[1] != 1) {
  219. l3_1tr6_error(pc, "setup_ack wrong chanID len", skb);
  220. return;
  221. }
  222. if ((p[2] & 0xf4) != 0x80) {
  223. l3_1tr6_error(pc, "setup_ack wrong WE0_chanID", skb);
  224. return;
  225. }
  226. pc->para.bchannel = p[2] & 0x3;
  227. } else {
  228. l3_1tr6_error(pc, "missing setup_ack WE0_chanID", skb);
  229. return;
  230. }
  231. dev_kfree_skb(skb);
  232. L3AddTimer(&pc->timer, T304, CC_T304);
  233. pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc);
  234. }
  235. static void
  236. l3_1tr6_call_sent(struct l3_process *pc, u_char pr, void *arg)
  237. {
  238. u_char *p;
  239. struct sk_buff *skb = arg;
  240. L3DelTimer(&pc->timer);
  241. p = skb->data;
  242. if ((p = findie(p, skb->len, WE0_chanID, 0))) {
  243. if (p[1] != 1) {
  244. l3_1tr6_error(pc, "call sent wrong chanID len", skb);
  245. return;
  246. }
  247. if ((p[2] & 0xf4) != 0x80) {
  248. l3_1tr6_error(pc, "call sent wrong WE0_chanID", skb);
  249. return;
  250. }
  251. if ((pc->state == 2) && (pc->para.bchannel != (p[2] & 0x3))) {
  252. l3_1tr6_error(pc, "call sent wrong chanID value", skb);
  253. return;
  254. }
  255. pc->para.bchannel = p[2] & 0x3;
  256. } else {
  257. l3_1tr6_error(pc, "missing call sent WE0_chanID", skb);
  258. return;
  259. }
  260. dev_kfree_skb(skb);
  261. L3AddTimer(&pc->timer, T310, CC_T310);
  262. newl3state(pc, 3);
  263. pc->st->l3.l3l4(pc->st, CC_PROCEEDING | INDICATION, pc);
  264. }
  265. static void
  266. l3_1tr6_alert(struct l3_process *pc, u_char pr, void *arg)
  267. {
  268. struct sk_buff *skb = arg;
  269. dev_kfree_skb(skb);
  270. L3DelTimer(&pc->timer); /* T304 */
  271. newl3state(pc, 4);
  272. pc->st->l3.l3l4(pc->st, CC_ALERTING | INDICATION, pc);
  273. }
  274. static void
  275. l3_1tr6_info(struct l3_process *pc, u_char pr, void *arg)
  276. {
  277. u_char *p;
  278. int i, tmpcharge = 0;
  279. char a_charge[8], tmp[32];
  280. struct sk_buff *skb = arg;
  281. p = skb->data;
  282. if ((p = findie(p, skb->len, WE6_chargingInfo, 6))) {
  283. iecpy(a_charge, p, 1);
  284. for (i = 0; i < strlen(a_charge); i++) {
  285. tmpcharge *= 10;
  286. tmpcharge += a_charge[i] & 0xf;
  287. }
  288. if (tmpcharge > pc->para.chargeinfo) {
  289. pc->para.chargeinfo = tmpcharge;
  290. pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc);
  291. }
  292. if (pc->st->l3.debug & L3_DEB_CHARGE) {
  293. sprintf(tmp, "charging info %d", pc->para.chargeinfo);
  294. l3_debug(pc->st, tmp);
  295. }
  296. } else if (pc->st->l3.debug & L3_DEB_CHARGE)
  297. l3_debug(pc->st, "charging info not found");
  298. dev_kfree_skb(skb);
  299. }
  300. static void
  301. l3_1tr6_info_s2(struct l3_process *pc, u_char pr, void *arg)
  302. {
  303. struct sk_buff *skb = arg;
  304. dev_kfree_skb(skb);
  305. }
  306. static void
  307. l3_1tr6_connect(struct l3_process *pc, u_char pr, void *arg)
  308. {
  309. struct sk_buff *skb = arg;
  310. L3DelTimer(&pc->timer); /* T310 */
  311. if (!findie(skb->data, skb->len, WE6_date, 6)) {
  312. l3_1tr6_error(pc, "missing connect date", skb);
  313. return;
  314. }
  315. newl3state(pc, 10);
  316. dev_kfree_skb(skb);
  317. pc->para.chargeinfo = 0;
  318. pc->st->l3.l3l4(pc->st, CC_SETUP | CONFIRM, pc);
  319. }
  320. static void
  321. l3_1tr6_rel(struct l3_process *pc, u_char pr, void *arg)
  322. {
  323. struct sk_buff *skb = arg;
  324. u_char *p;
  325. p = skb->data;
  326. if ((p = findie(p, skb->len, WE0_cause, 0))) {
  327. if (p[1] > 0) {
  328. pc->para.cause = p[2];
  329. if (p[1] > 1)
  330. pc->para.loc = p[3];
  331. else
  332. pc->para.loc = 0;
  333. } else {
  334. pc->para.cause = 0;
  335. pc->para.loc = 0;
  336. }
  337. } else {
  338. pc->para.cause = NO_CAUSE;
  339. l3_1tr6_error(pc, "missing REL cause", skb);
  340. return;
  341. }
  342. dev_kfree_skb(skb);
  343. StopAllL3Timer(pc);
  344. newl3state(pc, 0);
  345. l3_1TR6_message(pc, MT_N1_REL_ACK, PROTO_DIS_N1);
  346. pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
  347. release_l3_process(pc);
  348. }
  349. static void
  350. l3_1tr6_rel_ack(struct l3_process *pc, u_char pr, void *arg)
  351. {
  352. struct sk_buff *skb = arg;
  353. dev_kfree_skb(skb);
  354. StopAllL3Timer(pc);
  355. newl3state(pc, 0);
  356. pc->para.cause = NO_CAUSE;
  357. pc->st->l3.l3l4(pc->st, CC_RELEASE | CONFIRM, pc);
  358. release_l3_process(pc);
  359. }
  360. static void
  361. l3_1tr6_disc(struct l3_process *pc, u_char pr, void *arg)
  362. {
  363. struct sk_buff *skb = arg;
  364. u_char *p;
  365. int i, tmpcharge = 0;
  366. char a_charge[8], tmp[32];
  367. StopAllL3Timer(pc);
  368. p = skb->data;
  369. if ((p = findie(p, skb->len, WE6_chargingInfo, 6))) {
  370. iecpy(a_charge, p, 1);
  371. for (i = 0; i < strlen(a_charge); i++) {
  372. tmpcharge *= 10;
  373. tmpcharge += a_charge[i] & 0xf;
  374. }
  375. if (tmpcharge > pc->para.chargeinfo) {
  376. pc->para.chargeinfo = tmpcharge;
  377. pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc);
  378. }
  379. if (pc->st->l3.debug & L3_DEB_CHARGE) {
  380. sprintf(tmp, "charging info %d", pc->para.chargeinfo);
  381. l3_debug(pc->st, tmp);
  382. }
  383. } else if (pc->st->l3.debug & L3_DEB_CHARGE)
  384. l3_debug(pc->st, "charging info not found");
  385. p = skb->data;
  386. if ((p = findie(p, skb->len, WE0_cause, 0))) {
  387. if (p[1] > 0) {
  388. pc->para.cause = p[2];
  389. if (p[1] > 1)
  390. pc->para.loc = p[3];
  391. else
  392. pc->para.loc = 0;
  393. } else {
  394. pc->para.cause = 0;
  395. pc->para.loc = 0;
  396. }
  397. } else {
  398. if (pc->st->l3.debug & L3_DEB_WARN)
  399. l3_debug(pc->st, "cause not found");
  400. pc->para.cause = NO_CAUSE;
  401. }
  402. if (!findie(skb->data, skb->len, WE6_date, 6)) {
  403. l3_1tr6_error(pc, "missing connack date", skb);
  404. return;
  405. }
  406. dev_kfree_skb(skb);
  407. newl3state(pc, 12);
  408. pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc);
  409. }
  410. static void
  411. l3_1tr6_connect_ack(struct l3_process *pc, u_char pr, void *arg)
  412. {
  413. struct sk_buff *skb = arg;
  414. if (!findie(skb->data, skb->len, WE6_date, 6)) {
  415. l3_1tr6_error(pc, "missing connack date", skb);
  416. return;
  417. }
  418. dev_kfree_skb(skb);
  419. newl3state(pc, 10);
  420. pc->para.chargeinfo = 0;
  421. L3DelTimer(&pc->timer);
  422. pc->st->l3.l3l4(pc->st, CC_SETUP_COMPL | INDICATION, pc);
  423. }
  424. static void
  425. l3_1tr6_alert_req(struct l3_process *pc, u_char pr, void *arg)
  426. {
  427. newl3state(pc, 7);
  428. l3_1TR6_message(pc, MT_N1_ALERT, PROTO_DIS_N1);
  429. }
  430. static void
  431. l3_1tr6_setup_rsp(struct l3_process *pc, u_char pr, void *arg)
  432. {
  433. struct sk_buff *skb;
  434. u_char tmp[24];
  435. u_char *p = tmp;
  436. int l;
  437. MsgHead(p, pc->callref, MT_N1_CONN, PROTO_DIS_N1);
  438. if (pc->para.spv) { /* SPV ? */
  439. /* NSF SPV */
  440. *p++ = WE0_netSpecFac;
  441. *p++ = 4; /* Laenge */
  442. *p++ = 0;
  443. *p++ = FAC_SPV; /* SPV */
  444. *p++ = pc->para.setup.si1;
  445. *p++ = pc->para.setup.si2;
  446. *p++ = WE0_netSpecFac;
  447. *p++ = 4; /* Laenge */
  448. *p++ = 0;
  449. *p++ = FAC_Activate; /* aktiviere SPV */
  450. *p++ = pc->para.setup.si1;
  451. *p++ = pc->para.setup.si2;
  452. }
  453. newl3state(pc, 8);
  454. l = p - tmp;
  455. if (!(skb = l3_alloc_skb(l)))
  456. return;
  457. memcpy(skb_put(skb, l), tmp, l);
  458. l3_msg(pc->st, DL_DATA | REQUEST, skb);
  459. L3DelTimer(&pc->timer);
  460. L3AddTimer(&pc->timer, T313, CC_T313);
  461. }
  462. static void
  463. l3_1tr6_reset(struct l3_process *pc, u_char pr, void *arg)
  464. {
  465. release_l3_process(pc);
  466. }
  467. static void
  468. l3_1tr6_disconnect_req(struct l3_process *pc, u_char pr, void *arg)
  469. {
  470. struct sk_buff *skb;
  471. u_char tmp[16];
  472. u_char *p = tmp;
  473. int l;
  474. u_char cause = 0x10;
  475. u_char clen = 1;
  476. if (pc->para.cause > 0)
  477. cause = pc->para.cause;
  478. /* Map DSS1 causes */
  479. switch (cause & 0x7f) {
  480. case 0x10:
  481. clen = 0;
  482. break;
  483.                 case 0x11:
  484.                         cause = CAUSE_UserBusy;
  485.                         break;
  486. case 0x15:
  487. cause = CAUSE_CallRejected;
  488. break;
  489. }
  490. StopAllL3Timer(pc);
  491. MsgHead(p, pc->callref, MT_N1_DISC, PROTO_DIS_N1);
  492. *p++ = WE0_cause;
  493. *p++ = clen; /* Laenge */
  494. if (clen)
  495. *p++ = cause | 0x80;
  496. newl3state(pc, 11);
  497. l = p - tmp;
  498. if (!(skb = l3_alloc_skb(l)))
  499. return;
  500. memcpy(skb_put(skb, l), tmp, l);
  501. l3_msg(pc->st, DL_DATA | REQUEST, skb);
  502. L3AddTimer(&pc->timer, T305, CC_T305);
  503. }
  504. static void
  505. l3_1tr6_t303(struct l3_process *pc, u_char pr, void *arg)
  506. {
  507. if (pc->N303 > 0) {
  508. pc->N303--;
  509. L3DelTimer(&pc->timer);
  510. l3_1tr6_setup_req(pc, pr, arg);
  511. } else {
  512. L3DelTimer(&pc->timer);
  513. pc->para.cause = 0;
  514. l3_1tr6_disconnect_req(pc, 0, NULL);
  515. }
  516. }
  517. static void
  518. l3_1tr6_t304(struct l3_process *pc, u_char pr, void *arg)
  519. {
  520. L3DelTimer(&pc->timer);
  521. pc->para.cause = 0xE6;
  522. l3_1tr6_disconnect_req(pc, pr, NULL);
  523. pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
  524. }
  525. static void
  526. l3_1tr6_t305(struct l3_process *pc, u_char pr, void *arg)
  527. {
  528. struct sk_buff *skb;
  529. u_char tmp[16];
  530. u_char *p = tmp;
  531. int l;
  532. u_char cause = 0x90;
  533. u_char clen = 1;
  534. L3DelTimer(&pc->timer);
  535. if (pc->para.cause != NO_CAUSE)
  536. cause = pc->para.cause;
  537. /* Map DSS1 causes */
  538. switch (cause & 0x7f) {
  539. case 0x10:
  540. clen = 0;
  541. break;
  542. case 0x15:
  543. cause = CAUSE_CallRejected;
  544. break;
  545. }
  546. MsgHead(p, pc->callref, MT_N1_REL, PROTO_DIS_N1);
  547. *p++ = WE0_cause;
  548. *p++ = clen; /* Laenge */
  549. if (clen)
  550. *p++ = cause;
  551. newl3state(pc, 19);
  552. l = p - tmp;
  553. if (!(skb = l3_alloc_skb(l)))
  554. return;
  555. memcpy(skb_put(skb, l), tmp, l);
  556. l3_msg(pc->st, DL_DATA | REQUEST, skb);
  557. L3AddTimer(&pc->timer, T308, CC_T308_1);
  558. }
  559. static void
  560. l3_1tr6_t310(struct l3_process *pc, u_char pr, void *arg)
  561. {
  562. L3DelTimer(&pc->timer);
  563. pc->para.cause = 0xE6;
  564. l3_1tr6_disconnect_req(pc, pr, NULL);
  565. pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
  566. }
  567. static void
  568. l3_1tr6_t313(struct l3_process *pc, u_char pr, void *arg)
  569. {
  570. L3DelTimer(&pc->timer);
  571. pc->para.cause = 0xE6;
  572. l3_1tr6_disconnect_req(pc, pr, NULL);
  573. pc->st->l3.l3l4(pc->st, CC_CONNECT_ERR, pc);
  574. }
  575. static void
  576. l3_1tr6_t308_1(struct l3_process *pc, u_char pr, void *arg)
  577. {
  578. L3DelTimer(&pc->timer);
  579. l3_1TR6_message(pc, MT_N1_REL, PROTO_DIS_N1);
  580. L3AddTimer(&pc->timer, T308, CC_T308_2);
  581. newl3state(pc, 19);
  582. }
  583. static void
  584. l3_1tr6_t308_2(struct l3_process *pc, u_char pr, void *arg)
  585. {
  586. L3DelTimer(&pc->timer);
  587. pc->st->l3.l3l4(pc->st, CC_RELEASE_ERR, pc);
  588. release_l3_process(pc);
  589. }
  590. static void
  591. l3_1tr6_dl_reset(struct l3_process *pc, u_char pr, void *arg)
  592. {
  593.         pc->para.cause = CAUSE_LocalProcErr;
  594.         l3_1tr6_disconnect_req(pc, pr, NULL);
  595.         pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
  596. }
  597. static void
  598. l3_1tr6_dl_release(struct l3_process *pc, u_char pr, void *arg)
  599. {
  600.         newl3state(pc, 0);
  601.         pc->para.cause = 0x1b;          /* Destination out of order */
  602.         pc->para.loc = 0;
  603.         pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
  604.         release_l3_process(pc);
  605. }
  606. /* *INDENT-OFF* */
  607. static struct stateentry downstl[] =
  608. {
  609. {SBIT(0),
  610.  CC_SETUP | REQUEST, l3_1tr6_setup_req},
  611.     {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) |
  612.       SBIT(10),
  613.       CC_DISCONNECT | REQUEST, l3_1tr6_disconnect_req},
  614. {SBIT(12),
  615.  CC_RELEASE | REQUEST, l3_1tr6_release_req},
  616. {SBIT(6),
  617.  CC_IGNORE | REQUEST, l3_1tr6_reset},
  618. {SBIT(6),
  619.  CC_REJECT | REQUEST, l3_1tr6_disconnect_req},
  620. {SBIT(6),
  621.  CC_ALERTING | REQUEST, l3_1tr6_alert_req},
  622. {SBIT(6) | SBIT(7),
  623.  CC_SETUP | RESPONSE, l3_1tr6_setup_rsp},
  624. {SBIT(1),
  625.  CC_T303, l3_1tr6_t303},
  626. {SBIT(2),
  627.  CC_T304, l3_1tr6_t304},
  628. {SBIT(3),
  629.  CC_T310, l3_1tr6_t310},
  630. {SBIT(8),
  631.  CC_T313, l3_1tr6_t313},
  632. {SBIT(11),
  633.  CC_T305, l3_1tr6_t305},
  634. {SBIT(19),
  635.  CC_T308_1, l3_1tr6_t308_1},
  636. {SBIT(19),
  637.  CC_T308_2, l3_1tr6_t308_2},
  638. };
  639. #define DOWNSTL_LEN 
  640. (sizeof(downstl) / sizeof(struct stateentry))
  641. static struct stateentry datastln1[] =
  642. {
  643. {SBIT(0),
  644.  MT_N1_INVALID, l3_1tr6_invalid},
  645. {SBIT(0),
  646.  MT_N1_SETUP, l3_1tr6_setup},
  647. {SBIT(1),
  648.  MT_N1_SETUP_ACK, l3_1tr6_setup_ack},
  649. {SBIT(1) | SBIT(2),
  650.  MT_N1_CALL_SENT, l3_1tr6_call_sent},
  651. {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10),
  652.  MT_N1_DISC, l3_1tr6_disc},
  653. {SBIT(2) | SBIT(3) | SBIT(4),
  654.  MT_N1_ALERT, l3_1tr6_alert},
  655. {SBIT(2) | SBIT(3) | SBIT(4),
  656.  MT_N1_CONN, l3_1tr6_connect},
  657. {SBIT(2),
  658.  MT_N1_INFO, l3_1tr6_info_s2},
  659. {SBIT(8),
  660.  MT_N1_CONN_ACK, l3_1tr6_connect_ack},
  661. {SBIT(10),
  662.  MT_N1_INFO, l3_1tr6_info},
  663. {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) |
  664.  SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17),
  665.  MT_N1_REL, l3_1tr6_rel},
  666. {SBIT(19),
  667.  MT_N1_REL, l3_1tr6_rel_ack},
  668. {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) |
  669.  SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17),
  670.  MT_N1_REL_ACK, l3_1tr6_invalid},
  671. {SBIT(19),
  672.  MT_N1_REL_ACK, l3_1tr6_rel_ack}
  673. };
  674. #define DATASTLN1_LEN 
  675. (sizeof(datastln1) / sizeof(struct stateentry))
  676. static struct stateentry manstatelist[] =
  677. {
  678.         {SBIT(2),
  679.          DL_ESTABLISH | INDICATION, l3_1tr6_dl_reset},
  680.         {ALL_STATES,
  681.          DL_RELEASE | INDICATION, l3_1tr6_dl_release},
  682. };
  683.  
  684. #define MANSLLEN 
  685.         (sizeof(manstatelist) / sizeof(struct stateentry))
  686. /* *INDENT-ON* */
  687. static void
  688. up1tr6(struct PStack *st, int pr, void *arg)
  689. {
  690. int i, mt, cr;
  691. struct l3_process *proc;
  692. struct sk_buff *skb = arg;
  693. char tmp[80];
  694. switch (pr) {
  695. case (DL_DATA | INDICATION):
  696. case (DL_UNIT_DATA | INDICATION):
  697. break;
  698. case (DL_ESTABLISH | CONFIRM):
  699. case (DL_ESTABLISH | INDICATION):
  700. case (DL_RELEASE | INDICATION):
  701. case (DL_RELEASE | CONFIRM):
  702. l3_msg(st, pr, arg);
  703. return;
  704. break;
  705. }
  706. if (skb->len < 4) {
  707. if (st->l3.debug & L3_DEB_PROTERR) {
  708. sprintf(tmp, "up1tr6 len only %d", skb->len);
  709. l3_debug(st, tmp);
  710. }
  711. dev_kfree_skb(skb);
  712. return;
  713. }
  714. if ((skb->data[0] & 0xfe) != PROTO_DIS_N0) {
  715. if (st->l3.debug & L3_DEB_PROTERR) {
  716. sprintf(tmp, "up1tr6%sunexpected discriminator %x message len %d",
  717. (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
  718. skb->data[0], skb->len);
  719. l3_debug(st, tmp);
  720. }
  721. dev_kfree_skb(skb);
  722. return;
  723. }
  724. if (skb->data[1] != 1) {
  725. if (st->l3.debug & L3_DEB_PROTERR) {
  726. sprintf(tmp, "up1tr6 CR len not 1");
  727. l3_debug(st, tmp);
  728. }
  729. dev_kfree_skb(skb);
  730. return;
  731. }
  732. cr = skb->data[2];
  733. mt = skb->data[3];
  734. if (skb->data[0] == PROTO_DIS_N0) {
  735. dev_kfree_skb(skb);
  736. if (st->l3.debug & L3_DEB_STATE) {
  737. sprintf(tmp, "up1tr6%s N0 mt %x unhandled",
  738.      (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", mt);
  739. l3_debug(st, tmp);
  740. }
  741. } else if (skb->data[0] == PROTO_DIS_N1) {
  742. if (!(proc = getl3proc(st, cr))) {
  743. if (mt == MT_N1_SETUP) { 
  744. if (cr < 128) {
  745. if (!(proc = new_l3_process(st, cr))) {
  746. if (st->l3.debug & L3_DEB_PROTERR) {
  747. sprintf(tmp, "up1tr6 no roc mem");
  748. l3_debug(st, tmp);
  749. }
  750. dev_kfree_skb(skb);
  751. return;
  752. }
  753. } else {
  754. dev_kfree_skb(skb);
  755. return;
  756. }
  757. } else if ((mt == MT_N1_REL) || (mt == MT_N1_REL_ACK) ||
  758. (mt == MT_N1_CANC_ACK) || (mt == MT_N1_CANC_REJ) ||
  759. (mt == MT_N1_REG_ACK) || (mt == MT_N1_REG_REJ) ||
  760. (mt == MT_N1_SUSP_ACK) || (mt == MT_N1_RES_REJ) ||
  761. (mt == MT_N1_INFO)) {
  762. dev_kfree_skb(skb);
  763. return;
  764. } else {
  765. if (!(proc = new_l3_process(st, cr))) {
  766. if (st->l3.debug & L3_DEB_PROTERR) {
  767. sprintf(tmp, "up1tr6 no roc mem");
  768. l3_debug(st, tmp);
  769. }
  770. dev_kfree_skb(skb);
  771. return;
  772. }
  773. mt = MT_N1_INVALID;
  774. }
  775. }
  776. for (i = 0; i < DATASTLN1_LEN; i++)
  777. if ((mt == datastln1[i].primitive) &&
  778.     ((1 << proc->state) & datastln1[i].state))
  779. break;
  780. if (i == DATASTLN1_LEN) {
  781. dev_kfree_skb(skb);
  782. if (st->l3.debug & L3_DEB_STATE) {
  783. sprintf(tmp, "up1tr6%sstate %d mt %x unhandled",
  784.   (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
  785. proc->state, mt);
  786. l3_debug(st, tmp);
  787. }
  788. return;
  789. } else {
  790. if (st->l3.debug & L3_DEB_STATE) {
  791. sprintf(tmp, "up1tr6%sstate %d mt %x",
  792.   (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
  793. proc->state, mt);
  794. l3_debug(st, tmp);
  795. }
  796. datastln1[i].rout(proc, pr, skb);
  797. }
  798. }
  799. }
  800. static void
  801. down1tr6(struct PStack *st, int pr, void *arg)
  802. {
  803. int i, cr;
  804. struct l3_process *proc;
  805. struct Channel *chan;
  806. char tmp[80];
  807. if ((DL_ESTABLISH | REQUEST)== pr) {
  808. l3_msg(st, pr, NULL);
  809. return;
  810. } else if ((CC_SETUP | REQUEST) == pr) {
  811. chan = arg;
  812. cr = newcallref();
  813. cr |= 0x80;
  814. if (!(proc = new_l3_process(st, cr))) {
  815. return;
  816. } else {
  817. proc->chan = chan;
  818. chan->proc = proc;
  819. memcpy(&proc->para.setup, &chan->setup, sizeof(setup_parm));
  820. proc->callref = cr;
  821. }
  822. } else {
  823. proc = arg;
  824. }
  825. for (i = 0; i < DOWNSTL_LEN; i++)
  826. if ((pr == downstl[i].primitive) &&
  827.     ((1 << proc->state) & downstl[i].state))
  828. break;
  829. if (i == DOWNSTL_LEN) {
  830. if (st->l3.debug & L3_DEB_STATE) {
  831. sprintf(tmp, "down1tr6 state %d prim %d unhandled",
  832. proc->state, pr);
  833. l3_debug(st, tmp);
  834. }
  835. } else {
  836. if (st->l3.debug & L3_DEB_STATE) {
  837. sprintf(tmp, "down1tr6 state %d prim %d",
  838. proc->state, pr);
  839. l3_debug(st, tmp);
  840. }
  841. downstl[i].rout(proc, pr, arg);
  842. }
  843. }
  844. static void
  845. man1tr6(struct PStack *st, int pr, void *arg)
  846. {
  847.         int i;
  848.         struct l3_process *proc = arg;
  849.  
  850.         if (!proc) {
  851.                 printk(KERN_ERR "HiSax man1tr6 without proc pr=%04xn", pr);
  852.                 return;
  853.         }
  854.         for (i = 0; i < MANSLLEN; i++)
  855.                 if ((pr == manstatelist[i].primitive) &&
  856.                     ((1 << proc->state) & manstatelist[i].state))
  857.                         break;
  858.         if (i == MANSLLEN) {
  859.                 if (st->l3.debug & L3_DEB_STATE) {
  860.                         l3_debug(st, "cr %d man1tr6 state %d prim %d unhandled",
  861.                                 proc->callref & 0x7f, proc->state, pr);
  862.                 }
  863.         } else {
  864.                 if (st->l3.debug & L3_DEB_STATE) {
  865.                         l3_debug(st, "cr %d man1tr6 state %d prim %d",
  866.                                 proc->callref & 0x7f, proc->state, pr);
  867.                 }
  868.                 manstatelist[i].rout(proc, pr, arg);
  869.         }
  870. }
  871.  
  872. void
  873. setstack_1tr6(struct PStack *st)
  874. {
  875. char tmp[64];
  876. st->lli.l4l3 = down1tr6;
  877. st->l2.l2l3 = up1tr6;
  878. st->l3.l3ml3 = man1tr6;
  879. st->l3.N303 = 0;
  880. strcpy(tmp, l3_1tr6_revision);
  881. printk(KERN_INFO "HiSax: 1TR6 Rev. %sn", HiSax_getrev(tmp));
  882. }