PageRenderTime 64ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/mISDNuser-1_1_5/i4lnet/net_l3.c

#
C | 3034 lines | 2741 code | 220 blank | 73 comment | 596 complexity | 97bb70db34eaec27bfed77d335fce42f MD5 | raw file
Possible License(s): LGPL-2.0
  1. /* $Id: net_l3.c,v 1.15 2006/12/28 12:24:01 jolly Exp $
  2. *
  3. * Author Karsten Keil (keil@isdn4linux.de)
  4. *
  5. * This file is (c) under GNU PUBLIC LICENSE
  6. * For changes and modifications please read
  7. * ../../../Documentation/isdn/mISDN.cert
  8. *
  9. */
  10. #include <stdlib.h>
  11. #include "mISDNlib.h"
  12. #include "net_l2.h"
  13. #include "net_l3.h"
  14. #include "l3dss1.h"
  15. #include "helper.h"
  16. // #include "debug.h"
  17. const char *l3_revision = "$Revision: 1.15 $";
  18. #define PROTO_DIS_EURO 8
  19. #define L3_DEB_WARN 1
  20. #define L3_DEB_PROTERR 2
  21. #define L3_DEB_STATE 4
  22. #define L3_DEB_PROC 8
  23. #define L3_DEB_CHECK 16
  24. enum {
  25. ST_L3_LC_REL,
  26. ST_L3_LC_ESTAB_WAIT,
  27. ST_L3_LC_REL_DELAY,
  28. ST_L3_LC_REL_WAIT,
  29. ST_L3_LC_ESTAB,
  30. };
  31. enum {
  32. IMSG_END_PROC,
  33. IMSG_END_PROC_M,
  34. IMSG_L2_DATA,
  35. IMSG_L4_DATA,
  36. IMSG_TIMER_EXPIRED,
  37. IMSG_MASTER_L2_DATA,
  38. IMSG_PROCEEDING_IND,
  39. IMSG_ALERTING_IND,
  40. IMSG_CONNECT_IND,
  41. IMSG_SEL_PROC,
  42. IMSG_RELEASE_CHILDS,
  43. };
  44. static int send_proc(layer3_proc_t *proc, int op, void *arg);
  45. static int l3_msg(layer3_t *l3, u_int pr, int dinfo, void *arg);
  46. static int mISDN_l3up(layer3_proc_t *, msg_t *);
  47. static int l3down(layer3_t *l3, u_int prim, int dinfo, msg_t *msg);
  48. struct _l3_msg {
  49. int mt;
  50. msg_t *msg;
  51. };
  52. struct stateentry {
  53. int state;
  54. int primitive;
  55. void (*rout) (layer3_proc_t *, int, void *);
  56. };
  57. #define SBIT(state) (1<<state)
  58. #define ALL_STATES 0x03ffffff
  59. void
  60. display_NR_IE(u_char *p, char *head1, char *head2)
  61. {
  62. int len;
  63. char txt[128];
  64. char *tp = txt;
  65. len = *p++;
  66. tp += sprintf(tp, "len(%d)", len);
  67. if (len) {
  68. len--;
  69. tp += sprintf(tp, " plan(%x)", *p);
  70. if (len && !(*p & 0x80)) {
  71. len--;
  72. p++;
  73. tp += sprintf(tp, " pres(%x)", *p);
  74. }
  75. p++;
  76. tp += sprintf(tp, " ");
  77. while(len--)
  78. tp += sprintf(tp, "%c", *p++);
  79. }
  80. dprint(DBGM_L3, -1, "%s%s %s\n", head1, head2, txt);
  81. }
  82. static void
  83. l3_debug(layer3_t *l3, char *fmt, ...)
  84. {
  85. va_list args;
  86. char buf[256], *p;
  87. va_start(args, fmt);
  88. p = buf;
  89. p += sprintf(p, "l3 ");
  90. p += vsprintf(p, fmt, args);
  91. va_end(args);
  92. dprint(DBGM_L3, l3->nst->cardnr, "%s\n", buf);
  93. }
  94. static int
  95. getcallref(u_char *p)
  96. {
  97. int l, cr = 0;
  98. p++; /* prot discr */
  99. l = 0xf & *p++; /* callref length */
  100. if (l > 2) /* wrong callref only 1 or 2 octet*/
  101. return(-2);
  102. if (!l) /* dummy CallRef */
  103. return(-1);
  104. if (l == 1) { /* BRI */
  105. cr = *p & 0x7f;
  106. cr += (*p & 0x80) << 8;
  107. } else { /* PRI */
  108. cr = *p++ << 8;
  109. cr += *p;
  110. }
  111. return (cr);
  112. }
  113. void
  114. newl3state(layer3_proc_t *pc, int state)
  115. {
  116. if (pc->l3 && pc->l3->debug & L3_DEB_STATE)
  117. l3_debug(pc->l3, "newstate cr %d %d%s --> %d%s",
  118. pc->callref & 0x7FFF,
  119. pc->state, pc->master ? "i" : "",
  120. state, pc->master ? "i" : "");
  121. pc->state = state;
  122. }
  123. static void
  124. L3ExpireTimer(L3Timer_t *t)
  125. {
  126. if (t->pc->l3->debug & L3_DEB_STATE)
  127. l3_debug(t->pc->l3, "timer %p nr %x expired", t, t->nr);
  128. send_proc(t->pc, IMSG_TIMER_EXPIRED, &t->nr);
  129. }
  130. void
  131. L3InitTimer(layer3_proc_t *pc, L3Timer_t *t)
  132. {
  133. t->pc = pc;
  134. t->tl.function = (void *) L3ExpireTimer;
  135. t->tl.data = (long) t;
  136. init_timer(&t->tl, pc->l3->nst);
  137. }
  138. void
  139. L3DelTimer(L3Timer_t *t)
  140. {
  141. del_timer(&t->tl);
  142. }
  143. int
  144. L3AddTimer(L3Timer_t *t, int millisec, int timer_nr)
  145. {
  146. if (timer_pending(&t->tl)) {
  147. if (t->pc && t->pc->l3)
  148. dprint(DBGM_L3, t->pc->l3->nst->cardnr, "L3AddTimer: timer already active!\n");
  149. else
  150. dprint(DBGM_L3, 0, "L3AddTimer: timer already active!\n");
  151. return -1;
  152. }
  153. init_timer(&t->tl, t->pc->l3->nst);
  154. t->nr = timer_nr;
  155. t->tl.expires = millisec;
  156. add_timer(&t->tl);
  157. return 0;
  158. }
  159. void
  160. StopAllL3Timer(layer3_proc_t *pc)
  161. {
  162. L3DelTimer(&pc->timer1);
  163. L3DelTimer(&pc->timer2);
  164. dprint(DBGM_L3, pc->l3->nst->cardnr, "%s: pc=%p del timer2\n", __FUNCTION__, pc);
  165. #warning also remove flags:
  166. test_and_clear_bit(FLG_L3P_TIMER303_1, &pc->Flags);
  167. test_and_clear_bit(FLG_L3P_TIMER308_1, &pc->Flags);
  168. test_and_clear_bit(FLG_L3P_TIMER312, &pc->Flags);
  169. }
  170. void
  171. RemoveAllL3Timer(layer3_proc_t *pc)
  172. {
  173. int ret;
  174. ret = remove_timer(&pc->timer1.tl);
  175. if (ret)
  176. dprint(DBGM_L3, pc->l3?pc->l3->nst->cardnr:0, "RemoveL3Timer1: ret %d\n", ret);
  177. ret = remove_timer(&pc->timer2.tl);
  178. dprint(DBGM_L3, pc->l3->nst->cardnr, "%s: pc=%p del timer2\n", __FUNCTION__, pc);
  179. if (ret)
  180. dprint(DBGM_L3, pc->l3->nst->cardnr, "RemoveL3Timer2: ret %d\n", ret);
  181. #warning also remove flags:
  182. test_and_clear_bit(FLG_L3P_TIMER303_1, &pc->Flags);
  183. test_and_clear_bit(FLG_L3P_TIMER308_1, &pc->Flags);
  184. test_and_clear_bit(FLG_L3P_TIMER312, &pc->Flags);
  185. }
  186. static layer3_proc_t *
  187. create_proc(layer3_t *l3, int ces, int cr, layer3_proc_t *master)
  188. {
  189. layer3_proc_t *l3p;
  190. l3p = malloc(sizeof(layer3_proc_t));
  191. if (l3p) {
  192. memset(l3p, 0, sizeof(layer3_proc_t));
  193. l3p->l3 = l3;
  194. l3p->ces = ces;
  195. l3p->callref = cr;
  196. l3p->master = master;
  197. L3InitTimer(l3p, &l3p->timer1);
  198. L3InitTimer(l3p, &l3p->timer2);
  199. if (master) {
  200. APPEND_TO_LIST(l3p, master->child);
  201. }
  202. }
  203. return(l3p);
  204. }
  205. static layer3_proc_t *
  206. find_proc(layer3_proc_t *master, int ces, int cr)
  207. {
  208. layer3_proc_t *p = master;
  209. layer3_proc_t *cp;
  210. dprint(DBGM_L3, master?master->l3->nst->cardnr:0, "%s: ces(%x) cr(%x)\n", __FUNCTION__,
  211. ces, cr);
  212. while(p) {
  213. dprint(DBGM_L3, p->l3->nst->cardnr, "%s: proc %p ces(%x) cr(%x)\n", __FUNCTION__,
  214. p, p->ces, p->callref);
  215. if ((p->ces == ces) && (p->callref == cr))
  216. break;
  217. if (p->child) {
  218. cp = find_proc(p->child, ces, cr);
  219. if (cp)
  220. return(cp);
  221. }
  222. if (((p->ces & 0xffffff00) == 0xff00) && (p->callref == cr))
  223. break;
  224. p = p->next;
  225. }
  226. return(p);
  227. }
  228. u_char *
  229. findie(u_char * p, int size, u_char ie, int wanted_set)
  230. {
  231. int l, codeset, maincodeset;
  232. u_char *pend = p + size;
  233. /* skip protocol discriminator, callref and message type */
  234. p++;
  235. l = (*p++) & 0xf;
  236. p += l;
  237. p++;
  238. codeset = 0;
  239. maincodeset = 0;
  240. /* while there are bytes left... */
  241. while (p < pend) {
  242. if ((*p & 0xf0) == 0x90) {
  243. codeset = *p & 0x07;
  244. if (!(*p & 0x08))
  245. maincodeset = codeset;
  246. }
  247. if (codeset == wanted_set) {
  248. if (*p == ie) {
  249. /* improved length check (Werner Cornelius) */
  250. if (!(*p & 0x80)) {
  251. if ((pend - p) < 2)
  252. return(NULL);
  253. if (*(p+1) > (pend - (p+2)))
  254. return(NULL);
  255. p++; /* points to len */
  256. }
  257. return (p);
  258. } else if ((*p > ie) && !(*p & 0x80))
  259. return (NULL);
  260. }
  261. if (!(*p & 0x80)) {
  262. p++;
  263. l = *p;
  264. p += l;
  265. codeset = maincodeset;
  266. }
  267. p++;
  268. }
  269. return (NULL);
  270. }
  271. u_char *
  272. find_and_copy_ie(u_char * p, int size, u_char ie, int wanted_set, msg_t *msg)
  273. {
  274. u_char *iep, *mp;
  275. int l;
  276. iep = findie(p, size, ie, wanted_set);
  277. if (iep) {
  278. l = 1;
  279. if (!(ie & 0x80))
  280. l += *iep;
  281. mp = msg_put(msg, l);
  282. memcpy(mp, iep, l);
  283. iep = mp;
  284. }
  285. return(iep);
  286. }
  287. static void MsgStart(layer3_proc_t *pc, u_char mt) {
  288. pc->op = &pc->obuf[0];
  289. *pc->op++ = 8;
  290. if (pc->callref == -1) { /* dummy cr */
  291. *pc->op++ = 0;
  292. } else {
  293. if (pc->l3->nst->feature & FEATURE_NET_CRLEN2) {
  294. *pc->op++ = 2;
  295. *pc->op++ = (pc->callref >> 8) ^ 0x80;
  296. *pc->op++ = pc->callref & 0xff;
  297. } else {
  298. *pc->op++ = 1;
  299. *pc->op = pc->callref & 0x7f;
  300. if (!(pc->callref & 0x8000))
  301. *pc->op |= 0x80;
  302. pc->op++;
  303. }
  304. }
  305. *pc->op++ = mt;
  306. }
  307. static void AddvarIE(layer3_proc_t *pc, u_char ie, u_char *iep) {
  308. u_char len = *iep;
  309. *pc->op++ = ie;
  310. *pc->op++ = *iep++;
  311. while(len--)
  312. *pc->op++ = *iep++;
  313. }
  314. static int SendMsg(layer3_proc_t *pc, int state) {
  315. int l;
  316. int ret;
  317. msg_t *msg;
  318. l = pc->op - &pc->obuf[0];
  319. if (!(msg = l3_alloc_msg(l)))
  320. return(-ENOMEM);
  321. memcpy(msg_put(msg, l), &pc->obuf[0], l);
  322. dhexprint(DBGM_L3DATA, "l3 oframe:", &pc->obuf[0], l);
  323. if (state != -1)
  324. newl3state(pc, state);
  325. if ((ret = l3_msg(pc->l3, DL_DATA | REQUEST, pc->ces, msg)))
  326. free_msg(msg);
  327. return(ret);
  328. }
  329. static int
  330. l3dss1_message(layer3_proc_t *pc, u_char mt)
  331. {
  332. msg_t *msg;
  333. u_char *p;
  334. int ret;
  335. int crlen = 1;
  336. if (pc->l3->nst->feature & FEATURE_NET_CRLEN2)
  337. crlen = 2;
  338. if (!(msg = l3_alloc_msg(crlen+3)))
  339. return(-ENOMEM);
  340. p = msg_put(msg, crlen+3);
  341. *p++ = 8;
  342. *p++ = crlen;
  343. if (crlen == 2) {
  344. *p++ = (pc->callref >> 8) ^ 0x80;
  345. *p++ = pc->callref & 0xff;
  346. } else {
  347. *p = pc->callref & 0x7f;
  348. if (!(pc->callref & 0x8000))
  349. *p |= 0x80;
  350. p++;
  351. }
  352. *p++ = mt;
  353. dhexprint(DBGM_L3DATA, "l3 oframe:", msg->data, 4);
  354. if ((ret=l3_msg(pc->l3, DL_DATA | REQUEST, pc->ces, msg)))
  355. free_msg(msg);
  356. return(ret);
  357. }
  358. static void
  359. l3dss1_message_cause(layer3_proc_t *pc, u_char mt, u_char cause)
  360. {
  361. MsgStart(pc, mt);
  362. if (cause) {
  363. *pc->op++ = IE_CAUSE;
  364. *pc->op++ = 0x2;
  365. *pc->op++ = 0x80 | CAUSE_LOC_PNET_LOCUSER;
  366. *pc->op++ = 0x80 | cause;
  367. }
  368. SendMsg(pc, -1);
  369. }
  370. static void
  371. l3dss1_status_send(layer3_proc_t *pc, u_char cause)
  372. {
  373. MsgStart(pc, MT_STATUS);
  374. *pc->op++ = IE_CAUSE;
  375. *pc->op++ = 2;
  376. *pc->op++ = 0x80 | CAUSE_LOC_USER;
  377. *pc->op++ = 0x80 | cause;
  378. *pc->op++ = IE_CALL_STATE;
  379. *pc->op++ = 1;
  380. *pc->op++ = pc->state & 0x3f;
  381. SendMsg(pc, -1);
  382. }
  383. static void
  384. l3dss1_msg_without_setup(layer3_proc_t *pc, u_char cause)
  385. {
  386. /* This routine is called if here was no SETUP made (checks in dss1up and in
  387. * l3dss1_setup) and a RELEASE_COMPLETE have to be sent with an error code
  388. * MT_STATUS_ENQUIRE in the NULL state is handled too
  389. */
  390. switch (cause) {
  391. case 81: /* invalid callreference */
  392. case 88: /* incomp destination */
  393. case 96: /* mandory IE missing */
  394. case 100: /* invalid IE contents */
  395. case 101: /* incompatible Callstate */
  396. l3dss1_message_cause(pc, MT_RELEASE_COMPLETE, cause);
  397. break;
  398. default:
  399. dprint(DBGM_L3, pc->l3->nst->cardnr, "mISDN l3dss1_msg_without_setup wrong cause %d\n",
  400. cause);
  401. }
  402. send_proc(pc, IMSG_END_PROC, NULL);
  403. }
  404. #if 0
  405. static int
  406. l3dss1_check_messagetype_validity(layer3_proc_t *pc, int mt, void *arg)
  407. {
  408. switch (mt) {
  409. case MT_ALERTING:
  410. case MT_CALL_PROCEEDING:
  411. case MT_CONNECT:
  412. case MT_CONNECT_ACKNOWLEDGE:
  413. case MT_DISCONNECT:
  414. case MT_INFORMATION:
  415. case MT_FACILITY:
  416. case MT_NOTIFY:
  417. case MT_PROGRESS:
  418. case MT_RELEASE:
  419. case MT_RELEASE_COMPLETE:
  420. case MT_SETUP:
  421. case MT_SETUP_ACKNOWLEDGE:
  422. case MT_RESUME_ACKNOWLEDGE:
  423. case MT_RESUME_REJECT:
  424. case MT_SUSPEND_ACKNOWLEDGE:
  425. case MT_SUSPEND_REJECT:
  426. case MT_USER_INFORMATION:
  427. case MT_RESTART:
  428. case MT_RESTART_ACKNOWLEDGE:
  429. case MT_CONGESTION_CONTROL:
  430. case MT_STATUS:
  431. case MT_STATUS_ENQUIRY:
  432. case MT_HOLD:
  433. case MT_RETRIEVE:
  434. case MT_RESUME: /* RESUME only in user->net */
  435. case MT_SUSPEND: /* SUSPEND only in user->net */
  436. if (pc->l3->debug & L3_DEB_CHECK)
  437. l3_debug(pc->l3, "l3dss1_check_messagetype_validity mt(%x) OK", mt);
  438. break;
  439. default:
  440. if (pc->l3->debug & (L3_DEB_CHECK | L3_DEB_WARN))
  441. l3_debug(pc->l3, "l3dss1_check_messagetype_validity mt(%x) fail", mt);
  442. l3dss1_status_send(pc, CAUSE_MT_NOTIMPLEMENTED);
  443. return(1);
  444. }
  445. return(0);
  446. }
  447. #endif
  448. static void
  449. l3dss1_std_ie_err(layer3_proc_t *pc, int ret) {
  450. if (pc->l3->debug & L3_DEB_CHECK)
  451. l3_debug(pc->l3, "check_infoelements ret %d", ret);
  452. switch(ret) {
  453. case 0:
  454. break;
  455. case ERR_IE_COMPREHENSION:
  456. l3dss1_status_send(pc, CAUSE_MANDATORY_IE_MISS);
  457. break;
  458. case ERR_IE_UNRECOGNIZED:
  459. l3dss1_status_send(pc, CAUSE_IE_NOTIMPLEMENTED);
  460. break;
  461. case ERR_IE_LENGTH:
  462. l3dss1_status_send(pc, CAUSE_INVALID_CONTENTS);
  463. break;
  464. case ERR_IE_SEQUENCE:
  465. default:
  466. break;
  467. }
  468. }
  469. static u_char *
  470. l3dss1_get_channel_id(layer3_proc_t *pc, msg_t *omsg, msg_t *nmsg) {
  471. u_char *sp, *p;
  472. int l;
  473. if ((sp = p = findie(omsg->data, omsg->len, IE_CHANNEL_ID, 0))) {
  474. l = *p++;
  475. if (pc->l3->nst->feature & FEATURE_NET_EXTCID) { /* PRI */
  476. if (l < 3) {
  477. if (pc->l3->debug & L3_DEB_WARN)
  478. l3_debug(pc->l3, "wrong chid len %d", *p);
  479. pc->err = -2;
  480. return (NULL);
  481. }
  482. if ((*p & 0x60) != 0x20) {
  483. if (pc->l3->debug & L3_DEB_WARN)
  484. l3_debug(pc->l3, "wrong chid %x (for PRI interface)", *p);
  485. pc->err = -3;
  486. return (NULL);
  487. }
  488. p++;
  489. if (*p & 0x10) {
  490. if (pc->l3->debug & L3_DEB_WARN)
  491. l3_debug(pc->l3, "wrong chid %x (channel map not supported)", *p);
  492. pc->err = -4;
  493. return (NULL);
  494. }
  495. p++;
  496. pc->bc = *p & 0x7f;
  497. } else { /* BRI */
  498. if (l < 1) {
  499. if (pc->l3->debug & L3_DEB_WARN)
  500. l3_debug(pc->l3, "wrong chid len %d", *p);
  501. pc->err = -2;
  502. return (NULL);
  503. }
  504. if (*p & 0x60) {
  505. if (pc->l3->debug & L3_DEB_WARN)
  506. l3_debug(pc->l3, "wrong chid %x", *p);
  507. pc->err = -3;
  508. return (NULL);
  509. }
  510. pc->bc = *p & 3;
  511. }
  512. p = sp;
  513. sp = msg_put(nmsg, 1 + *p);
  514. memcpy(sp, p, 1 + *p);
  515. } else
  516. pc->err = -1;
  517. return(sp);
  518. }
  519. static u_char *
  520. l3dss1_get_cause(layer3_proc_t *pc, msg_t *omsg, msg_t *nmsg) {
  521. u_char l;
  522. u_char *p, *sp;
  523. if ((sp = p = findie(omsg->data, omsg->len, IE_CAUSE, 0))) {
  524. l = *p++;
  525. if (l>30) {
  526. pc->err = 1;
  527. return(NULL);
  528. }
  529. if (l)
  530. l--;
  531. else {
  532. pc->err = 2;
  533. return(NULL);
  534. }
  535. if (l && !(*p & 0x80)) {
  536. l--;
  537. p++; /* skip recommendation */
  538. }
  539. p++;
  540. if (l) {
  541. if (!(*p & 0x80)) {
  542. pc->err = 3;
  543. return(NULL);
  544. }
  545. pc->err = *p & 0x7F;
  546. } else {
  547. pc->err = 4;
  548. return(NULL);
  549. }
  550. if (nmsg) {
  551. p = sp;
  552. sp = msg_put(nmsg, 1 + *p);
  553. memcpy(sp, p, 1 + *p);
  554. }
  555. } else
  556. pc->err = -1;
  557. return(sp);
  558. }
  559. static void
  560. l3dss1_status_enq(layer3_proc_t *proc, int pr, void *arg)
  561. {
  562. }
  563. static void
  564. l3dss1_facility(layer3_proc_t *pc, int pr, void *arg)
  565. {
  566. msg_t *umsg,*msg = arg;
  567. FACILITY_t *fac;
  568. umsg = prep_l3data_msg(CC_FACILITY | INDICATION,
  569. pc->callref>0?pc->ces | (pc->callref << 16):-1,
  570. sizeof(FACILITY_t), msg->len, NULL);
  571. if (!umsg)
  572. return;
  573. fac = (FACILITY_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  574. fac->FACILITY =
  575. find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
  576. if (mISDN_l3up(pc, umsg))
  577. free_msg(umsg);
  578. }
  579. static void
  580. l3dss1_userinfo(layer3_proc_t *pc, int pr, void *arg)
  581. {
  582. msg_t *umsg,*msg = arg;
  583. USER_INFORMATION_t *ui;
  584. umsg = prep_l3data_msg(CC_USER_INFORMATION | INDICATION, pc->ces |
  585. (pc->callref << 16), sizeof(USER_INFORMATION_t), msg->len, NULL);
  586. if (!umsg)
  587. return;
  588. ui = (USER_INFORMATION_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  589. ui->USER_USER =
  590. find_and_copy_ie(msg->data, msg->len, IE_USER_USER, 0, umsg);
  591. if (mISDN_l3up(pc, umsg))
  592. free_msg(umsg);
  593. }
  594. static void
  595. l3dss1_setup(layer3_proc_t *pc, int pr, void *arg)
  596. {
  597. u_char *p;
  598. int bcfound = 0;
  599. msg_t *umsg,*msg = arg;
  600. int err = 0;
  601. SETUP_t *setup;
  602. umsg = prep_l3data_msg(CC_SETUP | INDICATION, pc->ces |
  603. (pc->callref << 16), sizeof(SETUP_t), msg->len, NULL);
  604. if (!umsg)
  605. return;
  606. setup = (SETUP_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  607. /*
  608. * Bearer Capabilities
  609. */
  610. /* only the first occurence 'll be detected ! */
  611. if ((p = setup->BEARER = find_and_copy_ie(msg->data, msg->len,
  612. IE_BEARER, 0, umsg))) {
  613. if ((p[0] < 2) || (p[0] > 11))
  614. err = 1;
  615. else {
  616. switch (p[1] & 0x7f) {
  617. case 0x00: /* Speech */
  618. case 0x10: /* 3.1 Khz audio */
  619. case 0x08: /* Unrestricted digital information */
  620. case 0x09: /* Restricted digital information */
  621. case 0x11:
  622. /* Unrestr. digital information with
  623. * tones/announcements ( or 7 kHz audio
  624. */
  625. case 0x18: /* Video */
  626. break;
  627. default:
  628. err = 2;
  629. break;
  630. }
  631. switch (p[2] & 0x7f) {
  632. case 0x40: /* packed mode */
  633. case 0x10: /* 64 kbit */
  634. case 0x11: /* 2*64 kbit */
  635. case 0x13: /* 384 kbit */
  636. case 0x15: /* 1536 kbit */
  637. case 0x17: /* 1920 kbit */
  638. break;
  639. default:
  640. err = 3;
  641. break;
  642. }
  643. }
  644. if (err) {
  645. if (pc->l3->debug & L3_DEB_WARN)
  646. l3_debug(pc->l3, "setup with wrong bearer(l=%d:%x,%x)",
  647. p[0], p[1], p[2]);
  648. l3dss1_msg_without_setup(pc, CAUSE_INVALID_CONTENTS);
  649. free_msg(umsg);
  650. return;
  651. }
  652. } else {
  653. if (pc->l3->debug & L3_DEB_WARN)
  654. l3_debug(pc->l3, "setup without bearer capabilities");
  655. /* ETS 300-104 1.3.3 */
  656. l3dss1_msg_without_setup(pc, CAUSE_MANDATORY_IE_MISS);
  657. free_msg(umsg);
  658. return;
  659. }
  660. /*
  661. * Channel Identification
  662. */
  663. if ((setup->CHANNEL_ID = l3dss1_get_channel_id(pc, msg, umsg))) {
  664. if (pc->bc) {
  665. bcfound++;
  666. } else {
  667. if (pc->l3->debug & L3_DEB_WARN)
  668. l3_debug(pc->l3, "setup without bchannel, call waiting");
  669. bcfound++;
  670. }
  671. } else if (pc->err != -1) {
  672. if (pc->l3->debug & L3_DEB_WARN)
  673. l3_debug(pc->l3, "setup with wrong chid ret %d", pc->err);
  674. }
  675. /* Now we are on none mandatory IEs */
  676. setup->COMPLETE =
  677. find_and_copy_ie(msg->data, msg->len, IE_COMPLETE, 0, umsg);
  678. setup->FACILITY =
  679. find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
  680. setup->PROGRESS =
  681. find_and_copy_ie(msg->data, msg->len, IE_PROGRESS, 0, umsg);
  682. setup->NET_FAC =
  683. find_and_copy_ie(msg->data, msg->len, IE_NET_FAC, 0, umsg);
  684. setup->KEYPAD =
  685. find_and_copy_ie(msg->data, msg->len, IE_KEYPAD, 0, umsg);
  686. setup->SIGNAL =
  687. find_and_copy_ie(msg->data, msg->len, IE_SIGNAL, 0, umsg);
  688. setup->CALLED_PN =
  689. find_and_copy_ie(msg->data, msg->len, IE_CALLED_PN, 0, umsg);
  690. setup->CALLED_SUB =
  691. find_and_copy_ie(msg->data, msg->len, IE_CALLED_SUB, 0, umsg);
  692. setup->CALLING_PN =
  693. find_and_copy_ie(msg->data, msg->len, IE_CALLING_PN, 0, umsg);
  694. setup->CALLING_SUB =
  695. find_and_copy_ie(msg->data, msg->len, IE_CALLING_SUB, 0, umsg);
  696. setup->REDIR_NR =
  697. find_and_copy_ie(msg->data, msg->len, IE_REDIR_NR, 0, umsg);
  698. setup->LLC =
  699. find_and_copy_ie(msg->data, msg->len, IE_LLC, 0, umsg);
  700. setup->HLC =
  701. find_and_copy_ie(msg->data, msg->len, IE_HLC, 0, umsg);
  702. setup->USER_USER =
  703. find_and_copy_ie(msg->data, msg->len, IE_USER_USER, 0, umsg);
  704. setup->ces = pc->ces;
  705. newl3state(pc, 1);
  706. L3DelTimer(&pc->timer2);
  707. dprint(DBGM_L3, pc->l3->nst->cardnr, "%s: pc=%p del timer2\n", __FUNCTION__, pc);
  708. L3AddTimer(&pc->timer2, T_CTRL, 0x31f);
  709. if (err) /* STATUS for none mandatory IE errors after actions are taken */
  710. l3dss1_std_ie_err(pc, err);
  711. if (mISDN_l3up(pc, umsg))
  712. free_msg(umsg);
  713. }
  714. static void
  715. l3dss1_disconnect(layer3_proc_t *pc, int pr, void *arg)
  716. {
  717. msg_t *umsg,*msg = arg;
  718. DISCONNECT_t *disc;
  719. if (pc->state == 19) {
  720. // printf("We're in State 19, receive disconnect, so we stay here\n");
  721. return ;
  722. }
  723. umsg = prep_l3data_msg(CC_DISCONNECT | INDICATION, pc->ces |
  724. (pc->callref << 16), sizeof(DISCONNECT_t), msg->len, NULL);
  725. if (!umsg)
  726. return;
  727. disc = (DISCONNECT_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  728. StopAllL3Timer(pc);
  729. newl3state(pc, 11);
  730. if (!(disc->CAUSE = l3dss1_get_cause(pc, msg, umsg))) {
  731. if (pc->l3->debug & L3_DEB_WARN)
  732. l3_debug(pc->l3, "DISC get_cause ret(%d)", pc->err);
  733. }
  734. disc->FACILITY =
  735. find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
  736. disc->SIGNAL =
  737. find_and_copy_ie(msg->data, msg->len, IE_SIGNAL, 0, umsg);
  738. disc->USER_USER =
  739. find_and_copy_ie(msg->data, msg->len, IE_USER_USER, 0, umsg);
  740. if (mISDN_l3up(pc, umsg))
  741. free_msg(umsg);
  742. }
  743. static void
  744. l3dss1_disconnect_i(layer3_proc_t *pc, int pr, void *arg)
  745. {
  746. msg_t *umsg,*msg = arg;
  747. DISCONNECT_t *disc;
  748. u_char cause = 0;
  749. umsg = prep_l3data_msg(CC_DISCONNECT | INDICATION, pc->ces |
  750. (pc->callref << 16), sizeof(DISCONNECT_t), msg->len, NULL);
  751. if (!umsg)
  752. return;
  753. disc = (DISCONNECT_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  754. StopAllL3Timer(pc);
  755. if (!(disc->CAUSE = l3dss1_get_cause(pc, msg, umsg))) {
  756. if (pc->l3->debug & L3_DEB_WARN)
  757. l3_debug(pc->l3, "DISC get_cause ret(%d)", pc->err);
  758. if (pc->err<0)
  759. cause = CAUSE_MANDATORY_IE_MISS;
  760. else if (pc->err>0)
  761. cause = CAUSE_INVALID_CONTENTS;
  762. }
  763. disc->FACILITY =
  764. find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
  765. disc->SIGNAL =
  766. find_and_copy_ie(msg->data, msg->len, IE_SIGNAL, 0, umsg);
  767. disc->USER_USER =
  768. find_and_copy_ie(msg->data, msg->len, IE_USER_USER, 0, umsg);
  769. if (cause)
  770. l3dss1_message_cause(pc, MT_RELEASE, cause);
  771. else
  772. l3dss1_message(pc, MT_RELEASE);
  773. newl3state(pc, 19);
  774. test_and_clear_bit(FLG_L3P_TIMER308_1, &pc->Flags);
  775. L3AddTimer(&pc->timer1, T308, 0x308);
  776. if (mISDN_l3up(pc, umsg))
  777. free_msg(umsg);
  778. }
  779. static void
  780. l3dss1_information(layer3_proc_t *pc, int pr, void *arg) {
  781. msg_t *umsg, *msg = arg;
  782. INFORMATION_t *info;
  783. umsg = prep_l3data_msg(CC_INFORMATION | INDICATION, pc->ces |
  784. (pc->callref << 16), sizeof(INFORMATION_t), msg->len, NULL);
  785. if (!umsg)
  786. return;
  787. info = (INFORMATION_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  788. info->COMPLETE =
  789. find_and_copy_ie(msg->data, msg->len, IE_COMPLETE, 0, umsg);
  790. info->KEYPAD =
  791. find_and_copy_ie(msg->data, msg->len, IE_KEYPAD, 0, umsg);
  792. info->SIGNAL =
  793. find_and_copy_ie(msg->data, msg->len, IE_SIGNAL, 0, umsg);
  794. info->CALLED_PN =
  795. find_and_copy_ie(msg->data, msg->len, IE_CALLED_PN, 0, umsg);
  796. if (pc->state == 2) { /* overlap receiving */
  797. L3DelTimer(&pc->timer1);
  798. L3AddTimer(&pc->timer1, T302, 0x302);
  799. }
  800. if (mISDN_l3up(pc, umsg))
  801. free_msg(umsg);
  802. }
  803. static void
  804. l3dss1_release(layer3_proc_t *pc, int pr, void *arg)
  805. {
  806. msg_t *umsg, *msg = arg;
  807. RELEASE_t *rel;
  808. int cause=0;
  809. umsg = prep_l3data_msg(CC_RELEASE | INDICATION, pc->ces |
  810. (pc->callref << 16), sizeof(RELEASE_t), msg->len, NULL);
  811. if (!umsg)
  812. return;
  813. rel = (RELEASE_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  814. StopAllL3Timer(pc);
  815. if (!(rel->CAUSE = l3dss1_get_cause(pc, msg, umsg))) {
  816. if (pc->state != 12)
  817. if (pc->l3->debug & L3_DEB_WARN)
  818. l3_debug(pc->l3, "REL get_cause ret(%d)",
  819. pc->err);
  820. if ((pc->err<0) && (pc->state != 12))
  821. cause = CAUSE_MANDATORY_IE_MISS;
  822. else if (pc->err>0)
  823. cause = CAUSE_INVALID_CONTENTS;
  824. }
  825. rel->FACILITY =
  826. find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
  827. rel->SIGNAL =
  828. find_and_copy_ie(msg->data, msg->len, IE_SIGNAL, 0, umsg);
  829. rel->USER_USER =
  830. find_and_copy_ie(msg->data, msg->len, IE_USER_USER, 0, umsg);
  831. if (cause)
  832. l3dss1_message_cause(pc, MT_RELEASE_COMPLETE, cause);
  833. else
  834. l3dss1_message(pc, MT_RELEASE_COMPLETE);
  835. if (mISDN_l3up(pc, umsg))
  836. free_msg(umsg);
  837. /*
  838. newl3state(pc, 0);
  839. send_proc(pc, IMSG_END_PROC_M, NULL);
  840. */
  841. }
  842. static void
  843. l3dss1_release_i(layer3_proc_t *pc, int pr, void *arg)
  844. {
  845. l3dss1_message(pc, MT_RELEASE_COMPLETE);
  846. newl3state(pc, 0);
  847. send_proc(pc, IMSG_END_PROC_M, NULL);
  848. }
  849. static void
  850. l3dss1_release_cmpl(layer3_proc_t *pc, int pr, void *arg)
  851. {
  852. msg_t *umsg, *msg = arg;
  853. RELEASE_COMPLETE_t *relc;
  854. umsg = prep_l3data_msg(CC_RELEASE_COMPLETE | INDICATION, pc->ces |
  855. (pc->callref << 16), sizeof(RELEASE_COMPLETE_t), msg->len, NULL);
  856. if (!umsg)
  857. return;
  858. relc = (RELEASE_COMPLETE_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  859. StopAllL3Timer(pc);
  860. newl3state(pc, 0);
  861. if (!(relc->CAUSE = l3dss1_get_cause(pc, msg, umsg))) {
  862. if (pc->err > 0)
  863. if (pc->l3->debug & L3_DEB_WARN)
  864. l3_debug(pc->l3, "RELCMPL get_cause err(%d)",
  865. pc->err);
  866. }
  867. relc->FACILITY =
  868. find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
  869. relc->SIGNAL =
  870. find_and_copy_ie(msg->data, msg->len, IE_SIGNAL, 0, umsg);
  871. relc->USER_USER =
  872. find_and_copy_ie(msg->data, msg->len, IE_USER_USER, 0, umsg);
  873. if (mISDN_l3up(pc, umsg))
  874. free_msg(umsg);
  875. send_proc(pc, IMSG_END_PROC_M, NULL);
  876. }
  877. static void
  878. l3dss1_release_cmpl_i(layer3_proc_t *pc, int pr, void *arg)
  879. {
  880. send_proc(pc, IMSG_END_PROC_M, NULL);
  881. }
  882. static void
  883. l3dss1_setup_acknowledge_i(layer3_proc_t *pc, int pr, void *arg)
  884. {
  885. msg_t *umsg, *msg = arg;
  886. SETUP_ACKNOWLEDGE_t *sa;
  887. dprint(DBGM_L3, pc->l3->nst->cardnr,"%s\n", __FUNCTION__);
  888. if (!pc->master) {
  889. L3DelTimer(&pc->timer1);
  890. newl3state(pc, 25);
  891. return;
  892. }
  893. umsg = prep_l3data_msg(CC_SETUP_ACKNOWLEDGE | INDICATION, pc->master->ces |
  894. (pc->master->callref << 16), sizeof(SETUP_ACKNOWLEDGE_t), msg->len, NULL);
  895. if (!umsg)
  896. return;
  897. sa = (SETUP_ACKNOWLEDGE_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  898. L3DelTimer(&pc->timer1); /* T304 */
  899. newl3state(pc, 25);
  900. sa->CHANNEL_ID =
  901. find_and_copy_ie(msg->data, msg->len, IE_CHANNEL_ID, 0, umsg);
  902. sa->FACILITY =
  903. find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
  904. sa->PROGRESS =
  905. find_and_copy_ie(msg->data, msg->len, IE_PROGRESS, 0, umsg);
  906. if (!mISDN_l3up(pc->master, umsg))
  907. return;
  908. free_msg(umsg);
  909. }
  910. static void
  911. l3dss1_proceeding_i(layer3_proc_t *pc, int pr, void *arg)
  912. {
  913. msg_t *umsg, *msg = arg;
  914. CALL_PROCEEDING_t *proc;
  915. dprint(DBGM_L3, pc->l3->nst->cardnr,"%s\n", __FUNCTION__);
  916. if (!pc->master) {
  917. L3DelTimer(&pc->timer1);
  918. newl3state(pc, 9);
  919. return;
  920. }
  921. umsg = prep_l3data_msg(CC_PROCEEDING | INDICATION, pc->master->ces |
  922. (pc->master->callref << 16), sizeof(CALL_PROCEEDING_t), msg->len, NULL);
  923. if (!umsg)
  924. return;
  925. proc = (CALL_PROCEEDING_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  926. L3DelTimer(&pc->timer1); /* T304 */
  927. newl3state(pc, 9);
  928. proc->CHANNEL_ID =
  929. find_and_copy_ie(msg->data, msg->len, IE_CHANNEL_ID, 0, umsg);
  930. proc->BEARER =
  931. find_and_copy_ie(msg->data, msg->len, IE_BEARER, 0, umsg);
  932. proc->FACILITY =
  933. find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
  934. proc->PROGRESS =
  935. find_and_copy_ie(msg->data, msg->len, IE_PROGRESS, 0, umsg);
  936. proc->HLC =
  937. find_and_copy_ie(msg->data, msg->len, IE_HLC, 0, umsg);
  938. if (!mISDN_l3up(pc->master, umsg))
  939. return;
  940. free_msg(umsg);
  941. }
  942. static void
  943. l3dss1_alerting_i(layer3_proc_t *pc, int pr, void *arg)
  944. {
  945. msg_t *umsg, *msg = arg;
  946. ALERTING_t *al;
  947. dprint(DBGM_L3, pc->l3->nst->cardnr,"%s\n", __FUNCTION__);
  948. if (!pc->master) {
  949. L3DelTimer(&pc->timer1);
  950. newl3state(pc, 7);
  951. return;
  952. }
  953. umsg = prep_l3data_msg(CC_ALERTING | INDICATION, pc->master->ces |
  954. (pc->master->callref << 16), sizeof(ALERTING_t), msg->len, NULL);
  955. if (!umsg)
  956. return;
  957. al = (ALERTING_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  958. L3DelTimer(&pc->timer1); /* T304 */
  959. newl3state(pc, 7);
  960. al->CHANNEL_ID =
  961. find_and_copy_ie(msg->data, msg->len, IE_CHANNEL_ID, 0, umsg);
  962. al->BEARER =
  963. find_and_copy_ie(msg->data, msg->len, IE_BEARER, 0, umsg);
  964. al->FACILITY =
  965. find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
  966. al->PROGRESS =
  967. find_and_copy_ie(msg->data, msg->len, IE_PROGRESS, 0, umsg);
  968. al->SIGNAL =
  969. find_and_copy_ie(msg->data, msg->len, IE_SIGNAL, 0, umsg);
  970. al->HLC =
  971. find_and_copy_ie(msg->data, msg->len, IE_HLC, 0, umsg);
  972. al->USER_USER =
  973. find_and_copy_ie(msg->data, msg->len, IE_USER_USER, 0, umsg);
  974. al->REDIR_DN =
  975. find_and_copy_ie(msg->data, msg->len, IE_REDIR_DN, 0, umsg);
  976. if (!mISDN_l3up(pc->master, umsg))
  977. return;
  978. free_msg(umsg);
  979. }
  980. #if 0
  981. static void
  982. l3dss1_call_proc(layer3_proc_t *pc, int pr, void *arg)
  983. {
  984. msg_t *umsg, *msg = arg;
  985. int ret = 0;
  986. u_char cause;
  987. CALL_PROCEEDING_t *cp;
  988. umsg = prep_l3data_msg(CC_PROCEEDING | INDICATION, pc->ces |
  989. (pc->callref << 16), sizeof(CALL_PROCEEDING_t), msg->len, NULL);
  990. if (!umsg)
  991. return;
  992. cp = (CALL_PROCEEDING_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  993. if ((cp->CHANNEL_ID = l3dss1_get_channel_id(pc, msg, umsg))) {
  994. if (!(pc->l3->nst->feature & FEATURE_NET_EXTCID)) { /* BRI */
  995. if ((0 == pc->bc) || (3 == pc->bc)) {
  996. if (pc->l3->debug & L3_DEB_WARN)
  997. l3_debug(pc->l3, "setup answer with wrong chid %x", pc->bc);
  998. l3dss1_status_send(pc, CAUSE_INVALID_CONTENTS);
  999. free_msg(umsg);
  1000. return;
  1001. }
  1002. }
  1003. } else if (1 == pc->state) {
  1004. if (pc->l3->debug & L3_DEB_WARN)
  1005. l3_debug(pc->l3, "setup answer wrong chid (ret %d)", pc->err);
  1006. if (pc->err == -1)
  1007. cause = CAUSE_MANDATORY_IE_MISS;
  1008. else
  1009. cause = CAUSE_INVALID_CONTENTS;
  1010. l3dss1_status_send(pc, cause);
  1011. free_msg(umsg);
  1012. return;
  1013. }
  1014. /* Now we are on none mandatory IEs */
  1015. cp->BEARER =
  1016. find_and_copy_ie(msg->data, msg->len, IE_BEARER, 0, umsg);
  1017. cp->FACILITY =
  1018. find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
  1019. cp->PROGRESS =
  1020. find_and_copy_ie(msg->data, msg->len, IE_PROGRESS, 0, umsg);
  1021. cp->DISPLAY =
  1022. find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
  1023. cp->REDIR_DN =
  1024. find_and_copy_ie(msg->data, msg->len, IE_REDIR_DN, 0, umsg);
  1025. cp->HLC =
  1026. find_and_copy_ie(msg->data, msg->len, IE_HLC, 0, umsg);
  1027. L3DelTimer(&pc->timer1);
  1028. newl3state(pc, 3);
  1029. L3AddTimer(&pc->timer1, T310, 0x310);
  1030. if (ret) /* STATUS for none mandatory IE errors after actions are taken */
  1031. l3dss1_std_ie_err(pc, ret);
  1032. if (mISDN_l3up(pc, umsg))
  1033. free_msg(umsg);
  1034. }
  1035. #endif
  1036. static void
  1037. l3dss1_connect_i(layer3_proc_t *pc, int pr, void *arg)
  1038. {
  1039. msg_t *umsg, *msg = arg;
  1040. CONNECT_t *conn;
  1041. if (!pc->master) {
  1042. L3DelTimer(&pc->timer1);
  1043. newl3state(pc, 8);
  1044. return;
  1045. }
  1046. umsg = prep_l3data_msg(CC_CONNECT | INDICATION, pc->master->ces |
  1047. (pc->master->callref << 16), sizeof(CONNECT_t), msg->len, NULL);
  1048. if (!umsg)
  1049. return;
  1050. conn = (CONNECT_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  1051. L3DelTimer(&pc->timer1); /* T310 */
  1052. newl3state(pc, 8);
  1053. conn->BEARER =
  1054. find_and_copy_ie(msg->data, msg->len, IE_BEARER, 0, umsg);
  1055. conn->FACILITY =
  1056. find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
  1057. conn->PROGRESS =
  1058. find_and_copy_ie(msg->data, msg->len, IE_PROGRESS, 0, umsg);
  1059. conn->DISPLAY =
  1060. find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
  1061. conn->DATE =
  1062. find_and_copy_ie(msg->data, msg->len, IE_DATE, 0, umsg);
  1063. conn->SIGNAL =
  1064. find_and_copy_ie(msg->data, msg->len, IE_SIGNAL, 0, umsg);
  1065. conn->CONNECT_PN =
  1066. find_and_copy_ie(msg->data, msg->len, IE_CONNECT_PN, 0, umsg);
  1067. conn->CONNECT_SUB =
  1068. find_and_copy_ie(msg->data, msg->len, IE_CONNECT_SUB, 0, umsg);
  1069. conn->HLC =
  1070. find_and_copy_ie(msg->data, msg->len, IE_HLC, 0, umsg);
  1071. conn->LLC =
  1072. find_and_copy_ie(msg->data, msg->len, IE_LLC, 0, umsg);
  1073. conn->USER_USER =
  1074. find_and_copy_ie(msg->data, msg->len, IE_USER_USER, 0, umsg);
  1075. conn->ces = pc->ces;
  1076. if (send_proc(pc, IMSG_CONNECT_IND, umsg))
  1077. free_msg(umsg);
  1078. }
  1079. static void
  1080. l3dss1_hold(layer3_proc_t *pc, int pr, void *arg)
  1081. {
  1082. msg_t *umsg, *msg = arg;
  1083. HOLD_t *hold;
  1084. if (!(pc->l3->nst->feature & FEATURE_NET_HOLD)) {
  1085. l3dss1_message_cause(pc, MT_HOLD_REJECT, CAUSE_MT_NOTIMPLEMENTED);
  1086. return;
  1087. }
  1088. dprint(DBGM_L3, pc->l3->nst->cardnr,"%s\n", __FUNCTION__);
  1089. if (pc->hold_state == HOLDAUX_HOLD_IND)
  1090. return;
  1091. if (pc->hold_state != HOLDAUX_IDLE) {
  1092. l3dss1_message_cause(pc, MT_HOLD_REJECT, CAUSE_NOTCOMPAT_STATE);
  1093. return;
  1094. }
  1095. pc->hold_state = HOLDAUX_HOLD_IND;
  1096. umsg = prep_l3data_msg(CC_HOLD | INDICATION, pc->ces |
  1097. (pc->callref << 16), sizeof(HOLD_t), msg->len, NULL);
  1098. if (!umsg)
  1099. return;
  1100. hold = (HOLD_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  1101. if (mISDN_l3up(pc, umsg))
  1102. free_msg(umsg);
  1103. }
  1104. static void
  1105. l3dss1_retrieve(layer3_proc_t *pc, int pr, void *arg)
  1106. {
  1107. msg_t *umsg, *msg = arg;
  1108. RETRIEVE_t *retr;
  1109. if (!(pc->l3->nst->feature & FEATURE_NET_HOLD)) {
  1110. l3dss1_message_cause(pc, MT_RETRIEVE_REJECT, CAUSE_MT_NOTIMPLEMENTED);
  1111. return;
  1112. }
  1113. dprint(DBGM_L3, pc->l3->nst->cardnr,"%s\n", __FUNCTION__);
  1114. if (pc->hold_state == HOLDAUX_RETR_IND)
  1115. return;
  1116. if (pc->hold_state != HOLDAUX_HOLD) {
  1117. l3dss1_message_cause(pc, MT_RETRIEVE_REJECT, CAUSE_NOTCOMPAT_STATE);
  1118. return;
  1119. }
  1120. pc->hold_state = HOLDAUX_RETR_IND;
  1121. umsg = prep_l3data_msg(CC_RETRIEVE | INDICATION, pc->ces |
  1122. (pc->callref << 16), sizeof(RETRIEVE_t), msg->len, NULL);
  1123. if (!umsg)
  1124. return;
  1125. retr = (RETRIEVE_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  1126. retr->CHANNEL_ID =
  1127. find_and_copy_ie(msg->data, msg->len, IE_CHANNEL_ID, 0, umsg);
  1128. if (mISDN_l3up(pc, umsg))
  1129. free_msg(umsg);
  1130. }
  1131. static void
  1132. l3dss1_suspend(layer3_proc_t *pc, int pr, void *arg)
  1133. {
  1134. msg_t *umsg, *msg = arg;
  1135. SUSPEND_t *susp;
  1136. dprint(DBGM_L3, pc->l3->nst->cardnr,"%s\n", __FUNCTION__);
  1137. umsg = prep_l3data_msg(CC_SUSPEND | INDICATION, pc->ces |
  1138. (pc->callref << 16), sizeof(SUSPEND_t), msg->len, NULL);
  1139. if (!umsg)
  1140. return;
  1141. susp = (SUSPEND_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  1142. susp->CALL_ID =
  1143. find_and_copy_ie(msg->data, msg->len, IE_CALL_ID, 0, umsg);
  1144. susp->FACILITY =
  1145. find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
  1146. newl3state(pc, 15);
  1147. if (mISDN_l3up(pc, umsg))
  1148. free_msg(umsg);
  1149. }
  1150. static void
  1151. l3dss1_resume(layer3_proc_t *pc, int pr, void *arg)
  1152. {
  1153. msg_t *umsg, *msg = arg;
  1154. RESUME_t *res;
  1155. dprint(DBGM_L3, pc->l3->nst->cardnr,"%s\n", __FUNCTION__);
  1156. umsg = prep_l3data_msg(CC_RESUME | INDICATION, pc->ces |
  1157. (pc->callref << 16), sizeof(RESUME_t), msg->len, NULL);
  1158. if (!umsg)
  1159. return;
  1160. res = (RESUME_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
  1161. res->CALL_ID =
  1162. find_and_copy_ie(msg->data, msg->len, IE_CALL_ID, 0, umsg);
  1163. res->FACILITY =
  1164. find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
  1165. res->ces = pc->ces;
  1166. newl3state(pc, 17);
  1167. if (mISDN_l3up(pc, umsg))
  1168. free_msg(umsg);
  1169. }
  1170. static struct stateentry datastatelist[] =
  1171. {
  1172. {ALL_STATES,
  1173. MT_STATUS_ENQUIRY, l3dss1_status_enq},
  1174. {ALL_STATES,
  1175. MT_FACILITY, l3dss1_facility},
  1176. {SBIT(19),
  1177. MT_STATUS, l3dss1_release_cmpl},
  1178. {SBIT(0),
  1179. MT_SETUP, l3dss1_setup},
  1180. {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
  1181. MT_SETUP_ACKNOWLEDGE, l3dss1_setup_acknowledge_i},
  1182. {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
  1183. MT_CALL_PROCEEDING, l3dss1_proceeding_i},
  1184. {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
  1185. MT_ALERTING, l3dss1_alerting_i},
  1186. {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
  1187. MT_CONNECT, l3dss1_connect_i},
  1188. {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(10) | SBIT(19),
  1189. MT_DISCONNECT, l3dss1_disconnect},
  1190. {SBIT(7) | SBIT(8) | SBIT(9) | SBIT(25),
  1191. MT_DISCONNECT, l3dss1_disconnect_i},
  1192. {SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) |
  1193. SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25),
  1194. MT_INFORMATION, l3dss1_information},
  1195. {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(10) |
  1196. SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17),
  1197. MT_RELEASE, l3dss1_release},
  1198. {SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(19) | SBIT(25),
  1199. MT_RELEASE, l3dss1_release_i},
  1200. {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(10) |
  1201. SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19),
  1202. MT_RELEASE_COMPLETE, l3dss1_release_cmpl},
  1203. {SBIT(4) | SBIT(7) | SBIT(10),
  1204. MT_USER_INFORMATION, l3dss1_userinfo},
  1205. {SBIT(7) | SBIT(8) | SBIT(9) | SBIT(25),
  1206. MT_RELEASE_COMPLETE, l3dss1_release_cmpl_i},
  1207. {SBIT(3) | SBIT(4) | SBIT(10),
  1208. MT_HOLD, l3dss1_hold},
  1209. {SBIT(3) | SBIT(4) | SBIT(10) | SBIT(12),
  1210. MT_RETRIEVE, l3dss1_retrieve},
  1211. {SBIT(10),
  1212. MT_SUSPEND, l3dss1_suspend},
  1213. {SBIT(0),
  1214. MT_RESUME, l3dss1_resume},
  1215. };
  1216. #define DATASLLEN \
  1217. (sizeof(datastatelist) / sizeof(struct stateentry))
  1218. static layer3_proc_t
  1219. *create_child_proc(layer3_proc_t *pc, int mt, msg_t *msg, int state) {
  1220. mISDNuser_head_t *hh;
  1221. struct _l3_msg l3m;
  1222. layer3_proc_t *p3i;
  1223. hh = (mISDNuser_head_t *)msg->data;
  1224. msg_pull(msg, mISDNUSER_HEAD_SIZE);
  1225. p3i = create_proc(pc->l3, hh->dinfo, pc->callref, pc);
  1226. if (!p3i) {
  1227. l3_debug(pc->l3, "cannot create child\n");
  1228. return(NULL);
  1229. }
  1230. p3i->state = pc->state;
  1231. if (pc->state != -1)
  1232. newl3state(pc, state);
  1233. l3m.mt = mt;
  1234. l3m.msg = msg;
  1235. send_proc(p3i, IMSG_L2_DATA, &l3m);
  1236. return(p3i);
  1237. }
  1238. static void
  1239. l3dss1_setup_acknowledge_m(layer3_proc_t *pc, int pr, void *arg)
  1240. {
  1241. dprint(DBGM_L3, pc->l3->nst->cardnr,"%s\n", __FUNCTION__);
  1242. L3DelTimer(&pc->timer1);
  1243. create_child_proc(pc, pr, arg, 25);
  1244. }
  1245. static void
  1246. l3dss1_proceeding_m(layer3_proc_t *pc, int pr, void *arg)
  1247. {
  1248. dprint(DBGM_L3, pc->l3->nst->cardnr,"%s\n", __FUNCTION__);
  1249. L3DelTimer(&pc->timer1);
  1250. create_child_proc(pc, pr, arg, 9);
  1251. }
  1252. static void
  1253. l3dss1_alerting_m(layer3_proc_t *pc, int pr, void *arg)
  1254. {
  1255. dprint(DBGM_L3, pc->l3->nst->cardnr,"%s\n", __FUNCTION__);
  1256. L3DelTimer(&pc->timer1);
  1257. create_child_proc(pc, pr, arg, 7);
  1258. }
  1259. static void
  1260. l3dss1_connect_m(layer3_proc_t *pc, int pr, void *arg)
  1261. {
  1262. dprint(DBGM_L3, pc->l3->nst->cardnr,"%s\n", __FUNCTION__);
  1263. L3DelTimer(&pc->timer1);
  1264. create_child_proc(pc, pr, arg, 8);
  1265. }
  1266. static void
  1267. l3dss1_release_m(layer3_proc_t *pc, int pr, void *arg)
  1268. {
  1269. msg_t *msg = arg;
  1270. msg_pull(msg, mISDNUSER_HEAD_SIZE);
  1271. l3dss1_release_i(pc, pr, msg);
  1272. }
  1273. static void
  1274. l3dss1_release_mx(layer3_proc_t *pc, int pr, void *arg)
  1275. {
  1276. msg_t *msg = arg;
  1277. msg_pull(msg, mISDNUSER_HEAD_SIZE);
  1278. l3dss1_release(pc, pr, msg);
  1279. }
  1280. static void
  1281. l3dss1_release_cmpl_m(layer3_proc_t *pc, int pr, void *arg)
  1282. {
  1283. msg_t *msg = arg;
  1284. u_char *p;
  1285. if (pc->state == 6) {
  1286. msg_pull(msg, mISDNUSER_HEAD_SIZE);
  1287. if ((p = l3dss1_get_cause(pc, msg, NULL))) {
  1288. dprint(DBGM_L3, pc->l3->nst->cardnr,"%s cause (%d/%d)\n", __FUNCTION__,
  1289. pc->cause, pc->err);
  1290. switch(pc->cause) {
  1291. case CAUSE_USER_BUSY:
  1292. break;
  1293. case CAUSE_CALL_REJECTED:
  1294. if (pc->err == CAUSE_USER_BUSY)
  1295. pc->cause = pc->err;
  1296. break;
  1297. default:
  1298. pc->cause = pc->err;
  1299. }
  1300. }
  1301. test_and_set_bit(FLG_L3P_GOTRELCOMP, &pc->Flags);
  1302. }
  1303. }
  1304. static void
  1305. l3dss1_release_cmpl_mx(layer3_proc_t *pc, int pr, void *arg)
  1306. {
  1307. msg_t *msg = arg;
  1308. msg_pull(msg, mISDNUSER_HEAD_SIZE);
  1309. l3dss1_release_cmpl(pc, pr, msg);
  1310. }
  1311. static void
  1312. l3dss1_information_mx(layer3_proc_t *pc, int pr, void *arg)
  1313. {
  1314. msg_t *msg = arg;
  1315. msg_pull(msg, mISDNUSER_HEAD_SIZE);
  1316. l3dss1_information(pc, pr, msg);
  1317. }
  1318. static struct stateentry mdatastatelist[] =
  1319. {
  1320. {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
  1321. MT_SETUP_ACKNOWLEDGE, l3dss1_setup_acknowledge_m},
  1322. {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
  1323. MT_CALL_PROCEEDING, l3dss1_proceeding_m},
  1324. {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
  1325. MT_ALERTING, l3dss1_alerting_m},
  1326. {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
  1327. MT_CONNECT, l3dss1_connect_m},
  1328. {SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) |
  1329. SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25),
  1330. MT_INFORMATION, l3dss1_information_mx},
  1331. {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(10) | SBIT(11) |
  1332. SBIT(12) | SBIT(15) | SBIT(17),
  1333. MT_RELEASE, l3dss1_release_mx},
  1334. {SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(22) | SBIT(25),
  1335. MT_RELEASE, l3dss1_release_m},
  1336. {SBIT(19), MT_RELEASE, l3dss1_release_cmpl},
  1337. {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(10) |
  1338. SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19),
  1339. MT_RELEASE_COMPLETE, l3dss1_release_cmpl_mx},
  1340. {SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(22) | SBIT(25),
  1341. MT_RELEASE_COMPLETE, l3dss1_release_cmpl_m},
  1342. };
  1343. #define MDATASLLEN \
  1344. (sizeof(mdatastatelist) / sizeof(struct stateentry))
  1345. static void
  1346. l3dss1_setup_ack_req(layer3_proc_t *pc, int pr, void *arg)
  1347. {
  1348. SETUP_ACKNOWLEDGE_t *setup_ack = arg;
  1349. if (setup_ack) {
  1350. MsgStart(pc, MT_SETUP_ACKNOWLEDGE);
  1351. if (setup_ack->CHANNEL_ID) {
  1352. if (setup_ack->CHANNEL_ID[0] == 1)
  1353. pc->bc = setup_ack->CHANNEL_ID[1] & 3;
  1354. AddvarIE(pc, IE_CHANNEL_ID, setup_ack->CHANNEL_ID);
  1355. }
  1356. if (setup_ack->FACILITY)
  1357. AddvarIE(pc, IE_FACILITY, setup_ack->FACILITY);
  1358. if (setup_ack->PROGRESS)
  1359. AddvarIE(pc, IE_PROGRESS, setup_ack->PROGRESS);
  1360. if (setup_ack->DISPLAY)
  1361. AddvarIE(pc, IE_DISPLAY, setup_ack->DISPLAY);
  1362. SendMsg(pc, 2);
  1363. } else {
  1364. newl3state(pc, 2);
  1365. l3dss1_message(pc, MT_SETUP_ACKNOWLEDGE);
  1366. }
  1367. L3DelTimer(&pc->timer1);
  1368. L3AddTimer(&pc->timer1, T302, 0x302);
  1369. }
  1370. static void
  1371. l3dss1_proceed_req(layer3_proc_t *pc, int pr, void *arg)
  1372. {
  1373. CALL_PROCEEDING_t *cproc = arg;
  1374. L3DelTimer(&pc->timer1);
  1375. if (cproc) {
  1376. MsgStart(pc, MT_CALL_PROCEEDING);
  1377. if (cproc->BEARER)
  1378. AddvarIE(pc, IE_BEARER, cproc->BEARER);
  1379. if (cproc->CHANNEL_ID) {
  1380. if (cproc->CHANNEL_ID[0] == 1)
  1381. pc->bc = cproc->CHANNEL_ID[1] & 3;
  1382. AddvarIE(pc, IE_CHANNEL_ID, cproc->CHANNEL_ID);
  1383. }
  1384. if (cproc->FACILITY)
  1385. AddvarIE(pc, IE_FACILITY, cproc->FACILITY);
  1386. if (cproc->PROGRESS)
  1387. AddvarIE(pc, IE_PROGRESS, cproc->PROGRESS);
  1388. if (cproc->DISPLAY)
  1389. AddvarIE(pc, IE_DISPLAY, cproc->DISPLAY);
  1390. if (cproc->REDIR_DN)
  1391. AddvarIE(pc, IE_REDIR_DN, cproc->REDIR_DN);
  1392. if (cproc->HLC)
  1393. AddvarIE(pc, IE_HLC, cproc->HLC);
  1394. SendMsg(pc, 3);
  1395. } else {
  1396. newl3state(pc, 3);
  1397. l3dss1_message(pc, MT_CALL_PROCEEDING);
  1398. }
  1399. }
  1400. static void
  1401. l3dss1_alert_req(layer3_proc_t *pc, int pr, void *arg)
  1402. {
  1403. ALERTING_t *alert = arg;
  1404. if (alert) {
  1405. MsgStart(pc, MT_ALERTING);
  1406. if (alert->BEARER)
  1407. AddvarIE(pc, IE_BEARER, alert->BEARER);
  1408. if (alert->CHANNEL_ID) {
  1409. if (alert->CHANNEL_ID[0] == 1)
  1410. pc->bc = alert->CHANNEL_ID[1] & 3;
  1411. AddvarIE(pc, IE_CHANNEL_ID, alert->CHANNEL_ID);
  1412. }
  1413. if (alert->FACILITY)
  1414. AddvarIE(pc, IE_FACILITY, alert->FACILITY);
  1415. if (alert->PROGRESS)
  1416. AddvarIE(pc, IE_PROGRESS, alert->PROGRESS);
  1417. if (alert->DISPLAY)
  1418. AddvarIE(pc, IE_DISPLAY, alert->DISPLAY);
  1419. if (alert->HLC)
  1420. AddvarIE(pc, IE_HLC, alert->HLC);
  1421. if (alert->USER_USER)
  1422. AddvarIE(pc, IE_USER_USER, alert->USER_USER);
  1423. if (alert->REDIR_DN)
  1424. AddvarIE(pc, IE_REDIR_DN, alert->REDIR_DN);
  1425. SendMsg(pc, 4);
  1426. } else {
  1427. newl3state(pc, 4);
  1428. l3dss1_message(pc, MT_ALERTING);
  1429. }
  1430. L3DelTimer(&pc->timer1);
  1431. }
  1432. static void
  1433. l3dss1_setup_req(layer3_proc_t *pc, int pr, void *arg)
  1434. {
  1435. SETUP_t *setup = arg;
  1436. msg_t *msg;
  1437. int l;
  1438. MsgStart(pc, MT_SETUP);
  1439. if (setup->COMPLETE)
  1440. *pc->op++ = IE_COMPLETE;
  1441. if (setup->BEARER)
  1442. AddvarIE(pc, IE_BEARER, setup->BEARER);
  1443. if (setup->CHANNEL_ID) {
  1444. if (setup->CHANNEL_ID[0] == 1)
  1445. pc->bc = setup->CHANNEL_ID[1] & 3;
  1446. AddvarIE(pc, IE_CHANNEL_ID, setup->CHANNEL_ID);
  1447. }
  1448. if (setup->FACILITY)
  1449. AddvarIE(pc, IE_FACILITY, setup->FACILITY);
  1450. if (setup->PROGRESS)
  1451. AddvarIE(pc, IE_PROGRESS, setup->PROGRESS);
  1452. if (setup->NET_FAC)
  1453. AddvarIE(pc, IE_NET_FAC, setup->NET_FAC);
  1454. if (setup->DISPLAY)
  1455. AddvarIE(pc, IE_DISPLAY, setup->DISPLAY);
  1456. if (setup->KEYPAD)
  1457. AddvarIE(pc, IE_KEYPAD, setup->KEYPAD);
  1458. if (setup->CALLING_PN)
  1459. AddvarIE(pc, IE_CALLING_PN, setup->CALLING_PN);
  1460. if (setup->CALLING_SUB)
  1461. AddvarIE(pc, IE_CALLING_SUB, setup->CALLING_SUB);
  1462. if (setup->CALLED_PN)
  1463. AddvarIE(pc, IE_CALLED_PN, setup->CALLED_PN);
  1464. if (setup->CALLED_SUB)
  1465. AddvarIE(pc, IE_CALLED_SUB, setup->CALLED_SUB);
  1466. if (setup->LLC)
  1467. AddvarIE(pc, IE_LLC, setup->LLC);
  1468. if (setup->HLC)
  1469. AddvarIE(pc, IE_HLC, setup->HLC);
  1470. if (setup->USER_USER)
  1471. AddvarIE(pc, IE_USER_USER, setup->USER_USER);
  1472. l = pc->op - &pc->obuf[0];
  1473. if (!(msg = l3_alloc_msg(l)))
  1474. return;
  1475. memcpy(msg_put(msg, l), &pc->obuf[0], l);
  1476. newl3state(pc, 6);
  1477. dhexprint(DBGM_L3DATA, "l3 oframe:", &pc->obuf[0], l);
  1478. if (pc->l3->nst->feature & FEATURE_NET_PTP) {
  1479. dprint(DBGM_L3, pc->l3->nst->cardnr, "%s: proc(%p) sending SETUP to CES 0\n", __FUNCTION__, pc);
  1480. if (l3_msg(pc->l3, DL_DATA | REQUEST, 0, msg))
  1481. free_msg(msg);
  1482. } else {
  1483. dprint(DBGM_L3, pc->l3->nst->cardnr, "%s: proc(%p) sending SETUP to broadcast CES\n", __FUNCTION__, pc);
  1484. if (l3_msg(pc->l3, DL_UNITDATA | REQUEST, 127, msg))
  1485. free_msg(msg);
  1486. }
  1487. L3DelTimer(&pc->timer1);
  1488. test_and_clear_bit(FLG_L3P_TIMER303_1, &pc->Flags);
  1489. L3AddTimer(&pc->timer1, T303, 0x303);
  1490. L3DelTimer(&pc->timer2);
  1491. if (!(pc->l3->nst->feature & FEATURE_NET_PTP)) {
  1492. test_and_set_bit(FLG_L3P_TIMER312, &pc->Flags);
  1493. L3AddTimer(&pc->timer2, T312, 0x312);
  1494. }
  1495. }
  1496. static void
  1497. l3dss1_disconnect_req(layer3_proc_t *pc, int pr, void *arg);
  1498. static void
  1499. l3dss1_connect_req(layer3_proc_t *pc, int pr, void *arg)
  1500. {
  1501. CONNECT_t *conn = arg;
  1502. L3DelTimer(&pc->timer1);
  1503. if (conn && conn->CHANNEL_ID) {
  1504. if (conn->CHANNEL_ID[0] == 1)
  1505. pc->bc = conn->CHANNEL_ID[1] & 3;
  1506. }
  1507. if (conn) {
  1508. MsgStart(pc, MT_CONNECT);
  1509. if (conn->BEARER)
  1510. AddvarIE(pc, IE_BEARER, conn->BEARER);
  1511. if (conn->CHANNEL_ID)
  1512. AddvarIE(pc, IE_CHANNEL_ID, conn->CHANNEL_ID);
  1513. if (conn->FACILITY)
  1514. AddvarIE(pc, IE_FACILITY, conn->FACILITY);
  1515. if (conn->PROGRESS)
  1516. AddvarIE(pc, IE_PROGRESS, conn->PROGRESS);
  1517. if (conn->DISPLAY)
  1518. AddvarIE(pc, IE_DISPLAY, conn->DISPLAY);
  1519. if (conn->DATE)
  1520. AddvarIE(pc, IE_DATE, conn->DATE);
  1521. if (conn->CONNECT_PN)
  1522. AddvarIE(pc, IE_CONNECT_PN, conn->CONNECT_PN);
  1523. if (conn->CONNECT_SUB)
  1524. AddvarIE(pc, IE_CONNECT_SUB, conn->CONNECT_SUB);
  1525. if (conn->LLC)
  1526. AddvarIE(pc, IE_LLC, conn->LLC);
  1527. if (conn->HLC)
  1528. AddvarIE(pc, IE_HLC, conn->HLC);
  1529. if (conn->USER_USER)
  1530. AddvarIE(pc, IE_USER_USER, conn->USER_USER);
  1531. SendMsg(pc, 10);
  1532. } else {
  1533. newl3state(pc, 10);
  1534. l3dss1_message(pc, MT_CONNECT);
  1535. }
  1536. }
  1537. static void
  1538. l3dss1_connect_res(layer3_proc_t *pc, int pr, void *arg)
  1539. {
  1540. CONNECT_ACKNOWLEDGE_t *connack = arg;
  1541. int cause;
  1542. L3DelTimer(&pc->timer1);
  1543. send_proc(pc, IMSG_SEL_PROC, NULL);
  1544. if (connack && connack->CHANNEL_ID) {
  1545. if (connack->CHANNEL_ID[0] == 1)
  1546. pc->bc = connack->CHANNEL_ID[1] & 3;
  1547. }
  1548. #if 0
  1549. if (!pc->bc) {
  1550. if (pc->l3->debug & L3_DEB_WARN)
  1551. l3_debug(pc->l3, "D-chan connect for waiting call");
  1552. l3dss1_disconnect_req(pc, pr, NULL);
  1553. return;
  1554. }
  1555. #endif
  1556. if (connack) {
  1557. MsgStart(pc, MT_CONNECT_ACKNOWLEDGE);
  1558. if (connack->CHANNEL_ID)
  1559. AddvarIE(pc, IE_CHANNEL_ID, connack->CHANNEL_ID);
  1560. if (connack->DISPLAY)
  1561. AddvarIE(pc, IE_DISPLAY, connack->DISPLAY);
  1562. if (connack->SIGNAL)
  1563. AddvarIE(pc, IE_SIGNAL, connack->SIGNAL);
  1564. SendMsg(pc, 10);
  1565. } else {
  1566. newl3state(pc, 10);
  1567. l3dss1_message(pc, MT_CONNECT_ACKNOWLEDGE);
  1568. }
  1569. cause = CAUSE_NONSELECTED_USER;
  1570. send_proc(pc, IMSG_RELEASE_CHILDS, &cause);
  1571. }
  1572. static void
  1573. l3dss1_disconnect_req(layer3_proc_t *pc, int pr, void *arg)
  1574. {
  1575. DISCONNECT_t *disc = arg;
  1576. StopAllL3Timer(pc);
  1577. if (disc) {
  1578. MsgStart(pc, MT_DISCONNECT);
  1579. if (disc->CAUSE){
  1580. AddvarIE(pc, IE_CAUSE, disc->CAUSE);
  1581. } else {
  1582. *pc->op++ = IE_CAUSE;
  1583. *pc->op++ = 2;
  1584. *pc->op++ = 0x80 | CAUSE_LOC_PNET_LOCUSER;
  1585. *pc->op++ = 0x80 | CAUSE_NORMALUNSPECIFIED;
  1586. }
  1587. if (disc->FACILITY)
  1588. AddvarIE(pc, IE_FACILITY, disc->FACILITY);
  1589. if (disc->PROGRESS)
  1590. AddvarIE(pc, IE_PROGRESS, disc->PROGRESS);
  1591. if (disc->DISPLAY)
  1592. AddvarIE(pc, IE_DISPLAY, disc->DISPLAY);
  1593. if (disc->USER_USER)
  1594. AddvarIE(pc, IE_USER_USER, disc->USER_USER);
  1595. SendMsg(pc, 12);
  1596. } else {
  1597. newl3state(pc, 12);
  1598. l3dss1_message_cause(pc, MT_DISCONNECT, CAUSE_NORMALUNSPECIFIED);
  1599. }
  1600. L3AddTimer(&pc->timer1, T305, 0x305);
  1601. }
  1602. static void
  1603. l3dss1_facility_req(layer3_proc_t *pc, int pr, void *arg)
  1604. {
  1605. FACILITY_t *fac = arg;
  1606. if (fac) {
  1607. MsgStart(pc, MT_FACILITY);
  1608. if (fac->FACILITY)
  1609. AddvarIE(pc, IE_FACILITY, fac->FACILITY);
  1610. else
  1611. return;
  1612. if (fac->DISPLAY)
  1613. AddvarIE(pc, IE_DISPLAY, fac->DISPLAY);
  1614. SendMsg(pc, -1);
  1615. }
  1616. }
  1617. static void
  1618. l3dss1_userinfo_req(layer3_proc_t *pc, int pr, void *arg)
  1619. {
  1620. USER_INFORMATION_t *ui = arg;
  1621. if (ui) {
  1622. MsgStart(pc, MT_USER_INFORMATION);
  1623. if (ui->USER_USER)
  1624. AddvarIE(pc, IE_USER_USER, ui->USER_USER);
  1625. else
  1626. return;
  1627. SendMsg(pc, -1);
  1628. }
  1629. }
  1630. static void
  1631. l3dss1_information_req(layer3_proc_t *pc, int pr, void *arg)
  1632. {
  1633. INFORMATION_t *info = arg;
  1634. msg_t *msg;
  1635. int l;
  1636. if (pc->state == 25 && !(pc->l3->nst->feature & FEATURE_NET_PTP))
  1637. return;
  1638. if (info) {
  1639. MsgStart(pc, MT_INFORMATION);
  1640. if (info->COMPLETE)
  1641. *pc->op++ = IE_COMPLETE;
  1642. if (info->DISPLAY)
  1643. AddvarIE(pc, IE_DISPLAY, info->DISPLAY);
  1644. if (info->KEYPAD)
  1645. AddvarIE(pc, IE_KEYPAD, info->KEYPAD);
  1646. if (info->SIGNAL)
  1647. AddvarIE(pc, IE_SIGNAL, info->SIGNAL);
  1648. if (info->CALLED_PN)
  1649. AddvarIE(pc, IE_CALLED_PN, info->CALLED_PN);
  1650. if (pc->state != 25)
  1651. SendMsg(pc, -1);
  1652. else {
  1653. l = pc->op - &pc->obuf[0];
  1654. if (!(msg = l3_alloc_msg(l)))
  1655. return;
  1656. memcpy(msg_put(msg, l), &pc->obuf[0], l);
  1657. dhexprint(DBGM_L3DATA, "l3 oframe:", &pc->obuf[0], l);
  1658. dprint(DBGM_L3, pc->l3->nst->cardnr, "%s: proc(%p) sending INFORMATION to CES 0 during state 25 (OVERLAP)\n", __FUNCTION__, pc);
  1659. if (l3_msg(pc->l3, DL_DATA | REQUEST, 0, msg))
  1660. free_msg(msg);
  1661. }
  1662. }
  1663. }
  1664. static void
  1665. l3dss1_progress_req(layer3_proc_t *pc, int pr, void *arg)
  1666. {
  1667. PROGRESS_t *prog = arg;
  1668. if (prog) {
  1669. MsgStart(pc, MT_INFORMATION);
  1670. if (prog->BEARER)
  1671. AddvarIE(pc, IE_BEARER, prog->BEARER);
  1672. if (prog->CAUSE)
  1673. AddvarIE(pc, IE_CAUSE, prog->CAUSE);
  1674. if (prog->FACILITY)
  1675. AddvarIE(pc, IE_FACILITY, prog->FACILITY);
  1676. if (prog->PROGRESS)
  1677. AddvarIE(pc, IE_PROGRESS, prog->PROGRESS);
  1678. else
  1679. return;
  1680. if (prog->DISPLAY)
  1681. AddvarIE(pc, IE_DISPLAY, prog->DISPLAY);
  1682. if (prog->HLC)
  1683. AddvarIE(pc, IE_HLC, prog->HLC);
  1684. SendMsg(pc, -1);
  1685. }
  1686. }
  1687. static void
  1688. l3dss1_notify_req(layer3_proc_t *pc, int pr, void *arg)
  1689. {
  1690. NOTIFY_t *noti = arg;
  1691. if (noti) {
  1692. MsgStart(pc, MT_INFORMATION);
  1693. if (noti->BEARER)
  1694. AddvarIE(pc, IE_BEARER, noti->BEARER);
  1695. if (noti->NOTIFY)
  1696. AddvarIE(pc, IE_NOTIFY, noti->NOTIFY);
  1697. else
  1698. return;
  1699. if (noti->DISPLAY)
  1700. AddvarIE(pc, IE_DISPLAY, noti->DISPLAY);
  1701. if (noti->REDIR_DN)
  1702. AddvarIE(pc, IE_REDIR_DN, noti->REDIR_DN);
  1703. SendMsg(pc, -1);
  1704. }
  1705. }
  1706. static void
  1707. l3dss1_disconnect_req_out(layer3_proc_t *pc, int pr, void *arg)
  1708. {
  1709. DISCONNECT_t *disc = arg;
  1710. int cause;
  1711. if (pc->master) { /* child */
  1712. l3dss1_disconnect_req_out(pc->master, pr, arg);
  1713. return;
  1714. }
  1715. L3DelTimer(&pc->timer1);
  1716. if (disc) {
  1717. if (disc->CAUSE){
  1718. cause = disc->CAUSE[2] & 0x7f;
  1719. } else {
  1720. cause = CAUSE_NORMALUNSPECIFIED;
  1721. }
  1722. }
  1723. send_proc(pc, IMSG_RELEASE_CHILDS, &cause);
  1724. if (test_bit(FLG_L3P_TIMER312, &pc->Flags)) {
  1725. newl3state(pc, 22);
  1726. } else {
  1727. if_link(pc->l3->nst->manager, (ifunc_t)pc->l3->nst->l3_manager,
  1728. CC_RELEASE | CONFIRM, pc->ces |
  1729. (pc->callref << 16), 0, NULL, 0);
  1730. newl3state(pc, 0);
  1731. if (!pc->child)
  1732. send_proc(pc, IMSG_END_PROC_M, NULL);
  1733. }
  1734. }
  1735. static void
  1736. l3dss1_release_req(layer3_proc_t *pc, int pr, void *arg)
  1737. {
  1738. RELEASE_t *rel = arg;
  1739. StopAllL3Timer(pc);
  1740. if (rel) {
  1741. MsgStart(pc, MT_RELEASE);
  1742. if (rel->CAUSE)
  1743. AddvarIE(pc, IE_CAUSE, rel->CAUSE);
  1744. if (rel->FACILITY)
  1745. AddvarIE(pc, IE_FACILITY, rel->FACILITY);
  1746. if (rel->DISPLAY)
  1747. AddvarIE(pc, IE_DISPLAY, rel->DISPLAY);
  1748. if (rel->USER_USER)
  1749. AddvarIE(pc, IE_USER_USER, rel->USER_USER);
  1750. SendMsg(pc, 19);
  1751. } else {
  1752. newl3state(pc, 19);
  1753. l3dss1_message(pc, MT_RELEASE);
  1754. }
  1755. test_and_clear_bit(FLG_L3P_TIMER308_1, &pc->Flags);
  1756. L3AddTimer(&pc->timer1, T308, 0x308);
  1757. }
  1758. static void
  1759. l3dss1_release_cmpl_req(layer3_proc_t *pc, int pr, void *arg)
  1760. {
  1761. RELEASE_COMPLETE_t *rcmpl = arg;
  1762. StopAllL3Timer(pc);
  1763. if (rcmpl) {
  1764. MsgStart(pc, MT_RELEASE_COMPLETE);
  1765. if (rcmpl->CAUSE)
  1766. AddvarIE(pc, IE_CAUSE, rcmpl->CAUSE);
  1767. if (rcmpl->FACILITY)
  1768. AddvarIE(pc, IE_FACILITY, rcmpl->FACILITY);
  1769. if (rcmpl->DISPLAY)
  1770. AddvarIE(pc, IE_DISPLAY, rcmpl->DISPLAY);
  1771. if (rcmpl->USER_USER)
  1772. AddvarIE(pc, IE_USER_USER, rcmpl->USER_USER);
  1773. SendMsg(pc, 0);
  1774. } else {
  1775. newl3state(pc, 0);
  1776. l3dss1_message(pc, MT_RELEASE_COMPLETE);
  1777. }
  1778. send_proc(pc, IMSG_END_PROC_M, NULL);
  1779. }
  1780. static void
  1781. l3dss1_t302(layer3_proc_t *pc, int pr, void *arg)
  1782. {
  1783. {
  1784. int t = 0x302;
  1785. StopAllL3Timer(pc);
  1786. if_link(pc->l3->nst->manager, (ifunc_t)pc->l3->nst->l3_manager,
  1787. CC_TIMEOUT | INDICATION,pc->ces | (pc->callref << 16),
  1788. sizeof(int), &t, 0);
  1789. }
  1790. }
  1791. static void
  1792. l3dss1_t303(layer3_proc_t *pc, int pr, void *arg)
  1793. {
  1794. int l;
  1795. msg_t *msg;
  1796. RELEASE_COMPLETE_t *relc;
  1797. L3DelTimer(&pc->timer1);
  1798. if (test_bit(FLG_L3P_GOTRELCOMP, &pc->Flags)) {
  1799. StopAllL3Timer(pc);
  1800. msg = prep_l3data_msg(CC_RELEASE_COMPLETE | INDICATION,
  1801. pc->ces | (pc->callref << 16),
  1802. sizeof(RELEASE_COMPLETE_t), 3, NULL);
  1803. if (!msg)
  1804. return;
  1805. relc = (RELEASE_COMPLETE_t *)(msg->data + mISDNUSER_HEAD_SIZE);
  1806. newl3state(pc, 0);
  1807. relc->CAUSE = msg_put(msg, 3);
  1808. relc->CAUSE[0] = 2;
  1809. relc->CAUSE[1] = 0x80;
  1810. if (pc->cause)
  1811. relc->CAUSE[2] = pc->cause | 0x80;
  1812. else
  1813. relc->CAUSE[2] = CAUSE_NORMALUNSPECIFIED | 0x80;
  1814. if (mISDN_l3up(pc, msg))
  1815. free_msg(msg);
  1816. send_proc(pc, IMSG_END_PROC_M, NULL);
  1817. return;
  1818. }
  1819. if (!test_and_set_bit(FLG_L3P_TIMER303_1, &pc->Flags)) {
  1820. if (pc->obuf[3] == MT_SETUP) {
  1821. l = pc->op - &pc->obuf[0];
  1822. dhexprint(DBGM_L3DATA, "l3 oframe:", &pc->obuf[0], l);
  1823. if ((msg = l3_alloc_msg(l))) {
  1824. memcpy(msg_put(msg, l), &pc->obuf[0], l);
  1825. if (pc->l3->nst->feature & FEATURE_NET_PTP) {
  1826. dprint(DBGM_L3, pc->l3->nst->cardnr, "%s: proc(%p) sending SETUP to CES 0\n", __FUNCTION__, pc);
  1827. if (l3_msg(pc->l3, DL_DATA | REQUEST, 0, msg))
  1828. free_msg(msg);
  1829. } else {
  1830. dprint(DBGM_L3, pc->l3->nst->cardnr, "%s: proc(%p) sending SETUP to broadcast CES\n", __FUNCTION__, pc);
  1831. if (l3_msg(pc->l3, DL_UNITDATA | REQUEST, 127, msg))
  1832. free_msg(msg);
  1833. }
  1834. }
  1835. L3DelTimer(&pc->timer2);
  1836. dprint(DBGM_L3, pc->l3->nst->cardnr, "%s: pc=%p del timer2\n", __FUNCTION__, pc);
  1837. if (!(pc->l3->nst->feature & FEATURE_NET_PTP)) {
  1838. L3AddTimer(&pc->timer2, T312, 0x312);
  1839. test_and_set_bit(FLG_L3P_TIMER312,
  1840. &pc->Flags);
  1841. }
  1842. L3AddTimer(&pc->timer1, T303, 0x303);
  1843. return;
  1844. }
  1845. }
  1846. msg = prep_l3data_msg(CC_RELEASE_COMPLETE | INDICATION,
  1847. pc->ces | (pc->callref << 16),
  1848. sizeof(RELEASE_COMPLETE_t), 3, NULL);
  1849. if (!msg)
  1850. return;
  1851. relc = (RELEASE_COMPLETE_t *)(msg->data + mISDNUSER_HEAD_SIZE);
  1852. relc->CAUSE = msg_put(msg, 3);
  1853. relc->CAUSE[0] = 2;
  1854. relc->CAUSE[1] = 0x85;
  1855. relc->CAUSE[2] = CAUSE_NOUSER_RESPONDING | 0x80;
  1856. if (mISDN_l3up(pc, msg))
  1857. free_msg(msg);
  1858. newl3state(pc, 22);
  1859. }
  1860. static void
  1861. l3dss1_t305(layer3_proc_t *pc, int pr, void *arg)
  1862. {
  1863. #warning: mut we dat sendn? : int t = 0x305;
  1864. StopAllL3Timer(pc);
  1865. newl3state(pc, 19);
  1866. l3dss1_message(pc, MT_RELEASE);
  1867. test_and_clear_bit(FLG_L3P_TIMER308_1, &pc->Flags);
  1868. L3AddTimer(&pc->timer1, T308, 0x308);
  1869. }
  1870. static void
  1871. l3dss1_t308(layer3_proc_t *pc, int pr, void *arg)
  1872. {
  1873. if (!test_and_set_bit(FLG_L3P_TIMER308_1, &pc->Flags)) {
  1874. newl3state(pc, 19);
  1875. L3DelTimer(&pc->timer1);
  1876. l3dss1_message(pc, MT_RELEASE);
  1877. L3AddTimer(&pc->timer1, T308, 0x308);
  1878. } else {
  1879. int t = 0x308;
  1880. StopAllL3Timer(pc);
  1881. newl3state(pc, 0);
  1882. if_link(pc->l3->nst->manager, (ifunc_t)pc->l3->nst->l3_manager,
  1883. CC_TIMEOUT | INDICATION,pc->ces | (pc->callref << 16),
  1884. sizeof(int), &t, 0);
  1885. send_proc(pc, IMSG_END_PROC_M, NULL);
  1886. }
  1887. }
  1888. static void
  1889. l3dss1_t312(layer3_proc_t *pc, int pr, void *arg)
  1890. {
  1891. int t = 0x312;
  1892. test_and_clear_bit(FLG_L3P_TIMER312, &pc->Flags);
  1893. L3DelTimer(&pc->timer2);
  1894. dprint(DBGM_L3, pc->l3->nst->cardnr, "%s: pc=%p del timer2\n", __FUNCTION__, pc);
  1895. l3_debug(pc->l3, "%s: state %d", __FUNCTION__, pc->state);
  1896. if (pc->state == 22 || pc->state == 25 || pc->state == 9 || pc->state == 7) {
  1897. StopAllL3Timer(pc);
  1898. if (!pc->child) {
  1899. if_link(pc->l3->nst->manager, (ifunc_t)pc->l3->nst->l3_manager,
  1900. CC_TIMEOUT | INDICATION,pc->ces |
  1901. (pc->callref << 16), sizeof(int), &t, 0);
  1902. send_proc(pc, IMSG_END_PROC_M, NULL);
  1903. }
  1904. }
  1905. }
  1906. static void
  1907. l3dss1_holdack_req(layer3_proc_t *pc, int pr, void *arg)
  1908. {
  1909. HOLD_ACKNOWLEDGE_t *hack = arg;
  1910. if (pc->hold_state != HOLDAUX_HOLD_IND)
  1911. return;
  1912. pc->hold_state = HOLDAUX_HOLD;
  1913. if (hack) {
  1914. MsgStart(pc, MT_HOLD_ACKNOWLEDGE);
  1915. if (hack->DISPLAY)
  1916. AddvarIE(pc, IE_DISPLAY, hack->DISPLAY);
  1917. SendMsg(pc, -1);
  1918. } else {
  1919. l3dss1_message(pc, MT_HOLD_ACKNOWLEDGE);
  1920. }
  1921. }
  1922. static void
  1923. l3dss1_holdrej_req(layer3_proc_t *pc, int pr, void *arg)
  1924. {
  1925. HOLD_REJECT_t *hrej = arg;
  1926. if (pc->hold_state != HOLDAUX_HOLD_IND)
  1927. return;
  1928. pc->hold_state = HOLDAUX_IDLE;
  1929. MsgStart(pc, MT_HOLD_REJECT);
  1930. if (hrej) {
  1931. if (hrej->CAUSE)
  1932. AddvarIE(pc, IE_CAUSE, hrej->CAUSE);
  1933. else {
  1934. *pc->op++ = IE_CAUSE;
  1935. *pc->op++ = 2;
  1936. *pc->op++ = 0x80;
  1937. *pc->op++ = 0x80 | 0x47;
  1938. }
  1939. if (hrej->DISPLAY)
  1940. AddvarIE(pc, IE_DISPLAY, hrej->DISPLAY);
  1941. } else {
  1942. *pc->op++ = IE_CAUSE;
  1943. *pc->op++ = 2;
  1944. *pc->op++ = 0x80;
  1945. *pc->op++ = 0x80 | 0x47;
  1946. }
  1947. SendMsg(pc, -1);
  1948. }
  1949. static void
  1950. l3dss1_retrack_req(layer3_proc_t *pc, int pr, void *arg)
  1951. {
  1952. RETRIEVE_ACKNOWLEDGE_t *rack = arg;
  1953. if (pc->hold_state != HOLDAUX_RETR_IND)
  1954. return;
  1955. pc->hold_state = HOLDAUX_IDLE;
  1956. if (rack) {
  1957. MsgStart(pc, MT_RETRIEVE_ACKNOWLEDGE);
  1958. if (rack->CHANNEL_ID)
  1959. AddvarIE(pc, IE_CHANNEL_ID, rack->CHANNEL_ID);
  1960. if (rack->DISPLAY)
  1961. AddvarIE(pc, IE_DISPLAY, rack->DISPLAY);
  1962. SendMsg(pc, -1);
  1963. } else {
  1964. l3dss1_message(pc, MT_RETRIEVE_ACKNOWLEDGE);
  1965. }
  1966. }
  1967. static void
  1968. l3dss1_retrrej_req(layer3_proc_t *pc, int pr, void *arg)
  1969. {
  1970. RETRIEVE_REJECT_t *rrej = arg;
  1971. if (pc->hold_state != HOLDAUX_RETR_IND)
  1972. return;
  1973. pc->hold_state = HOLDAUX_HOLD;
  1974. MsgStart(pc, MT_RETRIEVE_REJECT);
  1975. if (rrej) {
  1976. if (rrej->CAUSE)
  1977. AddvarIE(pc, IE_CAUSE, rrej->CAUSE);
  1978. else {
  1979. *pc->op++ = IE_CAUSE;
  1980. *pc->op++ = 2;
  1981. *pc->op++ = 0x80;
  1982. *pc->op++ = 0x80 | 0x47;
  1983. }
  1984. if (rrej->DISPLAY)
  1985. AddvarIE(pc, IE_DISPLAY, rrej->DISPLAY);
  1986. } else {
  1987. *pc->op++ = IE_CAUSE;
  1988. *pc->op++ = 2;
  1989. *pc->op++ = 0x80;
  1990. *pc->op++ = 0x80 | 0x47;
  1991. }
  1992. SendMsg(pc, -1);
  1993. }
  1994. static void
  1995. l3dss1_suspack_req(layer3_proc_t *pc, int pr, void *arg)
  1996. {
  1997. SUSPEND_ACKNOWLEDGE_t *sack = arg;
  1998. StopAllL3Timer(pc);
  1999. if (sack) {
  2000. MsgStart(pc, MT_SUSPEND_ACKNOWLEDGE);
  2001. if (sack->FACILITY)
  2002. AddvarIE(pc, IE_FACILITY, sack->FACILITY);
  2003. if (sack->DISPLAY)
  2004. AddvarIE(pc, IE_DISPLAY, sack->DISPLAY);
  2005. SendMsg(pc, 0);
  2006. } else {
  2007. l3dss1_message(pc, MT_SUSPEND_ACKNOWLEDGE);
  2008. }
  2009. newl3state(pc, 0);
  2010. send_proc(pc, IMSG_END_PROC_M, NULL);
  2011. }
  2012. static void
  2013. l3dss1_susprej_req(layer3_proc_t *pc, int pr, void *arg)
  2014. {
  2015. SUSPEND_REJECT_t *srej = arg;
  2016. MsgStart(pc, MT_SUSPEND_REJECT);
  2017. if (srej) {
  2018. if (srej->CAUSE)
  2019. AddvarIE(pc, IE_CAUSE, srej->CAUSE);
  2020. else {
  2021. *pc->op++ = IE_CAUSE;
  2022. *pc->op++ = 2;
  2023. *pc->op++ = 0x80;
  2024. *pc->op++ = 0x80 | 0x47;
  2025. }
  2026. if (srej->DISPLAY)
  2027. AddvarIE(pc, IE_DISPLAY, srej->DISPLAY);
  2028. } else {
  2029. *pc->op++ = IE_CAUSE;
  2030. *pc->op++ = 2;
  2031. *pc->op++ = 0x80;
  2032. *pc->op++ = 0x80 | 0x47;
  2033. }
  2034. SendMsg(pc, -1);
  2035. newl3state(pc, 10);
  2036. }
  2037. static void
  2038. l3dss1_resack_req(layer3_proc_t *pc, int pr, void *arg)
  2039. {
  2040. RESUME_ACKNOWLEDGE_t *rack = arg;
  2041. StopAllL3Timer(pc);
  2042. if (rack) {
  2043. MsgStart(pc, MT_RESUME_ACKNOWLEDGE);
  2044. if (rack->CHANNEL_ID)
  2045. AddvarIE(pc, IE_CHANNEL_ID, rack->CHANNEL_ID);
  2046. if (rack->FACILITY)
  2047. AddvarIE(pc, IE_FACILITY, rack->FACILITY);
  2048. if (rack->DISPLAY)
  2049. AddvarIE(pc, IE_DISPLAY, rack->DISPLAY);
  2050. SendMsg(pc, 0);
  2051. } else {
  2052. l3dss1_message(pc, MT_RESUME_ACKNOWLEDGE);
  2053. }
  2054. newl3state(pc, 10);
  2055. }
  2056. static void
  2057. l3dss1_resrej_req(layer3_proc_t *pc, int pr, void *arg)
  2058. {
  2059. RESUME_REJECT_t *rrej = arg;
  2060. MsgStart(pc, MT_RESUME_REJECT);
  2061. if (rrej) {
  2062. if (rrej->CAUSE)
  2063. AddvarIE(pc, IE_CAUSE, rrej->CAUSE);
  2064. else {
  2065. *pc->op++ = IE_CAUSE;
  2066. *pc->op++ = 2;
  2067. *pc->op++ = 0x80;
  2068. *pc->op++ = 0x80 | 0x47;
  2069. }
  2070. if (rrej->DISPLAY)
  2071. AddvarIE(pc, IE_DISPLAY, rrej->DISPLAY);
  2072. } else {
  2073. *pc->op++ = IE_CAUSE;
  2074. *pc->op++ = 2;
  2075. *pc->op++ = 0x80;
  2076. *pc->op++ = 0x80 | 0x47;
  2077. }
  2078. SendMsg(pc, -1);
  2079. newl3state(pc, 0);
  2080. send_proc(pc, IMSG_END_PROC_M, NULL);
  2081. }
  2082. /* *INDENT-OFF* */
  2083. static struct stateentry downstatelist[] =
  2084. {
  2085. #if 0
  2086. {SBIT(0),
  2087. CC_RESUME | REQUEST, l3dss1_resume_req},
  2088. {SBIT(12),
  2089. CC_RELEASE | REQUEST, l3dss1_release_req},
  2090. {ALL_STATES,
  2091. CC_RESTART | REQUEST, l3dss1_restart},
  2092. {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
  2093. CC_CONNECT | REQUEST, l3dss1_connect_req},
  2094. {SBIT(10),
  2095. CC_SUSPEND | REQUEST, l3dss1_suspend_req},
  2096. #endif
  2097. {ALL_STATES,
  2098. CC_RELEASE_COMPLETE | REQUEST, l3dss1_release_cmpl_req},
  2099. {SBIT(0),
  2100. CC_SETUP | REQUEST, l3dss1_setup_req},
  2101. {SBIT(1),
  2102. CC_SETUP_ACKNOWLEDGE | REQUEST, l3dss1_setup_ack_req},
  2103. {SBIT(1) | SBIT(2),
  2104. CC_PROCEEDING | REQUEST, l3dss1_proceed_req},
  2105. {SBIT(2) | SBIT(3),
  2106. CC_ALERTING | REQUEST, l3dss1_alert_req},
  2107. {SBIT(2) | SBIT(3) | SBIT(4),
  2108. CC_CONNECT | REQUEST, l3dss1_connect_req},
  2109. {SBIT(8),
  2110. CC_CONNECT | RESPONSE, l3dss1_connect_res},
  2111. {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(10),
  2112. CC_DISCONNECT | REQUEST, l3dss1_disconnect_req},
  2113. { SBIT(2) | SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(25),
  2114. CC_DISCONNECT | REQUEST, l3dss1_disconnect_req_out},
  2115. { SBIT(2) | SBIT(11)
  2116. #warning bitte beachte folgendes:
  2117. /*
  2118. andreas:
  2119. es ist nur erlaubt, im state 11 einen release zu schicken!
  2120. dennoch verwende der stack den release scheinbar, um einen prozess
  2121. zu releasen, wie es z.b. in l3dss1_disconnect_req_out geschieht.
  2122. der process befindet sich zu diesem zeitpunk noch im state 7, 9 oder 25.
  2123. wenn man den (Layer 4) state auf 11 ändern würde, braucht mann die folgende
  2124. zeile nicht: (bitte nachdenken, ob dies korrekt ist)
  2125. karsten:
  2126. Nein glaube ich nicht. CC_RELEASE |= CC_RELEASE_CR muss aber mal ein paar Tests
  2127. machen
  2128. andreas:
  2129. solltest du was ändern, bitte vorher mit mit sprechen, da bei mir alles soweit fabelhaft läuft un ich layer 4 eventuell anpassen muss.
  2130. */
  2131. | SBIT(12) | SBIT(7) | SBIT(9) | SBIT(25)
  2132. ,CC_RELEASE | REQUEST, l3dss1_release_req},
  2133. /*
  2134. andreas:
  2135. wenn ein CC_DISCONNECT gesendet wird (state 7 = klingeling), dann bekommt man nur einen RELEASE_CR, aber keinen vorherigen RELEASE
  2136. karsten:
  2137. muss ich auch testen, keine Zeit
  2138. andreas:
  2139. solltest du was ändern, bitte vorher mit mit sprechen, da bei mir alles soweit fabelhaft läuft un ich layer 4 eventuell anpassen muss.
  2140. */
  2141. {ALL_STATES,
  2142. CC_FACILITY | REQUEST, l3dss1_facility_req},
  2143. {SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10),
  2144. CC_USER_INFORMATION | REQUEST, l3dss1_userinfo_req},
  2145. {SBIT(2) | SBIT(3) | SBIT(4) | SBIT(10) | SBIT(11) | SBIT(12) | SBIT(25),
  2146. CC_INFORMATION | REQUEST, l3dss1_information_req},
  2147. {SBIT(2) | SBIT(3) | SBIT(4),
  2148. CC_PROGRESS | REQUEST, l3dss1_progress_req},
  2149. {SBIT(10) | SBIT(15),
  2150. CC_NOTIFY | REQUEST, l3dss1_notify_req},
  2151. {SBIT(2),
  2152. CC_T302, l3dss1_t302},
  2153. {SBIT(12),
  2154. CC_T305, l3dss1_t305},
  2155. {SBIT(6),
  2156. CC_T303, l3dss1_t303},
  2157. {SBIT(19),
  2158. CC_T308, l3dss1_t308},
  2159. {ALL_STATES,
  2160. CC_T312, l3dss1_t312},
  2161. {SBIT(3) | SBIT(4) | SBIT(10) | SBIT(12),
  2162. CC_HOLD_ACKNOWLEDGE | REQUEST, l3dss1_holdack_req},
  2163. {SBIT(3) | SBIT(4) | SBIT(10) | SBIT(12),
  2164. CC_HOLD_REJECT | REQUEST, l3dss1_holdrej_req},
  2165. {SBIT(3) | SBIT(4) | SBIT(10) | SBIT(12),
  2166. CC_RETRIEVE_ACKNOWLEDGE | REQUEST, l3dss1_retrack_req},
  2167. {SBIT(3) | SBIT(4) | SBIT(10) | SBIT(12),
  2168. CC_RETRIEVE_REJECT | REQUEST, l3dss1_retrrej_req},
  2169. {SBIT(15),
  2170. CC_SUSPEND_ACKNOWLEDGE | REQUEST, l3dss1_suspack_req},
  2171. {SBIT(15),
  2172. CC_SUSPEND_REJECT | REQUEST, l3dss1_susprej_req},
  2173. {SBIT(17),
  2174. CC_RESUME_ACKNOWLEDGE | REQUEST, l3dss1_resack_req},
  2175. {SBIT(17),
  2176. CC_RESUME_REJECT | REQUEST, l3dss1_resrej_req},
  2177. };
  2178. #define DOWNSLLEN \
  2179. (sizeof(downstatelist) / sizeof(struct stateentry))
  2180. static int
  2181. imsg_intrelease(layer3_proc_t *master, layer3_proc_t *child)
  2182. {
  2183. int cause;
  2184. if ((!master) || (!child))
  2185. return(-EINVAL);
  2186. dprint(DBGM_L3, master->l3->nst->cardnr, "%s: m/c(%x/%x) state(%d/%d) m->c(%p)\n", __FUNCTION__,
  2187. master->ces, child->ces, master->state, child->state,
  2188. master->child);
  2189. switch (master->state) {
  2190. case 0:
  2191. if (!master->child) {
  2192. send_proc(master, IMSG_END_PROC, master);
  2193. }
  2194. break;
  2195. case 6:
  2196. case 10:
  2197. break;
  2198. case 19:
  2199. send_proc(master, IMSG_END_PROC, NULL);
  2200. break;
  2201. case 7:
  2202. case 9:
  2203. case 25:
  2204. if (master->child ||
  2205. test_bit(FLG_L3P_TIMER312, &master->Flags)) {
  2206. dprint(DBGM_L3, master->l3->nst->cardnr, "%s: JOLLY child=%p, flg=%d\n", __FUNCTION__, master->child, test_bit(FLG_L3P_TIMER312, &master->Flags));
  2207. } else {
  2208. send_proc(master, IMSG_END_PROC, NULL);
  2209. }
  2210. break;
  2211. case 8:
  2212. if (master->selces == child->ces) {
  2213. cause = CAUSE_NONSELECTED_USER;
  2214. send_proc(master, IMSG_RELEASE_CHILDS, &cause);
  2215. if (test_bit(FLG_L3P_TIMER312, &master->Flags)) {
  2216. newl3state(master, 22);
  2217. } else {
  2218. if (!master->child)
  2219. send_proc(master,
  2220. IMSG_END_PROC, NULL);
  2221. }
  2222. }
  2223. break;
  2224. case 22:
  2225. if (!master->child) {
  2226. send_proc(master, IMSG_END_PROC, NULL);
  2227. }
  2228. break;
  2229. }
  2230. return(0);
  2231. }
  2232. static int
  2233. send_proc(layer3_proc_t *proc, int op, void *arg)
  2234. {
  2235. int i;
  2236. layer3_proc_t *selp;
  2237. struct _l3_msg *l3m = arg;
  2238. struct _l3_msg l3msg;
  2239. if (proc->l3 && proc->l3->debug & L3_DEB_PROC)
  2240. l3_debug(proc->l3, "%s: proc(%x,%d) op(%d)", __FUNCTION__,
  2241. proc->ces, proc->callref, op);
  2242. switch(op) {
  2243. case IMSG_END_PROC:
  2244. case IMSG_END_PROC_M:
  2245. RemoveAllL3Timer(proc);
  2246. if (!proc->master && !arg) {
  2247. if_link(proc->l3->nst->manager,
  2248. (ifunc_t)proc->l3->nst->l3_manager,
  2249. CC_RELEASE_CR | INDICATION,
  2250. proc->ces | (proc->callref << 16),
  2251. sizeof(int), &proc->err, 0);
  2252. }
  2253. while (proc->child)
  2254. send_proc(proc->child, IMSG_END_PROC, NULL);
  2255. if (proc->next)
  2256. proc->next->prev = proc->prev;
  2257. if (proc->prev)
  2258. proc->prev->next = proc->next;
  2259. if (proc->l3 && (proc == proc->l3->proc) )
  2260. proc->l3->proc = proc->next;
  2261. if (proc->master) {
  2262. if (proc->master->child == proc)
  2263. proc->master->child = proc->next;
  2264. if (op == IMSG_END_PROC_M)
  2265. imsg_intrelease(proc->master, proc);
  2266. }
  2267. free(proc);
  2268. break;
  2269. case IMSG_L2_DATA:
  2270. for (i = 0; i < DATASLLEN; i++)
  2271. if ((l3m->mt == datastatelist[i].primitive) &&
  2272. ((1 << proc->state) & datastatelist[i].state))
  2273. break;
  2274. if (i == DATASLLEN) {
  2275. if (proc->l3->debug & L3_DEB_STATE) {
  2276. l3_debug(proc->l3, "dss1 state %d mt %#x unhandled",
  2277. proc->state, l3m->mt);
  2278. }
  2279. if ((MT_RELEASE_COMPLETE != l3m->mt) && (MT_RELEASE != l3m->mt)) {
  2280. // l3dss1_status_send(proc, CAUSE_NOTCOMPAT_STATE);
  2281. }
  2282. } else {
  2283. if (proc->l3->debug & L3_DEB_STATE) {
  2284. l3_debug(proc->l3, "dss1 state %d mt %x",
  2285. proc->state, l3m->mt);
  2286. }
  2287. datastatelist[i].rout(proc, l3m->mt, l3m->msg);
  2288. }
  2289. break;
  2290. case IMSG_MASTER_L2_DATA:
  2291. for (i = 0; i < MDATASLLEN; i++)
  2292. if ((l3m->mt == mdatastatelist[i].primitive) &&
  2293. ((1 << proc->state) & mdatastatelist[i].state))
  2294. break;
  2295. if (i == MDATASLLEN) {
  2296. if (proc->l3->debug & L3_DEB_STATE) {
  2297. l3_debug(proc->l3, "dss1 state %d mt %#x unhandled",
  2298. proc->state, l3m->mt);
  2299. }
  2300. if ((MT_RELEASE_COMPLETE != l3m->mt) && (MT_RELEASE != l3m->mt)) {
  2301. // l3dss1_status_send(proc, CAUSE_NOTCOMPAT_STATE);
  2302. }
  2303. } else {
  2304. if (proc->l3->debug & L3_DEB_STATE) {
  2305. l3_debug(proc->l3, "dss1 state %d mt %x",
  2306. proc->state, l3m->mt);
  2307. }
  2308. mdatastatelist[i].rout(proc, l3m->mt, l3m->msg);
  2309. }
  2310. break;
  2311. case IMSG_TIMER_EXPIRED:
  2312. i = *((int *)arg);
  2313. l3_debug(proc->l3, "%s: timer %x", __FUNCTION__, i);
  2314. l3m = &l3msg;
  2315. l3m->mt = CC_TIMER | (i<<8);
  2316. l3m->msg = NULL;
  2317. case IMSG_L4_DATA:
  2318. for (i = 0; i < DOWNSLLEN; i++)
  2319. if ((l3m->mt == downstatelist[i].primitive) &&
  2320. ((1 << proc->state) & downstatelist[i].state))
  2321. break;
  2322. if (i == DOWNSLLEN) {
  2323. if (proc->l3->debug & L3_DEB_STATE) {
  2324. l3_debug(proc->l3, "dss1 state %d L4 %#x unhandled",
  2325. proc->state, l3m->mt);
  2326. }
  2327. } else {
  2328. if (proc->l3->debug & L3_DEB_STATE) {
  2329. l3_debug(proc->l3, "dss1 state %d L4 %x",
  2330. proc->state, l3m->mt);
  2331. }
  2332. if (l3m->msg)
  2333. downstatelist[i].rout(proc, l3m->mt,
  2334. l3m->msg->data);
  2335. else
  2336. downstatelist[i].rout(proc, l3m->mt,
  2337. NULL);
  2338. }
  2339. break;
  2340. case IMSG_CONNECT_IND:
  2341. selp = proc;
  2342. proc = proc->master;
  2343. if (!proc)
  2344. return(-EINVAL);
  2345. proc->selces = selp->ces;
  2346. newl3state(proc, 8);
  2347. return(mISDN_l3up(proc, arg));
  2348. case IMSG_SEL_PROC:
  2349. selp = find_proc(proc->child, proc->selces,
  2350. proc->callref);
  2351. i = proc->selces | (proc->callref << 16);
  2352. if_link(proc->l3->nst->manager,
  2353. (ifunc_t)proc->l3->nst->l3_manager,
  2354. CC_NEW_CR | INDICATION, proc->ces |
  2355. (proc->callref << 16), sizeof(int), &i, 0);
  2356. proc->ces = proc->selces;
  2357. send_proc(selp, IMSG_END_PROC, NULL);
  2358. break;
  2359. case IMSG_RELEASE_CHILDS:
  2360. {
  2361. RELEASE_t *rel;
  2362. char cause[3];
  2363. cause[0] = 2;
  2364. cause[1] = CAUSE_LOC_PNET_LOCUSER | 0x80;
  2365. cause[2] = *((int *)arg) | 0x80;
  2366. l3msg.mt = CC_RELEASE | REQUEST;
  2367. l3msg.msg = alloc_msg(sizeof(RELEASE_t));
  2368. if (!l3msg.msg)
  2369. return(-ENOMEM);
  2370. rel = (RELEASE_t *)msg_put(l3msg.msg,
  2371. sizeof(RELEASE_t));
  2372. memset(rel, 0, sizeof(RELEASE_t));
  2373. rel->CAUSE = cause;
  2374. selp = proc->child;
  2375. while(selp) {
  2376. layer3_proc_t *next = selp->next;
  2377. send_proc(selp, IMSG_L4_DATA, &l3msg);
  2378. selp = next;
  2379. }
  2380. free_msg(l3msg.msg);
  2381. }
  2382. break;
  2383. }
  2384. return(0);
  2385. }
  2386. static int
  2387. dl_data_mux(layer3_t *l3, mISDNuser_head_t *hh, msg_t *msg)
  2388. {
  2389. layer3_proc_t *proc;
  2390. int ret = -EINVAL;
  2391. int cr;
  2392. struct _l3_msg l3m;
  2393. if (!l3)
  2394. return(ret);
  2395. dprint(DBGM_L3, l3->nst->cardnr, "%s: len(%d)\n", __FUNCTION__, msg->len);
  2396. dhexprint(DBGM_L3DATA, "l3 iframe:", msg->data, msg->len);
  2397. if (msg->len < 3) {
  2398. l3_debug(l3, "dss1 frame too short(%d)", msg->len);
  2399. free_msg(msg);
  2400. return(0);
  2401. }
  2402. if (msg->data[0] != PROTO_DIS_EURO) {
  2403. if (l3->debug & L3_DEB_PROTERR) {
  2404. l3_debug(l3, "dss1%sunexpected discriminator %x message len %d",
  2405. (hh->prim == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
  2406. msg->data[0], msg->len);
  2407. }
  2408. free_msg(msg);
  2409. return(0);
  2410. }
  2411. dprint(DBGM_L3, l3->nst->cardnr, "%s: dis(%x)\n", __FUNCTION__, msg->data[0]);
  2412. cr = getcallref(msg->data);
  2413. dprint(DBGM_L3, l3->nst->cardnr, "%s: cr(%x)\n", __FUNCTION__, cr);
  2414. if (msg->len < ((msg->data[1] & 0x0f) + 3)) {
  2415. l3_debug(l3, "dss1 frame too short(%d)", msg->len);
  2416. free_msg(msg);
  2417. return(0);
  2418. }
  2419. l3m.msg = msg;
  2420. l3m.mt = msg->data[msg->data[1] + 2];
  2421. if (cr == -2) { /* wrong Callref */
  2422. if (l3->debug & L3_DEB_WARN)
  2423. l3_debug(l3, "dss1 wrong Callref");
  2424. free_msg(msg);
  2425. return(0);
  2426. } else if (cr == -1) { /* Dummy Callref */
  2427. if (l3m.mt == MT_FACILITY) {
  2428. layer3_proc_t dummy;
  2429. memset( &dummy, 0, sizeof(layer3_proc_t));
  2430. dummy.l3 = l3;
  2431. dummy.ces = 0;
  2432. dummy.callref = -1;
  2433. l3dss1_facility(&dummy, hh->prim, msg);
  2434. }
  2435. else if (l3->debug & L3_DEB_WARN)
  2436. l3_debug(l3, "dss1 dummy Callref (no facility msg)");
  2437. free_msg(msg);
  2438. return(0);
  2439. } else if ((((msg->data[1] & 0x0f) == 1) && (0==(cr & 0x7f))) ||
  2440. (((msg->data[1] & 0x0f) == 2) && (0==(cr & 0x7fff)))) {
  2441. /* Global CallRef */
  2442. if (l3->debug & L3_DEB_STATE)
  2443. l3_debug(l3, "dss1 Global CallRef");
  2444. // global_handler(l3, l3m.mt, msg);
  2445. free_msg(msg);
  2446. return(0);
  2447. }
  2448. dprint(DBGM_L3, l3->nst->cardnr, "%s: mt(%x)\n", __FUNCTION__, l3m.mt);
  2449. proc = find_proc(l3->proc, hh->dinfo, cr);
  2450. dprint(DBGM_L3, l3->nst->cardnr, "%s: proc(%p)\n", __FUNCTION__, proc);
  2451. if (!proc) {
  2452. if (l3m.mt == MT_SETUP || l3m.mt == MT_RESUME) {
  2453. /* Setup/Resume creates a new transaction process */
  2454. if (msg->data[2] & 0x80) {
  2455. /* Setup/Resume with wrong CREF flag */
  2456. if (l3->debug & L3_DEB_STATE)
  2457. l3_debug(l3, "dss1 wrong CRef flag");
  2458. free_msg(msg);
  2459. return(0);
  2460. }
  2461. dprint(DBGM_L3, l3->nst->cardnr, "%s: %s\n", __FUNCTION__, (l3m.mt==MT_SETUP)?"MT_SETUP":"MT_RESUME");
  2462. if (!(proc = create_proc(l3, hh->dinfo, cr, NULL))) {
  2463. /* May be to answer with RELEASE_COMPLETE and
  2464. * CAUSE 0x2f "Resource unavailable", but this
  2465. * need a new_l3_process too ... arghh
  2466. */
  2467. free_msg(msg);
  2468. return(0);
  2469. }
  2470. dprint(DBGM_L3, l3->nst->cardnr, "%s: proc(%p)\n", __FUNCTION__, proc);
  2471. APPEND_TO_LIST(proc, l3->proc);
  2472. } else {
  2473. dprint(DBGM_L3, l3->nst->cardnr, "%s: mt(%x) do not create proc\n", __FUNCTION__,
  2474. l3m.mt);
  2475. // TODO: it happens that a response to an outgoing setup is received after connect of another terminal. in this case we must release.
  2476. free_msg(msg);
  2477. return(0);
  2478. }
  2479. }
  2480. if ((proc->ces & 0xffffff00) == 0xff00) {
  2481. dprint(DBGM_L3, l3->nst->cardnr, "%s: master state %d found\n", __FUNCTION__,
  2482. proc->state);
  2483. msg_push(msg, mISDNUSER_HEAD_SIZE);
  2484. send_proc(proc, IMSG_MASTER_L2_DATA, &l3m);
  2485. } else
  2486. send_proc(proc, IMSG_L2_DATA, &l3m);
  2487. free_msg(msg);
  2488. return(0);
  2489. }
  2490. int
  2491. l3_muxer(net_stack_t *nst, msg_t *msg)
  2492. {
  2493. mISDNuser_head_t *hh;
  2494. int ret = -EINVAL;
  2495. hh = (mISDNuser_head_t *)msg->data;
  2496. dprint(DBGM_L3, nst->cardnr, "%s: msg len(%d)\n", __FUNCTION__, msg->len);
  2497. dprint(DBGM_L3, nst->cardnr, "%s: pr(%x) di(%x)\n", __FUNCTION__,
  2498. hh->prim, hh->dinfo);
  2499. msg_pull(msg, mISDNUSER_HEAD_SIZE);
  2500. if (hh->prim == (DL_DATA | INDICATION)) {
  2501. ret = dl_data_mux(nst->layer3, hh, msg);
  2502. } else {
  2503. ret = l3_msg(nst->layer3, hh->prim, hh->dinfo, msg);
  2504. }
  2505. if (ret)
  2506. free_msg(msg);
  2507. ret = 0;
  2508. return(ret);
  2509. }
  2510. static int
  2511. manager_l3(net_stack_t *nst, msg_t *msg)
  2512. {
  2513. mISDNuser_head_t *hh;
  2514. layer3_proc_t *proc;
  2515. struct _l3_msg l3m;
  2516. hh = (mISDNuser_head_t *)msg->data;
  2517. dprint(DBGM_L3, nst->cardnr, "%s: msg len(%d)\n", __FUNCTION__, msg->len);
  2518. dprint(DBGM_L3, nst->cardnr, "%s: pr(%x) di(%x)\n", __FUNCTION__,
  2519. hh->prim, hh->dinfo);
  2520. msg_pull(msg, mISDNUSER_HEAD_SIZE);
  2521. proc = find_proc(nst->layer3->proc, hh->dinfo & 0xffff,
  2522. (hh->dinfo>>16)& 0xffff);
  2523. if (!proc) {
  2524. switch (hh->prim) {
  2525. case CC_SETUP | REQUEST:
  2526. {
  2527. int l4id;
  2528. nst->layer3->next_cr++;
  2529. if (nst->feature & FEATURE_NET_CRLEN2) {
  2530. if (nst->layer3->next_cr>32766)
  2531. nst->layer3->next_cr = 1;
  2532. } else {
  2533. if (nst->layer3->next_cr>126)
  2534. nst->layer3->next_cr = 1;
  2535. }
  2536. proc = create_proc(nst->layer3, hh->dinfo & 0xffff,
  2537. nst->layer3->next_cr | 0x8000, NULL);
  2538. if (!proc) {
  2539. dprint(DBGM_L3, nst->cardnr, "%s: pr(%x) failed to create proc.\n",
  2540. __FUNCTION__, hh->prim);
  2541. free_msg(msg);
  2542. return(0);
  2543. }
  2544. dprint(DBGM_L3, nst->cardnr, "%s: proc(%p)\n", __FUNCTION__, proc);
  2545. #warning testing
  2546. #if 0
  2547. printf("check for tei 0 active\n");
  2548. l2 = nst->layer2;
  2549. while(l2) {
  2550. if (l2->tei == 0 && l2->sapi == 0)
  2551. break;
  2552. l2 = l2->next;
  2553. }
  2554. if (l2) if (l2->state == ST_L2_4) {
  2555. p3i = create_proc(proc->l3, 0, proc->callref, proc);
  2556. if (!p3i) {
  2557. l3_debug(proc->l3, "cannot create child\n");
  2558. return(NULL);
  2559. }
  2560. proc = p3i;
  2561. dprint(DBGM_L3, nst->cardnr, "%s: TEI 0 is active, so we created proc(%p)\n", __FUNCTION__, proc);
  2562. }
  2563. #endif
  2564. APPEND_TO_LIST(proc, nst->layer3->proc);
  2565. l4id = proc->ces | (proc->callref << 16);
  2566. if_link(nst->manager, (ifunc_t)nst->l3_manager, CC_SETUP | CONFIRM, hh->dinfo, sizeof(int), &l4id, 0);
  2567. }
  2568. break;
  2569. case DL_ESTABLISH | REQUEST:
  2570. if (nst->feature & FEATURE_NET_PTP) {
  2571. l3down(nst->layer3, DL_ESTABLISH | REQUEST, 0, NULL);
  2572. free_msg(msg);
  2573. return 0;
  2574. }
  2575. break;
  2576. default:
  2577. break;
  2578. }
  2579. }
  2580. if (!proc) {
  2581. dprint(DBGM_L3, nst->cardnr, "%s: pr(%x) no proc id %x found\n", __FUNCTION__,
  2582. hh->prim, hh->dinfo);
  2583. free_msg(msg);
  2584. return(0);
  2585. }
  2586. l3m.mt = hh->prim;
  2587. if (msg->len)
  2588. l3m.msg = msg;
  2589. else {
  2590. dprint(DBGM_L3, nst->cardnr, "%s: pr(%x) id(%x) zero param\n", __FUNCTION__,
  2591. hh->prim, hh->dinfo);
  2592. l3m.msg = NULL;
  2593. }
  2594. send_proc(proc, IMSG_L4_DATA, &l3m);
  2595. free_msg(msg);
  2596. return(0);
  2597. }
  2598. static void
  2599. release_l3(layer3_t *l3) {
  2600. dprint(DBGM_L3, l3->nst->cardnr, "%s(%p)\n", __FUNCTION__, l3);
  2601. while(l3->proc) {
  2602. dprint(DBGM_L3, l3->nst->cardnr, "%s: rel_proc ces(%x)\n", __FUNCTION__,
  2603. l3->proc->ces);
  2604. send_proc(l3->proc, IMSG_END_PROC, NULL);
  2605. }
  2606. msg_queue_purge(&l3->squeue0);
  2607. REMOVE_FROM_LISTBASE(l3, l3->nst->layer3);
  2608. free(l3);
  2609. }
  2610. static int
  2611. mISDN_l3up(layer3_proc_t *l3p, msg_t *msg)
  2612. {
  2613. int err = -EINVAL;
  2614. if (!l3p || !l3p->l3 || !l3p->l3->nst)
  2615. return(-EINVAL);
  2616. if (l3p->l3->nst->l3_manager)
  2617. err = l3p->l3->nst->l3_manager(l3p->l3->nst->manager, msg);
  2618. if (err)
  2619. dprint(DBGM_L3, l3p->l3->nst->cardnr, "%s: error %d\n", __FUNCTION__, err);
  2620. return(err);
  2621. }
  2622. static int
  2623. l3down(layer3_t *l3, u_int prim, int dinfo, msg_t *msg) {
  2624. int err = -EINVAL;
  2625. if (!msg)
  2626. err = if_link(l3->nst, l3->nst->l3_l2, prim, dinfo, 0, NULL, 0);
  2627. else
  2628. err = if_addhead(l3->nst, l3->nst->l3_l2, prim, dinfo, msg);
  2629. return(err);
  2630. }
  2631. static void
  2632. send_squeue(layer3_t *l3, msg_queue_t *squeue)
  2633. {
  2634. msg_t *msg;
  2635. while((msg = msg_dequeue(&l3->squeue0))) {
  2636. if (l3->nst->l3_l2(l3->nst, msg))
  2637. free_msg(msg);
  2638. }
  2639. }
  2640. #warning testing
  2641. static int
  2642. remove_proc(layer3_proc_t **procp, int ces)
  2643. {
  2644. int found = 1;
  2645. int any = 0;
  2646. layer3_proc_t *proc;
  2647. if (ces > 126)
  2648. return(0);
  2649. while(found) {
  2650. found = 0;
  2651. proc = *procp;
  2652. while(proc) {
  2653. dprint(DBGM_L3, proc->l3->nst->cardnr, "%s: comparing %s proc(%x) ces(%x)\n", __FUNCTION__,
  2654. (proc->master)?"child":"master", proc, proc->ces);
  2655. if (proc->ces == ces) {
  2656. dprint(DBGM_L3, proc->l3->nst->cardnr, "%s: found proc(%x)\n", __FUNCTION__,
  2657. proc);
  2658. if (proc->master)
  2659. send_proc(proc, IMSG_END_PROC_M, NULL);
  2660. else
  2661. send_proc(proc, IMSG_END_PROC, NULL);
  2662. any = 1;
  2663. found = 1;
  2664. break;
  2665. }
  2666. if (proc->child) {
  2667. if (remove_proc(&proc->child, ces)) {
  2668. any = 1;
  2669. found = 1;
  2670. break;
  2671. }
  2672. }
  2673. proc = proc->next;
  2674. }
  2675. }
  2676. return(any);
  2677. }
  2678. #warning l2_state makes no sense in multipoint environment. shouldnt we use something like l2_state[ces] ?
  2679. static int
  2680. l3_msg(layer3_t *l3, u_int pr, int dinfo, void *arg)
  2681. {
  2682. msg_t *msg = arg, *lmsg = NULL;
  2683. #warning testing
  2684. int ces = dinfo & 0xffff;
  2685. dprint(DBGM_L3, l3->nst->cardnr, "%s: pr(%x) di(%x) arg(%p)\n", __FUNCTION__,
  2686. pr, dinfo, arg);
  2687. if (l3->nst->feature & FEATURE_NET_PTP) dinfo=0;
  2688. switch (pr) {
  2689. case (DL_UNITDATA | REQUEST):
  2690. return(l3down(l3, pr, dinfo, arg));
  2691. case (DL_DATA | REQUEST):
  2692. if (l3->l2_state0 == ST_L3_LC_ESTAB || ces > 0) {
  2693. return(l3down(l3, pr, dinfo, arg));
  2694. } else {
  2695. if (ces == 0) {
  2696. mISDN_addhead(pr, dinfo, msg);
  2697. msg_queue_tail(&l3->squeue0, msg);
  2698. l3->l2_state0 = ST_L3_LC_ESTAB_WAIT;
  2699. l3down(l3, DL_ESTABLISH | REQUEST, dinfo, NULL);
  2700. return(0);
  2701. }
  2702. }
  2703. break;
  2704. case (DL_DATA | CONFIRM):
  2705. break;
  2706. case (DL_ESTABLISH | REQUEST):
  2707. if (ces == 0) {
  2708. if (l3->l2_state0 != ST_L3_LC_ESTAB) {
  2709. l3down(l3, pr, dinfo, NULL);
  2710. l3->l2_state0 = ST_L3_LC_ESTAB_WAIT;
  2711. }
  2712. }
  2713. break;
  2714. case (DL_ESTABLISH | CONFIRM):
  2715. if (ces == 0) {
  2716. if (l3->l2_state0 != ST_L3_LC_REL_WAIT) {
  2717. l3->l2_state0 = ST_L3_LC_ESTAB;
  2718. send_squeue(l3, &l3->squeue0);
  2719. }
  2720. }
  2721. if (!l3->nst->l3_manager)
  2722. break;
  2723. if (!(lmsg = create_link_msg(pr, dinfo, 0, NULL, 0)))
  2724. break;
  2725. if (l3->nst->l3_manager(l3->nst->manager, lmsg))
  2726. free_msg(lmsg);
  2727. break;
  2728. case (DL_ESTABLISH | INDICATION):
  2729. if (ces == 0) {
  2730. if (l3->l2_state0 == ST_L3_LC_REL) {
  2731. l3->l2_state0 = ST_L3_LC_ESTAB;
  2732. send_squeue(l3, &l3->squeue0);
  2733. }
  2734. }
  2735. if (!l3->nst->l3_manager)
  2736. break;
  2737. if (!(lmsg = create_link_msg(pr, dinfo, 0, NULL, 0)))
  2738. break;
  2739. if (l3->nst->l3_manager(l3->nst->manager, lmsg))
  2740. free_msg(lmsg);
  2741. break;
  2742. case (DL_RELEASE | INDICATION):
  2743. #warning du musst alle processe releasen CC_RELEASE!!! dies geschieht z.b. wenn man das telefon vom s0-bus abnimmt und der layer-2 dadurch zusammen bricht.
  2744. #warning geschieht dies auch im TE-mode?
  2745. #warning TODO DL_RELEASE | INDICATION handling; inclusiv special state 10 (T309)
  2746. if (ces == 0) {
  2747. if (l3->l2_state0 == ST_L3_LC_ESTAB) {
  2748. l3->l2_state0 = ST_L3_LC_REL;
  2749. }
  2750. }
  2751. if (!l3->nst->l3_manager)
  2752. break;
  2753. if (!(lmsg = create_link_msg(pr, dinfo, 0, NULL, 0)))
  2754. break;
  2755. if (l3->nst->l3_manager(l3->nst->manager, lmsg))
  2756. free_msg(lmsg);
  2757. remove_proc(&l3->proc, dinfo);
  2758. break;
  2759. case (DL_RELEASE | CONFIRM):
  2760. if (ces == 0) {
  2761. if (l3->l2_state0 == ST_L3_LC_REL_WAIT) {
  2762. l3->l2_state0 = ST_L3_LC_REL;
  2763. }
  2764. }
  2765. if (!l3->nst->l3_manager)
  2766. break;
  2767. if (!(lmsg = create_link_msg(pr, dinfo, 0, NULL, 0)))
  2768. break;
  2769. if (l3->nst->l3_manager(l3->nst->manager, lmsg))
  2770. free_msg(lmsg);
  2771. remove_proc(&l3->proc, dinfo);
  2772. break;
  2773. case (DL_RELEASE | REQUEST):
  2774. if (ces == 0) {
  2775. if (l3->l2_state0 == ST_L3_LC_ESTAB) {
  2776. l3down(l3, pr, dinfo, NULL);
  2777. l3->l2_state0 = ST_L3_LC_REL_WAIT;
  2778. }
  2779. }
  2780. break;
  2781. }
  2782. if (msg)
  2783. free_msg(msg);
  2784. return(0);
  2785. }
  2786. int Isdnl3Init(net_stack_t *nst)
  2787. {
  2788. layer3_t *l3;
  2789. l3 = malloc(sizeof(layer3_t));
  2790. if (!l3)
  2791. return(-ENOMEM);
  2792. memset(l3, 0, sizeof(layer3_t));
  2793. l3->nst = nst;
  2794. nst->l2_l3 = l3_muxer;
  2795. nst->manager_l3 = manager_l3;
  2796. l3->debug = 0xff;
  2797. #warning testing
  2798. msg_queue_init(&l3->squeue0);
  2799. l3->l2_state0 = ST_L3_LC_REL;
  2800. APPEND_TO_LIST(l3, nst->layer3);
  2801. return(0);
  2802. }
  2803. void cleanup_Isdnl3(net_stack_t *nst)
  2804. {
  2805. if (nst->layer3) {
  2806. dprint(DBGM_L3, nst->cardnr, "%s: l3 list not empty\n", __FUNCTION__);
  2807. while(nst->layer3)
  2808. release_l3(nst->layer3);
  2809. }
  2810. }