PageRenderTime 131ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/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

Large files files are truncated, but you can click here to view the full file

  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_L

Large files files are truncated, but you can click here to view the full file