1 /* $Id: l3ni1.c,v 2.8.2.3 2004/01/13 14:31:25 keil Exp $
3 * NI1 D-channel protocol
5 * Author Matt Henderson & Guy Ellis
6 * Copyright by Traverse Technologies Pty Ltd, www.travers.com.au
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
11 * 2000.6.6 Initial implementation of routines for US NI1
12 * Layer 3 protocol based on the EURO/DSS1 D-channel protocol
13 * driver written by Karsten Keil et al.
14 * NI-1 Hall of Fame - Thanks to....
15 * Ragnar Paulson - for some handy code fragments
16 * Will Scales - beta tester extraordinaire
17 * Brett Whittacre - beta tester and remote devel system in Vegas
24 #include <linux/ctype.h>
25 #include <linux/slab.h>
27 extern char *HiSax_getrev(const char *revision);
28 static const char *ni1_revision = "$Revision: 2.8.2.3 $";
30 #define EXT_BEARER_CAPS 1
32 #define MsgHead(ptr, cref, mty) \
43 /**********************************************/
44 /* get a new invoke id for remote operations. */
45 /* Only a return value != 0 is valid */
46 /**********************************************/
47 static unsigned char new_invoke_id(struct PStack *p)
52 i = 32; /* maximum search depth */
54 retval = p->prot.ni1.last_invoke_id + 1; /* try new id */
55 while ((i) && (p->prot.ni1.invoke_used[retval >> 3] == 0xFF)) {
56 p->prot.ni1.last_invoke_id = (retval & 0xF8) + 8;
60 while (p->prot.ni1.invoke_used[retval >> 3] & (1 << (retval & 7)))
64 p->prot.ni1.last_invoke_id = retval;
65 p->prot.ni1.invoke_used[retval >> 3] |= (1 << (retval & 7));
69 /*************************/
70 /* free a used invoke id */
71 /*************************/
72 static void free_invoke_id(struct PStack *p, unsigned char id)
75 if (!id) return; /* 0 = invalid value */
77 p->prot.ni1.invoke_used[id >> 3] &= ~(1 << (id & 7));
78 } /* free_invoke_id */
81 /**********************************************************/
82 /* create a new l3 process and fill in ni1 specific data */
83 /**********************************************************/
84 static struct l3_process
85 *ni1_new_l3_process(struct PStack *st, int cr)
86 { struct l3_process *proc;
88 if (!(proc = new_l3_process(st, cr)))
91 proc->prot.ni1.invoke_id = 0;
92 proc->prot.ni1.remote_operation = 0;
93 proc->prot.ni1.uus1_data[0] = '\0';
96 } /* ni1_new_l3_process */
98 /************************************************/
99 /* free a l3 process and all ni1 specific data */
100 /************************************************/
102 ni1_release_l3_process(struct l3_process *p)
104 free_invoke_id(p->st, p->prot.ni1.invoke_id);
105 release_l3_process(p);
106 } /* ni1_release_l3_process */
108 /********************************************************/
109 /* search a process with invoke id id and dummy callref */
110 /********************************************************/
111 static struct l3_process *
112 l3ni1_search_dummy_proc(struct PStack *st, int id)
113 { struct l3_process *pc = st->l3.proc; /* start of processes */
115 if (!id) return (NULL);
118 { if ((pc->callref == -1) && (pc->prot.ni1.invoke_id == id))
123 } /* l3ni1_search_dummy_proc */
125 /*******************************************************************/
126 /* called when a facility message with a dummy callref is received */
127 /* and a return result is delivered. id specifies the invoke id. */
128 /*******************************************************************/
130 l3ni1_dummy_return_result(struct PStack *st, int id, u_char *p, u_char nlen)
132 struct IsdnCardState *cs;
133 struct l3_process *pc = NULL;
135 if ((pc = l3ni1_search_dummy_proc(st, id)))
136 { L3DelTimer(&pc->timer); /* remove timer */
138 cs = pc->st->l1.hardware;
139 ic.driver = cs->myid;
140 ic.command = ISDN_STAT_PROT;
141 ic.arg = NI1_STAT_INVOKE_RES;
142 ic.parm.ni1_io.hl_id = pc->prot.ni1.invoke_id;
143 ic.parm.ni1_io.ll_id = pc->prot.ni1.ll_id;
144 ic.parm.ni1_io.proc = pc->prot.ni1.proc;
145 ic.parm.ni1_io.timeout = 0;
146 ic.parm.ni1_io.datalen = nlen;
147 ic.parm.ni1_io.data = p;
148 free_invoke_id(pc->st, pc->prot.ni1.invoke_id);
149 pc->prot.ni1.invoke_id = 0; /* reset id */
151 cs->iif.statcallb(&ic);
152 ni1_release_l3_process(pc);
155 l3_debug(st, "dummy return result id=0x%x result len=%d", id, nlen);
156 } /* l3ni1_dummy_return_result */
158 /*******************************************************************/
159 /* called when a facility message with a dummy callref is received */
160 /* and a return error is delivered. id specifies the invoke id. */
161 /*******************************************************************/
163 l3ni1_dummy_error_return(struct PStack *st, int id, ulong error)
165 struct IsdnCardState *cs;
166 struct l3_process *pc = NULL;
168 if ((pc = l3ni1_search_dummy_proc(st, id)))
169 { L3DelTimer(&pc->timer); /* remove timer */
171 cs = pc->st->l1.hardware;
172 ic.driver = cs->myid;
173 ic.command = ISDN_STAT_PROT;
174 ic.arg = NI1_STAT_INVOKE_ERR;
175 ic.parm.ni1_io.hl_id = pc->prot.ni1.invoke_id;
176 ic.parm.ni1_io.ll_id = pc->prot.ni1.ll_id;
177 ic.parm.ni1_io.proc = pc->prot.ni1.proc;
178 ic.parm.ni1_io.timeout = error;
179 ic.parm.ni1_io.datalen = 0;
180 ic.parm.ni1_io.data = NULL;
181 free_invoke_id(pc->st, pc->prot.ni1.invoke_id);
182 pc->prot.ni1.invoke_id = 0; /* reset id */
184 cs->iif.statcallb(&ic);
185 ni1_release_l3_process(pc);
188 l3_debug(st, "dummy return error id=0x%x error=0x%lx", id, error);
189 } /* l3ni1_error_return */
191 /*******************************************************************/
192 /* called when a facility message with a dummy callref is received */
193 /* and a invoke is delivered. id specifies the invoke id. */
194 /*******************************************************************/
196 l3ni1_dummy_invoke(struct PStack *st, int cr, int id,
197 int ident, u_char *p, u_char nlen)
199 struct IsdnCardState *cs;
201 l3_debug(st, "dummy invoke %s id=0x%x ident=0x%x datalen=%d",
202 (cr == -1) ? "local" : "broadcast", id, ident, nlen);
203 if (cr >= -1) return; /* ignore local data */
205 cs = st->l1.hardware;
206 ic.driver = cs->myid;
207 ic.command = ISDN_STAT_PROT;
208 ic.arg = NI1_STAT_INVOKE_BRD;
209 ic.parm.ni1_io.hl_id = id;
210 ic.parm.ni1_io.ll_id = 0;
211 ic.parm.ni1_io.proc = ident;
212 ic.parm.ni1_io.timeout = 0;
213 ic.parm.ni1_io.datalen = nlen;
214 ic.parm.ni1_io.data = p;
216 cs->iif.statcallb(&ic);
217 } /* l3ni1_dummy_invoke */
220 l3ni1_parse_facility(struct PStack *st, struct l3_process *pc,
224 unsigned char nlen = 0, ilen, cp_tag;
229 st = pc->st; /* valid Stack */
231 if ((!st) || (cr >= 0)) return; /* neither pc nor st specified */
236 l3_debug(st, "qd_len == 0");
239 if ((*p & 0x1F) != 0x11) { /* Service discriminator, supplementary service */
240 l3_debug(st, "supplementary service != 0x11");
243 while (qd_len > 0 && !(*p & 0x80)) { /* extension ? */
248 l3_debug(st, "qd_len < 2");
253 if ((*p & 0xE0) != 0xA0) { /* class and form */
254 l3_debug(st, "class and form != 0xA0");
258 cp_tag = *p & 0x1F; /* remember tag value */
263 { l3_debug(st, "qd_len < 1");
267 { /* length format indefinite or limited */
268 nlen = *p++ & 0x7F; /* number of len bytes or indefinite */
269 if ((qd_len-- < ((!nlen) ? 3 : (1 + nlen))) ||
271 { l3_debug(st, "length format error or not implemented");
275 { nlen = *p++; /* complete length */
279 { qd_len -= 2; /* trailing null bytes */
280 if ((*(p + qd_len)) || (*(p + qd_len + 1)))
281 { l3_debug(st, "length format indefinite error");
292 { l3_debug(st, "qd_len < nlen");
298 { l3_debug(st, "nlen < 2");
302 { /* invoke identifier tag */
303 l3_debug(st, "invoke identifier tag !=0x02");
309 { /* length format */
310 l3_debug(st, "invoke id length format 2");
315 if (ilen > nlen || ilen == 0)
316 { l3_debug(st, "ilen > nlen || ilen == 0");
322 { id = (id << 8) | (*p++ & 0xFF); /* invoke identifier */
326 switch (cp_tag) { /* component tag */
329 l3_debug(st, "nlen < 2 22");
332 if (*p != 0x02) { /* operation value */
333 l3_debug(st, "operation value !=0x02");
340 if (ilen > nlen || ilen == 0) {
341 l3_debug(st, "ilen > nlen || ilen == 0 22");
347 ident = (ident << 8) | (*p++ & 0xFF);
353 l3ni1_dummy_invoke(st, cr, id, ident, p, nlen);
356 l3_debug(st, "invoke break");
358 case 2: /* return result */
359 /* if no process available handle separately */
362 l3ni1_dummy_return_result(st, id, p, nlen);
365 if ((pc->prot.ni1.invoke_id) && (pc->prot.ni1.invoke_id == id))
366 { /* Diversion successful */
367 free_invoke_id(st, pc->prot.ni1.invoke_id);
368 pc->prot.ni1.remote_result = 0; /* success */
369 pc->prot.ni1.invoke_id = 0;
370 pc->redir_result = pc->prot.ni1.remote_result;
371 st->l3.l3l4(st, CC_REDIR | INDICATION, pc); } /* Diversion successful */
373 l3_debug(st, "return error unknown identifier");
375 case 3: /* return error */
378 { l3_debug(st, "return error nlen < 2");
383 l3_debug(st, "invoke error tag !=0x02");
389 { /* length format */
390 l3_debug(st, "invoke return errlen > 4 ");
395 if (ilen > nlen || ilen == 0)
396 { l3_debug(st, "error return ilen > nlen || ilen == 0");
401 { err_ret = (err_ret << 8) | (*p++ & 0xFF); /* error value */
404 /* if no process available handle separately */
407 l3ni1_dummy_error_return(st, id, err_ret);
410 if ((pc->prot.ni1.invoke_id) && (pc->prot.ni1.invoke_id == id))
411 { /* Deflection error */
412 free_invoke_id(st, pc->prot.ni1.invoke_id);
413 pc->prot.ni1.remote_result = err_ret; /* result */
414 pc->prot.ni1.invoke_id = 0;
415 pc->redir_result = pc->prot.ni1.remote_result;
416 st->l3.l3l4(st, CC_REDIR | INDICATION, pc);
417 } /* Deflection error */
419 l3_debug(st, "return result unknown identifier");
422 l3_debug(st, "facility default break tag=0x%02x", cp_tag);
428 l3ni1_message(struct l3_process *pc, u_char mt)
433 if (!(skb = l3_alloc_skb(4)))
436 MsgHead(p, pc->callref, mt);
437 l3_msg(pc->st, DL_DATA | REQUEST, skb);
441 l3ni1_message_plus_chid(struct l3_process *pc, u_char mt)
442 /* sends an l3 messages plus channel id - added GE 05/09/00 */
449 chid = (u_char)(pc->para.bchannel & 0x03) | 0x88;
450 MsgHead(p, pc->callref, mt);
451 *p++ = IE_CHANNEL_ID;
455 if (!(skb = l3_alloc_skb(7)))
457 memcpy(skb_put(skb, 7), tmp, 7);
458 l3_msg(pc->st, DL_DATA | REQUEST, skb);
462 l3ni1_message_cause(struct l3_process *pc, u_char mt, u_char cause)
469 MsgHead(p, pc->callref, mt);
476 if (!(skb = l3_alloc_skb(l)))
478 memcpy(skb_put(skb, l), tmp, l);
479 l3_msg(pc->st, DL_DATA | REQUEST, skb);
483 l3ni1_status_send(struct l3_process *pc, u_char pr, void *arg)
490 MsgHead(p, pc->callref, MT_STATUS);
495 *p++ = pc->para.cause | 0x80;
497 *p++ = IE_CALL_STATE;
499 *p++ = pc->state & 0x3f;
502 if (!(skb = l3_alloc_skb(l)))
504 memcpy(skb_put(skb, l), tmp, l);
505 l3_msg(pc->st, DL_DATA | REQUEST, skb);
509 l3ni1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg)
511 /* This routine is called if here was no SETUP made (checks in ni1up and in
512 * l3ni1_setup) and a RELEASE_COMPLETE have to be sent with an error code
513 * MT_STATUS_ENQUIRE in the NULL state is handled too
520 switch (pc->para.cause) {
521 case 81: /* invalid callreference */
522 case 88: /* incomp destination */
523 case 96: /* mandory IE missing */
524 case 100: /* invalid IE contents */
525 case 101: /* incompatible Callstate */
526 MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);
530 *p++ = pc->para.cause | 0x80;
533 printk(KERN_ERR "HiSax l3ni1_msg_without_setup wrong cause %d\n",
538 if (!(skb = l3_alloc_skb(l)))
540 memcpy(skb_put(skb, l), tmp, l);
541 l3_msg(pc->st, DL_DATA | REQUEST, skb);
542 ni1_release_l3_process(pc);
545 static int ie_ALERTING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
546 IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_HLC,
548 static int ie_CALL_PROCEEDING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
549 IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_HLC, -1};
550 static int ie_CONNECT[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
551 IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_DATE, IE_SIGNAL,
552 IE_CONNECT_PN, IE_CONNECT_SUB, IE_LLC, IE_HLC, IE_USER_USER, -1};
553 static int ie_CONNECT_ACKNOWLEDGE[] = {IE_CHANNEL_ID, IE_DISPLAY, IE_SIGNAL, -1};
554 static int ie_DISCONNECT[] = {IE_CAUSE | IE_MANDATORY, IE_FACILITY,
555 IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};
556 static int ie_INFORMATION[] = {IE_COMPLETE, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL,
558 static int ie_NOTIFY[] = {IE_BEARER, IE_NOTIFY | IE_MANDATORY, IE_DISPLAY, -1};
559 static int ie_PROGRESS[] = {IE_BEARER, IE_CAUSE, IE_FACILITY, IE_PROGRESS |
560 IE_MANDATORY, IE_DISPLAY, IE_HLC, IE_USER_USER, -1};
561 static int ie_RELEASE[] = {IE_CAUSE | IE_MANDATORY_1, IE_FACILITY, IE_DISPLAY,
562 IE_SIGNAL, IE_USER_USER, -1};
563 /* a RELEASE_COMPLETE with errors don't require special actions
564 static int ie_RELEASE_COMPLETE[] = {IE_CAUSE | IE_MANDATORY_1, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};
566 static int ie_RESUME_ACKNOWLEDGE[] = {IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY,
568 static int ie_RESUME_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
569 static int ie_SETUP[] = {IE_COMPLETE, IE_BEARER | IE_MANDATORY,
570 IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY, IE_PROGRESS,
571 IE_NET_FAC, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL, IE_CALLING_PN,
572 IE_CALLING_SUB, IE_CALLED_PN, IE_CALLED_SUB, IE_REDIR_NR,
573 IE_LLC, IE_HLC, IE_USER_USER, -1};
574 static int ie_SETUP_ACKNOWLEDGE[] = {IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY,
575 IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, -1};
576 static int ie_STATUS[] = {IE_CAUSE | IE_MANDATORY, IE_CALL_STATE |
577 IE_MANDATORY, IE_DISPLAY, -1};
578 static int ie_STATUS_ENQUIRY[] = {IE_DISPLAY, -1};
579 static int ie_SUSPEND_ACKNOWLEDGE[] = {IE_DISPLAY, IE_FACILITY, -1};
580 static int ie_SUSPEND_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
582 * static int ie_CONGESTION_CONTROL[] = {IE_CONGESTION | IE_MANDATORY,
583 * IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
584 * static int ie_USER_INFORMATION[] = {IE_MORE_DATA, IE_USER_USER | IE_MANDATORY, -1};
585 * static int ie_RESTART[] = {IE_CHANNEL_ID, IE_DISPLAY, IE_RESTART_IND |
588 static int ie_FACILITY[] = {IE_FACILITY | IE_MANDATORY, IE_DISPLAY, -1};
589 static int comp_required[] = {1, 2, 3, 5, 6, 7, 9, 10, 11, 14, 15, -1};
590 static int l3_valid_states[] = {0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 15, 17, 19, 25, -1};
598 struct ie_len max_ie_len[] = {
616 {IE_PACK_BINPARA, 3},
617 {IE_PACK_WINSIZE, 4},
622 {IE_CALLING_SUB, 23},
635 getmax_ie_len(u_char ie) {
637 while (max_ie_len[i].ie != -1) {
638 if (max_ie_len[i].ie == ie)
639 return (max_ie_len[i].len);
646 ie_in_set(struct l3_process *pc, u_char ie, int *checklist) {
649 while (*checklist != -1) {
650 if ((*checklist & 0xff) == ie) {
663 check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist)
668 int l, newpos, oldpos;
669 int err_seq = 0, err_len = 0, err_compr = 0, err_ureg = 0;
671 u_char old_codeset = 0;
681 while ((p - skb->data) < skb->len) {
682 if ((*p & 0xf0) == 0x90) { /* shift codeset */
683 old_codeset = codeset;
689 if (pc->debug & L3_DEB_CHECK)
690 l3_debug(pc->st, "check IE shift%scodeset %d->%d",
691 codelock ? " locking " : " ", old_codeset, codeset);
695 if (!codeset) { /* only codeset 0 */
696 if ((newpos = ie_in_set(pc, *p, cl))) {
704 if (ie_in_set(pc, *p, comp_required))
718 if (!codeset && (l > getmax_ie_len(ie)))
721 if (pc->debug & L3_DEB_CHECK)
722 l3_debug(pc->st, "check IE shift back codeset %d->%d",
723 codeset, old_codeset);
724 codeset = old_codeset;
728 if (err_compr | err_ureg | err_len | err_seq) {
729 if (pc->debug & L3_DEB_CHECK)
730 l3_debug(pc->st, "check IE MT(%x) %d/%d/%d/%d",
731 mt, err_compr, err_ureg, err_len, err_seq);
733 return (ERR_IE_COMPREHENSION);
735 return (ERR_IE_UNRECOGNIZED);
737 return (ERR_IE_LENGTH);
739 return (ERR_IE_SEQUENCE);
744 /* verify if a message type exists and contain no IE error */
746 l3ni1_check_messagetype_validity(struct l3_process *pc, int mt, void *arg)
750 case MT_CALL_PROCEEDING:
752 case MT_CONNECT_ACKNOWLEDGE:
759 case MT_RELEASE_COMPLETE:
761 case MT_SETUP_ACKNOWLEDGE:
762 case MT_RESUME_ACKNOWLEDGE:
763 case MT_RESUME_REJECT:
764 case MT_SUSPEND_ACKNOWLEDGE:
765 case MT_SUSPEND_REJECT:
766 case MT_USER_INFORMATION:
768 case MT_RESTART_ACKNOWLEDGE:
769 case MT_CONGESTION_CONTROL:
771 case MT_STATUS_ENQUIRY:
772 if (pc->debug & L3_DEB_CHECK)
773 l3_debug(pc->st, "l3ni1_check_messagetype_validity mt(%x) OK", mt);
775 case MT_RESUME: /* RESUME only in user->net */
776 case MT_SUSPEND: /* SUSPEND only in user->net */
778 if (pc->debug & (L3_DEB_CHECK | L3_DEB_WARN))
779 l3_debug(pc->st, "l3ni1_check_messagetype_validity mt(%x) fail", mt);
781 l3ni1_status_send(pc, 0, NULL);
788 l3ni1_std_ie_err(struct l3_process *pc, int ret) {
790 if (pc->debug & L3_DEB_CHECK)
791 l3_debug(pc->st, "check_infoelements ret %d", ret);
795 case ERR_IE_COMPREHENSION:
797 l3ni1_status_send(pc, 0, NULL);
799 case ERR_IE_UNRECOGNIZED:
801 l3ni1_status_send(pc, 0, NULL);
804 pc->para.cause = 100;
805 l3ni1_status_send(pc, 0, NULL);
807 case ERR_IE_SEQUENCE:
814 l3ni1_get_channel_id(struct l3_process *pc, struct sk_buff *skb) {
818 if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) {
820 if (*p != 1) { /* len for BRI = 1 */
821 if (pc->debug & L3_DEB_WARN)
822 l3_debug(pc->st, "wrong chid len %d", *p);
826 if (*p & 0x60) { /* only base rate interface */
827 if (pc->debug & L3_DEB_WARN)
828 l3_debug(pc->st, "wrong chid %x", *p);
837 l3ni1_get_cause(struct l3_process *pc, struct sk_buff *skb) {
844 if ((p = findie(p, skb->len, IE_CAUSE, 0))) {
855 if (l && !(pc->para.loc & 0x80)) {
857 p++; /* skip recommendation */
860 pc->para.cause = *p++;
862 if (!(pc->para.cause & 0x80))
866 while (l && (i < 6)) {
867 pc->para.diag[i++] = *p++;
876 l3ni1_msg_with_uus(struct l3_process *pc, u_char cmd)
883 MsgHead(p, pc->callref, cmd);
885 if (pc->prot.ni1.uus1_data[0])
886 { *p++ = IE_USER_USER; /* UUS info element */
887 *p++ = strlen(pc->prot.ni1.uus1_data) + 1;
888 *p++ = 0x04; /* IA5 chars */
889 strcpy(p, pc->prot.ni1.uus1_data);
890 p += strlen(pc->prot.ni1.uus1_data);
891 pc->prot.ni1.uus1_data[0] = '\0';
895 if (!(skb = l3_alloc_skb(l)))
897 memcpy(skb_put(skb, l), tmp, l);
898 l3_msg(pc->st, DL_DATA | REQUEST, skb);
899 } /* l3ni1_msg_with_uus */
902 l3ni1_release_req(struct l3_process *pc, u_char pr, void *arg)
906 if (!pc->prot.ni1.uus1_data[0])
907 l3ni1_message(pc, MT_RELEASE);
909 l3ni1_msg_with_uus(pc, MT_RELEASE);
910 L3AddTimer(&pc->timer, T308, CC_T308_1);
914 l3ni1_release_cmpl(struct l3_process *pc, u_char pr, void *arg)
916 struct sk_buff *skb = arg;
919 if ((ret = l3ni1_get_cause(pc, skb)) > 0) {
920 if (pc->debug & L3_DEB_WARN)
921 l3_debug(pc->st, "RELCMPL get_cause ret(%d)", ret);
923 pc->para.cause = NO_CAUSE;
926 pc->st->l3.l3l4(pc->st, CC_RELEASE | CONFIRM, pc);
927 ni1_release_l3_process(pc);
933 EncodeASyncParams(u_char *p, u_char si2)
934 { // 7c 06 88 90 21 42 00 bb
937 p[1] = 0x40; // Intermediate rate: 16 kbit/s jj 2000.02.19
939 if (si2 & 32) // 7 data bits
946 if (si2 & 16) // 2 stop bits
953 if (si2 & 8) // even parity
960 switch (si2 & 0x07) {
962 p[0] = 66; // 1200 bit/s
966 p[0] = 88; // 1200/75 bit/s
970 p[0] = 87; // 75/1200 bit/s
974 p[0] = 67; // 2400 bit/s
978 p[0] = 69; // 4800 bit/s
982 p[0] = 72; // 9600 bit/s
986 p[0] = 73; // 14400 bit/s
990 p[0] = 75; // 19200 bit/s
998 EncodeSyncParams(u_char si2, u_char ai)
1003 return ai + 2; // 1200 bit/s
1006 return ai + 24; // 1200/75 bit/s
1009 return ai + 23; // 75/1200 bit/s
1012 return ai + 3; // 2400 bit/s
1015 return ai + 5; // 4800 bit/s
1018 return ai + 8; // 9600 bit/s
1021 return ai + 9; // 14400 bit/s
1024 return ai + 11; // 19200 bit/s
1027 return ai + 14; // 48000 bit/s
1030 return ai + 15; // 56000 bit/s
1033 return ai + 40; // negotiate bit/s
1043 DecodeASyncParams(u_char si2, u_char *p)
1048 case 66: // 1200 bit/s
1050 break; // si2 don't change
1052 case 88: // 1200/75 bit/s
1056 case 87: // 75/1200 bit/s
1060 case 67: // 2400 bit/s
1064 case 69: // 4800 bit/s
1068 case 72: // 9600 bit/s
1072 case 73: // 14400 bit/s
1076 case 75: // 19200 bit/s
1083 if ((info & 16) && (!(info & 8))) // 7 data bits
1085 si2 += 32; // else 8 data bits
1087 if ((info & 96) == 96) // 2 stop bits
1089 si2 += 16; // else 1 stop bit
1091 if ((info & 2) && (!(info & 1))) // even parity
1093 si2 += 8; // else no parity
1100 DecodeSyncParams(u_char si2, u_char info)
1104 case 40: // bit/s negotiation failed ai := 165 not 175!
1107 case 15: // 56000 bit/s failed, ai := 0 not 169 !
1110 case 14: // 48000 bit/s
1113 case 11: // 19200 bit/s
1116 case 9: // 14400 bit/s
1119 case 8: // 9600 bit/s
1122 case 5: // 4800 bit/s
1125 case 3: // 2400 bit/s
1128 case 23: // 75/1200 bit/s
1131 case 24: // 1200/75 bit/s
1134 default: // 1200 bit/s
1141 DecodeSI2(struct sk_buff *skb)
1143 u_char *p; //, *pend=skb->data + skb->len;
1145 if ((p = findie(skb->data, skb->len, 0x7c, 0))) {
1146 switch (p[4] & 0x0f) {
1148 if (p[1] == 0x04) // sync. Bitratenadaption
1150 return DecodeSyncParams(160, p[5]); // V.110/X.30
1152 else if (p[1] == 0x06) // async. Bitratenadaption
1154 return DecodeASyncParams(192, p); // V.110/X.30
1157 case 0x08: // if (p[5] == 0x02) // sync. Bitratenadaption
1159 return DecodeSyncParams(176, p[5]); // V.120
1170 l3ni1_setup_req(struct l3_process *pc, u_char pr,
1173 struct sk_buff *skb;
1182 MsgHead(p, pc->callref, MT_SETUP);
1184 teln = pc->para.setup.phone;
1186 *p++ = 0xa1; /* complete indicator */
1188 * Set Bearer Capability, Map info from 1TR6-convention to NI1
1190 switch (pc->para.setup.si1) {
1191 case 1: /* Telephony */
1193 *p++ = 0x3; /* Length */
1194 *p++ = 0x90; /* 3.1khz Audio */
1195 *p++ = 0x90; /* Circuit-Mode 64kbps */
1196 *p++ = 0xa2; /* u-Law Audio */
1198 case 5: /* Datatransmission 64k, BTX */
1199 case 7: /* Datatransmission 64k */
1202 *p++ = 0x2; /* Length */
1203 *p++ = 0x88; /* Coding Std. CCITT, unrestr. dig. Inform. */
1204 *p++ = 0x90; /* Circuit-Mode 64kbps */
1219 *p++ = strlen(teln);
1221 *p++ = (*teln++) & 0x7F;
1227 if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) { // sync. Bitratenadaption, V.110/X.30
1234 *p++ = EncodeSyncParams(pc->para.setup.si2 - 160, 0x80);
1235 } else if ((pc->para.setup.si2 >= 176) && (pc->para.setup.si2 <= 191)) { // sync. Bitratenadaption, V.120
1242 *p++ = EncodeSyncParams(pc->para.setup.si2 - 176, 0);
1244 } else if (pc->para.setup.si2 >= 192) { // async. Bitratenadaption, V.110/X.30
1251 p = EncodeASyncParams(p, pc->para.setup.si2 - 192);
1253 switch (pc->para.setup.si1) {
1254 case 1: /* Telephony */
1256 *p++ = 0x3; /* Length */
1257 *p++ = 0x90; /* Coding Std. CCITT, 3.1 kHz audio */
1258 *p++ = 0x90; /* Circuit-Mode 64kbps */
1259 *p++ = 0xa2; /* u-Law Audio */
1261 case 5: /* Datatransmission 64k, BTX */
1262 case 7: /* Datatransmission 64k */
1265 *p++ = 0x2; /* Length */
1266 *p++ = 0x88; /* Coding Std. CCITT, unrestr. dig. Inform. */
1267 *p++ = 0x90; /* Circuit-Mode 64kbps */
1273 if (!(skb = l3_alloc_skb(l)))
1277 memcpy(skb_put(skb, l), tmp, l);
1278 L3DelTimer(&pc->timer);
1279 L3AddTimer(&pc->timer, T303, CC_T303);
1281 l3_msg(pc->st, DL_DATA | REQUEST, skb);
1285 l3ni1_call_proc(struct l3_process *pc, u_char pr, void *arg)
1287 struct sk_buff *skb = arg;
1290 if ((id = l3ni1_get_channel_id(pc, skb)) >= 0) {
1291 if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) {
1292 if (pc->debug & L3_DEB_WARN)
1293 l3_debug(pc->st, "setup answer with wrong chid %x", id);
1294 pc->para.cause = 100;
1295 l3ni1_status_send(pc, pr, NULL);
1298 pc->para.bchannel = id;
1299 } else if (1 == pc->state) {
1300 if (pc->debug & L3_DEB_WARN)
1301 l3_debug(pc->st, "setup answer wrong chid (ret %d)", id);
1303 pc->para.cause = 96;
1305 pc->para.cause = 100;
1306 l3ni1_status_send(pc, pr, NULL);
1309 /* Now we are on none mandatory IEs */
1310 ret = check_infoelements(pc, skb, ie_CALL_PROCEEDING);
1311 if (ERR_IE_COMPREHENSION == ret) {
1312 l3ni1_std_ie_err(pc, ret);
1315 L3DelTimer(&pc->timer);
1317 L3AddTimer(&pc->timer, T310, CC_T310);
1318 if (ret) /* STATUS for none mandatory IE errors after actions are taken */
1319 l3ni1_std_ie_err(pc, ret);
1320 pc->st->l3.l3l4(pc->st, CC_PROCEEDING | INDICATION, pc);
1324 l3ni1_setup_ack(struct l3_process *pc, u_char pr, void *arg)
1326 struct sk_buff *skb = arg;
1329 if ((id = l3ni1_get_channel_id(pc, skb)) >= 0) {
1330 if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) {
1331 if (pc->debug & L3_DEB_WARN)
1332 l3_debug(pc->st, "setup answer with wrong chid %x", id);
1333 pc->para.cause = 100;
1334 l3ni1_status_send(pc, pr, NULL);
1337 pc->para.bchannel = id;
1339 if (pc->debug & L3_DEB_WARN)
1340 l3_debug(pc->st, "setup answer wrong chid (ret %d)", id);
1342 pc->para.cause = 96;
1344 pc->para.cause = 100;
1345 l3ni1_status_send(pc, pr, NULL);
1348 /* Now we are on none mandatory IEs */
1349 ret = check_infoelements(pc, skb, ie_SETUP_ACKNOWLEDGE);
1350 if (ERR_IE_COMPREHENSION == ret) {
1351 l3ni1_std_ie_err(pc, ret);
1354 L3DelTimer(&pc->timer);
1356 L3AddTimer(&pc->timer, T304, CC_T304);
1357 if (ret) /* STATUS for none mandatory IE errors after actions are taken */
1358 l3ni1_std_ie_err(pc, ret);
1359 pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc);
1363 l3ni1_disconnect(struct l3_process *pc, u_char pr, void *arg)
1365 struct sk_buff *skb = arg;
1371 if ((ret = l3ni1_get_cause(pc, skb))) {
1372 if (pc->debug & L3_DEB_WARN)
1373 l3_debug(pc->st, "DISC get_cause ret(%d)", ret);
1379 if ((p = findie(skb->data, skb->len, IE_FACILITY, 0)))
1380 l3ni1_parse_facility(pc->st, pc, pc->callref, p);
1381 ret = check_infoelements(pc, skb, ie_DISCONNECT);
1382 if (ERR_IE_COMPREHENSION == ret)
1384 else if ((!cause) && (ERR_IE_UNRECOGNIZED == ret))
1391 pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc);
1393 l3ni1_release_req(pc, pr, NULL);
1395 l3ni1_message_cause(pc, MT_RELEASE, cause);
1396 L3AddTimer(&pc->timer, T308, CC_T308_1);
1401 l3ni1_connect(struct l3_process *pc, u_char pr, void *arg)
1403 struct sk_buff *skb = arg;
1406 ret = check_infoelements(pc, skb, ie_CONNECT);
1407 if (ERR_IE_COMPREHENSION == ret) {
1408 l3ni1_std_ie_err(pc, ret);
1411 L3DelTimer(&pc->timer); /* T310 */
1413 pc->para.chargeinfo = 0;
1414 /* here should inserted COLP handling KKe */
1416 l3ni1_std_ie_err(pc, ret);
1417 pc->st->l3.l3l4(pc->st, CC_SETUP | CONFIRM, pc);
1421 l3ni1_alerting(struct l3_process *pc, u_char pr, void *arg)
1423 struct sk_buff *skb = arg;
1426 ret = check_infoelements(pc, skb, ie_ALERTING);
1427 if (ERR_IE_COMPREHENSION == ret) {
1428 l3ni1_std_ie_err(pc, ret);
1431 L3DelTimer(&pc->timer); /* T304 */
1434 l3ni1_std_ie_err(pc, ret);
1435 pc->st->l3.l3l4(pc->st, CC_ALERTING | INDICATION, pc);
1439 l3ni1_setup(struct l3_process *pc, u_char pr, void *arg)
1444 struct sk_buff *skb = arg;
1449 * Bearer Capabilities
1452 /* only the first occurrence 'll be detected ! */
1453 if ((p = findie(p, skb->len, 0x04, 0))) {
1454 if ((p[1] < 2) || (p[1] > 11))
1457 pc->para.setup.si2 = 0;
1458 switch (p[2] & 0x7f) {
1459 case 0x00: /* Speech */
1460 case 0x10: /* 3.1 Khz audio */
1461 pc->para.setup.si1 = 1;
1463 case 0x08: /* Unrestricted digital information */
1464 pc->para.setup.si1 = 7;
1465 /* JIM, 05.11.97 I wanna set service indicator 2 */
1467 pc->para.setup.si2 = DecodeSI2(skb);
1470 case 0x09: /* Restricted digital information */
1471 pc->para.setup.si1 = 2;
1474 /* Unrestr. digital information with
1475 * tones/announcements ( or 7 kHz audio
1477 pc->para.setup.si1 = 3;
1479 case 0x18: /* Video */
1480 pc->para.setup.si1 = 4;
1486 switch (p[3] & 0x7f) {
1487 case 0x40: /* packed mode */
1488 pc->para.setup.si1 = 8;
1490 case 0x10: /* 64 kbit */
1491 case 0x11: /* 2*64 kbit */
1492 case 0x13: /* 384 kbit */
1493 case 0x15: /* 1536 kbit */
1494 case 0x17: /* 1920 kbit */
1495 pc->para.moderate = p[3] & 0x7f;
1502 if (pc->debug & L3_DEB_SI)
1503 l3_debug(pc->st, "SI=%d, AI=%d",
1504 pc->para.setup.si1, pc->para.setup.si2);
1506 if (pc->debug & L3_DEB_WARN)
1507 l3_debug(pc->st, "setup with wrong bearer(l=%d:%x,%x)",
1509 pc->para.cause = 100;
1510 l3ni1_msg_without_setup(pc, pr, NULL);
1514 if (pc->debug & L3_DEB_WARN)
1515 l3_debug(pc->st, "setup without bearer capabilities");
1516 /* ETS 300-104 1.3.3 */
1517 pc->para.cause = 96;
1518 l3ni1_msg_without_setup(pc, pr, NULL);
1522 * Channel Identification
1524 if ((id = l3ni1_get_channel_id(pc, skb)) >= 0) {
1525 if ((pc->para.bchannel = id)) {
1526 if ((3 == id) && (0x10 == pc->para.moderate)) {
1527 if (pc->debug & L3_DEB_WARN)
1528 l3_debug(pc->st, "setup with wrong chid %x",
1530 pc->para.cause = 100;
1531 l3ni1_msg_without_setup(pc, pr, NULL);
1536 { if (pc->debug & L3_DEB_WARN)
1537 l3_debug(pc->st, "setup without bchannel, call waiting");
1541 if (pc->debug & L3_DEB_WARN)
1542 l3_debug(pc->st, "setup with wrong chid ret %d", id);
1544 pc->para.cause = 96;
1546 pc->para.cause = 100;
1547 l3ni1_msg_without_setup(pc, pr, NULL);
1550 /* Now we are on none mandatory IEs */
1551 err = check_infoelements(pc, skb, ie_SETUP);
1552 if (ERR_IE_COMPREHENSION == err) {
1553 pc->para.cause = 96;
1554 l3ni1_msg_without_setup(pc, pr, NULL);
1558 if ((p = findie(p, skb->len, 0x70, 0)))
1559 iecpy(pc->para.setup.eazmsn, p, 1);
1561 pc->para.setup.eazmsn[0] = 0;
1564 if ((p = findie(p, skb->len, 0x71, 0))) {
1565 /* Called party subaddress */
1566 if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) {
1568 iecpy(&tmp[1], p, 2);
1569 strcat(pc->para.setup.eazmsn, tmp);
1570 } else if (pc->debug & L3_DEB_WARN)
1571 l3_debug(pc->st, "wrong called subaddress");
1574 if ((p = findie(p, skb->len, 0x6c, 0))) {
1575 pc->para.setup.plan = p[2];
1577 iecpy(pc->para.setup.phone, p, 1);
1578 pc->para.setup.screen = 0;
1580 iecpy(pc->para.setup.phone, p, 2);
1581 pc->para.setup.screen = p[3];
1584 pc->para.setup.phone[0] = 0;
1585 pc->para.setup.plan = 0;
1586 pc->para.setup.screen = 0;
1589 if ((p = findie(p, skb->len, 0x6d, 0))) {
1590 /* Calling party subaddress */
1591 if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) {
1593 iecpy(&tmp[1], p, 2);
1594 strcat(pc->para.setup.phone, tmp);
1595 } else if (pc->debug & L3_DEB_WARN)
1596 l3_debug(pc->st, "wrong calling subaddress");
1599 if (err) /* STATUS for none mandatory IE errors after actions are taken */
1600 l3ni1_std_ie_err(pc, err);
1601 pc->st->l3.l3l4(pc->st, CC_SETUP | INDICATION, pc);
1605 l3ni1_reset(struct l3_process *pc, u_char pr, void *arg)
1607 ni1_release_l3_process(pc);
1611 l3ni1_disconnect_req(struct l3_process *pc, u_char pr, void *arg)
1613 struct sk_buff *skb;
1614 u_char tmp[16 + 40];
1619 if (pc->para.cause != NO_CAUSE)
1620 cause = pc->para.cause;
1624 MsgHead(p, pc->callref, MT_DISCONNECT);
1629 *p++ = cause | 0x80;
1631 if (pc->prot.ni1.uus1_data[0])
1632 { *p++ = IE_USER_USER; /* UUS info element */
1633 *p++ = strlen(pc->prot.ni1.uus1_data) + 1;
1634 *p++ = 0x04; /* IA5 chars */
1635 strcpy(p, pc->prot.ni1.uus1_data);
1636 p += strlen(pc->prot.ni1.uus1_data);
1637 pc->prot.ni1.uus1_data[0] = '\0';
1641 if (!(skb = l3_alloc_skb(l)))
1643 memcpy(skb_put(skb, l), tmp, l);
1645 l3_msg(pc->st, DL_DATA | REQUEST, skb);
1646 L3AddTimer(&pc->timer, T305, CC_T305);
1650 l3ni1_setup_rsp(struct l3_process *pc, u_char pr,
1653 if (!pc->para.bchannel)
1654 { if (pc->debug & L3_DEB_WARN)
1655 l3_debug(pc->st, "D-chan connect for waiting call");
1656 l3ni1_disconnect_req(pc, pr, arg);
1660 if (pc->debug & L3_DEB_WARN)
1661 l3_debug(pc->st, "D-chan connect for waiting call");
1662 l3ni1_message_plus_chid(pc, MT_CONNECT); /* GE 05/09/00 */
1663 L3DelTimer(&pc->timer);
1664 L3AddTimer(&pc->timer, T313, CC_T313);
1668 l3ni1_connect_ack(struct l3_process *pc, u_char pr, void *arg)
1670 struct sk_buff *skb = arg;
1673 ret = check_infoelements(pc, skb, ie_CONNECT_ACKNOWLEDGE);
1674 if (ERR_IE_COMPREHENSION == ret) {
1675 l3ni1_std_ie_err(pc, ret);
1679 L3DelTimer(&pc->timer);
1681 l3ni1_std_ie_err(pc, ret);
1682 pc->st->l3.l3l4(pc->st, CC_SETUP_COMPL | INDICATION, pc);
1686 l3ni1_reject_req(struct l3_process *pc, u_char pr, void *arg)
1688 struct sk_buff *skb;
1694 if (pc->para.cause != NO_CAUSE)
1695 cause = pc->para.cause;
1697 MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);
1702 *p++ = cause | 0x80;
1705 if (!(skb = l3_alloc_skb(l)))
1707 memcpy(skb_put(skb, l), tmp, l);
1708 l3_msg(pc->st, DL_DATA | REQUEST, skb);
1709 pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
1711 ni1_release_l3_process(pc);
1715 l3ni1_release(struct l3_process *pc, u_char pr, void *arg)
1717 struct sk_buff *skb = arg;
1722 if ((ret = l3ni1_get_cause(pc, skb)) > 0) {
1723 if (pc->debug & L3_DEB_WARN)
1724 l3_debug(pc->st, "REL get_cause ret(%d)", ret);
1726 pc->para.cause = NO_CAUSE;
1727 if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) {
1728 l3ni1_parse_facility(pc->st, pc, pc->callref, p);
1730 if ((ret < 0) && (pc->state != 11))
1734 ret = check_infoelements(pc, skb, ie_RELEASE);
1735 if (ERR_IE_COMPREHENSION == ret)
1737 else if ((ERR_IE_UNRECOGNIZED == ret) && (!cause))
1740 l3ni1_message_cause(pc, MT_RELEASE_COMPLETE, cause);
1742 l3ni1_message(pc, MT_RELEASE_COMPLETE);
1743 pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
1745 ni1_release_l3_process(pc);
1749 l3ni1_alert_req(struct l3_process *pc, u_char pr,
1753 if (!pc->prot.ni1.uus1_data[0])
1754 l3ni1_message(pc, MT_ALERTING);
1756 l3ni1_msg_with_uus(pc, MT_ALERTING);
1760 l3ni1_proceed_req(struct l3_process *pc, u_char pr,
1764 l3ni1_message(pc, MT_CALL_PROCEEDING);
1765 pc->st->l3.l3l4(pc->st, CC_PROCEED_SEND | INDICATION, pc);
1769 l3ni1_setup_ack_req(struct l3_process *pc, u_char pr,
1773 L3DelTimer(&pc->timer);
1774 L3AddTimer(&pc->timer, T302, CC_T302);
1775 l3ni1_message(pc, MT_SETUP_ACKNOWLEDGE);
1778 /********************************************/
1779 /* deliver a incoming display message to HL */
1780 /********************************************/
1782 l3ni1_deliver_display(struct l3_process *pc, int pr, u_char *infp)
1785 struct IsdnCardState *cs;
1788 if (*infp++ != IE_DISPLAY) return;
1789 if ((len = *infp++) > 80) return; /* total length <= 82 */
1790 if (!pc->chan) return;
1792 p = ic.parm.display;
1796 ic.command = ISDN_STAT_DISPLAY;
1797 cs = pc->st->l1.hardware;
1798 ic.driver = cs->myid;
1799 ic.arg = pc->chan->chan;
1800 cs->iif.statcallb(&ic);
1801 } /* l3ni1_deliver_display */
1805 l3ni1_progress(struct l3_process *pc, u_char pr, void *arg)
1807 struct sk_buff *skb = arg;
1811 if ((p = findie(skb->data, skb->len, IE_PROGRESS, 0))) {
1814 pc->para.cause = 100;
1815 } else if (!(p[2] & 0x70)) {
1833 pc->para.cause = 100;
1839 pc->para.cause = 100;
1844 pc->para.cause = 96;
1848 if (pc->debug & L3_DEB_WARN)
1849 l3_debug(pc->st, "progress error %d", err);
1850 l3ni1_status_send(pc, pr, NULL);
1853 /* Now we are on none mandatory IEs */
1854 err = check_infoelements(pc, skb, ie_PROGRESS);
1856 l3ni1_std_ie_err(pc, err);
1857 if (ERR_IE_COMPREHENSION != err)
1858 pc->st->l3.l3l4(pc->st, CC_PROGRESS | INDICATION, pc);
1862 l3ni1_notify(struct l3_process *pc, u_char pr, void *arg)
1864 struct sk_buff *skb = arg;
1868 if ((p = findie(skb->data, skb->len, IE_NOTIFY, 0))) {
1871 pc->para.cause = 100;
1879 pc->para.cause = 100;
1885 pc->para.cause = 96;
1889 if (pc->debug & L3_DEB_WARN)
1890 l3_debug(pc->st, "notify error %d", err);
1891 l3ni1_status_send(pc, pr, NULL);
1894 /* Now we are on none mandatory IEs */
1895 err = check_infoelements(pc, skb, ie_NOTIFY);
1897 l3ni1_std_ie_err(pc, err);
1898 if (ERR_IE_COMPREHENSION != err)
1899 pc->st->l3.l3l4(pc->st, CC_NOTIFY | INDICATION, pc);
1903 l3ni1_status_enq(struct l3_process *pc, u_char pr, void *arg)
1906 struct sk_buff *skb = arg;
1908 ret = check_infoelements(pc, skb, ie_STATUS_ENQUIRY);
1909 l3ni1_std_ie_err(pc, ret);
1910 pc->para.cause = 30; /* response to STATUS_ENQUIRY */
1911 l3ni1_status_send(pc, pr, NULL);
1915 l3ni1_information(struct l3_process *pc, u_char pr, void *arg)
1918 struct sk_buff *skb = arg;
1922 ret = check_infoelements(pc, skb, ie_INFORMATION);
1924 l3ni1_std_ie_err(pc, ret);
1925 if (pc->state == 25) { /* overlap receiving */
1926 L3DelTimer(&pc->timer);
1928 if ((p = findie(p, skb->len, 0x70, 0))) {
1930 strcat(pc->para.setup.eazmsn, tmp);
1931 pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc);
1933 L3AddTimer(&pc->timer, T302, CC_T302);
1937 /******************************/
1938 /* handle deflection requests */
1939 /******************************/
1940 static void l3ni1_redir_req(struct l3_process *pc, u_char pr, void *arg)
1942 struct sk_buff *skb;
1946 u_char len_phone = 0;
1951 strcpy(pc->prot.ni1.uus1_data, pc->chan->setup.eazmsn); /* copy uus element if available */
1952 if (!pc->chan->setup.phone[0])
1953 { pc->para.cause = -1;
1954 l3ni1_disconnect_req(pc, pr, arg); /* disconnect immediately */
1958 if (pc->prot.ni1.invoke_id)
1959 free_invoke_id(pc->st, pc->prot.ni1.invoke_id);
1961 if (!(pc->prot.ni1.invoke_id = new_invoke_id(pc->st)))
1964 MsgHead(p, pc->callref, MT_FACILITY);
1966 for (subp = pc->chan->setup.phone; (*subp) && (*subp != '.'); subp++) len_phone++; /* len of phone number */
1967 if (*subp++ == '.') len_sub = strlen(subp) + 2; /* length including info subaddress element */
1969 *p++ = 0x1c; /* Facility info element */
1970 *p++ = len_phone + len_sub + 2 + 2 + 8 + 3 + 3; /* length of element */
1971 *p++ = 0x91; /* remote operations protocol */
1972 *p++ = 0xa1; /* invoke component */
1974 *p++ = len_phone + len_sub + 2 + 2 + 8 + 3; /* length of data */
1975 *p++ = 0x02; /* invoke id tag, integer */
1976 *p++ = 0x01; /* length */
1977 *p++ = pc->prot.ni1.invoke_id; /* invoke id */
1978 *p++ = 0x02; /* operation value tag, integer */
1979 *p++ = 0x01; /* length */
1980 *p++ = 0x0D; /* Call Deflect */
1982 *p++ = 0x30; /* sequence phone number */
1983 *p++ = len_phone + 2 + 2 + 3 + len_sub; /* length */
1985 *p++ = 0x30; /* Deflected to UserNumber */
1986 *p++ = len_phone + 2 + len_sub; /* length */
1987 *p++ = 0x80; /* NumberDigits */
1988 *p++ = len_phone; /* length */
1989 for (l = 0; l < len_phone; l++)
1990 *p++ = pc->chan->setup.phone[l];
1993 { *p++ = 0x04; /* called party subaddress */
1995 while (*subp) *p++ = *subp++;
1998 *p++ = 0x01; /* screening identifier */
2000 *p++ = pc->chan->setup.screen;
2003 if (!(skb = l3_alloc_skb(l))) return;
2004 memcpy(skb_put(skb, l), tmp, l);
2006 l3_msg(pc->st, DL_DATA | REQUEST, skb);
2007 } /* l3ni1_redir_req */
2009 /********************************************/
2010 /* handle deflection request in early state */
2011 /********************************************/
2012 static void l3ni1_redir_req_early(struct l3_process *pc, u_char pr, void *arg)
2014 l3ni1_proceed_req(pc, pr, arg);
2015 l3ni1_redir_req(pc, pr, arg);
2016 } /* l3ni1_redir_req_early */
2018 /***********************************************/
2019 /* handle special commands for this protocol. */
2020 /* Examples are call independent services like */
2021 /* remote operations with dummy callref. */
2022 /***********************************************/
2023 static int l3ni1_cmd_global(struct PStack *st, isdn_ctrl *ic)
2028 struct sk_buff *skb;
2029 struct l3_process *pc = NULL;
2032 { case NI1_CMD_INVOKE:
2033 if (ic->parm.ni1_io.datalen < 0) return (-2); /* invalid parameter */
2035 for (proc_len = 1, i = ic->parm.ni1_io.proc >> 8; i; i++)
2036 i = i >> 8; /* add one byte */
2037 l = ic->parm.ni1_io.datalen + proc_len + 8; /* length excluding ie header */
2039 return (-2); /* too long */
2041 if (!(id = new_invoke_id(st)))
2042 return (0); /* first get a invoke id -> return if no available */
2045 MsgHead(p, i, MT_FACILITY); /* build message head */
2046 *p++ = 0x1C; /* Facility IE */
2047 *p++ = l; /* length of ie */
2048 *p++ = 0x91; /* remote operations */
2049 *p++ = 0xA1; /* invoke */
2050 *p++ = l - 3; /* length of invoke */
2051 *p++ = 0x02; /* invoke id tag */
2052 *p++ = 0x01; /* length is 1 */
2053 *p++ = id; /* invoke id */
2054 *p++ = 0x02; /* operation */
2055 *p++ = proc_len; /* length of operation */
2057 for (i = proc_len; i; i--)
2058 *p++ = (ic->parm.ni1_io.proc >> (i - 1)) & 0xFF;
2059 memcpy(p, ic->parm.ni1_io.data, ic->parm.ni1_io.datalen); /* copy data */
2060 l = (p - temp) + ic->parm.ni1_io.datalen; /* total length */
2062 if (ic->parm.ni1_io.timeout > 0) {
2063 pc = ni1_new_l3_process(st, -1);
2065 free_invoke_id(st, id);
2069 pc->prot.ni1.ll_id = ic->parm.ni1_io.ll_id;
2071 pc->prot.ni1.proc = ic->parm.ni1_io.proc;
2074 if (!(skb = l3_alloc_skb(l)))
2075 { free_invoke_id(st, id);
2076 if (pc) ni1_release_l3_process(pc);
2079 memcpy(skb_put(skb, l), temp, l);
2082 { pc->prot.ni1.invoke_id = id; /* remember id */
2083 L3AddTimer(&pc->timer, ic->parm.ni1_io.timeout, CC_TNI1_IO | REQUEST);
2086 l3_msg(st, DL_DATA | REQUEST, skb);
2087 ic->parm.ni1_io.hl_id = id; /* return id */
2090 case NI1_CMD_INVOKE_ABORT:
2091 if ((pc = l3ni1_search_dummy_proc(st, ic->parm.ni1_io.hl_id)))
2092 { L3DelTimer(&pc->timer); /* remove timer */
2093 ni1_release_l3_process(pc);
2097 { l3_debug(st, "l3ni1_cmd_global abort unknown id");
2103 l3_debug(st, "l3ni1_cmd_global unknown cmd 0x%lx", ic->arg);
2105 } /* switch ic-> arg */
2107 } /* l3ni1_cmd_global */
2110 l3ni1_io_timer(struct l3_process *pc)
2112 struct IsdnCardState *cs = pc->st->l1.hardware;
2114 L3DelTimer(&pc->timer); /* remove timer */
2116 ic.driver = cs->myid;
2117 ic.command = ISDN_STAT_PROT;
2118 ic.arg = NI1_STAT_INVOKE_ERR;
2119 ic.parm.ni1_io.hl_id = pc->prot.ni1.invoke_id;
2120 ic.parm.ni1_io.ll_id = pc->prot.ni1.ll_id;
2121 ic.parm.ni1_io.proc = pc->prot.ni1.proc;
2122 ic.parm.ni1_io.timeout = -1;
2123 ic.parm.ni1_io.datalen = 0;
2124 ic.parm.ni1_io.data = NULL;
2125 free_invoke_id(pc->st, pc->prot.ni1.invoke_id);
2126 pc->prot.ni1.invoke_id = 0; /* reset id */
2128 cs->iif.statcallb(&ic);
2130 ni1_release_l3_process(pc);
2131 } /* l3ni1_io_timer */
2134 l3ni1_release_ind(struct l3_process *pc, u_char pr, void *arg)
2137 struct sk_buff *skb = arg;
2141 if ((p = findie(p, skb->len, IE_CALL_STATE, 0))) {
2146 if (callState == 0) {
2147 /* ETS 300-104 7.6.1, 8.6.1, 10.6.1... and 16.1
2148 * set down layer 3 without sending any message
2150 pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
2152 ni1_release_l3_process(pc);
2154 pc->st->l3.l3l4(pc->st, CC_IGNORE | INDICATION, pc);
2159 l3ni1_dummy(struct l3_process *pc, u_char pr, void *arg)
2164 l3ni1_t302(struct l3_process *pc, u_char pr, void *arg)
2166 L3DelTimer(&pc->timer);
2168 pc->para.cause = 28; /* invalid number */
2169 l3ni1_disconnect_req(pc, pr, NULL);
2170 pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
2174 l3ni1_t303(struct l3_process *pc, u_char pr, void *arg)
2178 L3DelTimer(&pc->timer);
2179 l3ni1_setup_req(pc, pr, arg);
2181 L3DelTimer(&pc->timer);
2182 l3ni1_message_cause(pc, MT_RELEASE_COMPLETE, 102);
2183 pc->st->l3.l3l4(pc->st, CC_NOSETUP_RSP, pc);
2184 ni1_release_l3_process(pc);
2189 l3ni1_t304(struct l3_process *pc, u_char pr, void *arg)
2191 L3DelTimer(&pc->timer);
2193 pc->para.cause = 102;
2194 l3ni1_disconnect_req(pc, pr, NULL);
2195 pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
2200 l3ni1_t305(struct l3_process *pc, u_char pr, void *arg)
2205 struct sk_buff *skb;
2208 L3DelTimer(&pc->timer);
2209 if (pc->para.cause != NO_CAUSE)
2210 cause = pc->para.cause;
2212 MsgHead(p, pc->callref, MT_RELEASE);
2217 *p++ = cause | 0x80;
2220 if (!(skb = l3_alloc_skb(l)))
2222 memcpy(skb_put(skb, l), tmp, l);
2224 l3_msg(pc->st, DL_DATA | REQUEST, skb);
2225 L3AddTimer(&pc->timer, T308, CC_T308_1);
2229 l3ni1_t310(struct l3_process *pc, u_char pr, void *arg)
2231 L3DelTimer(&pc->timer);
2233 pc->para.cause = 102;
2234 l3ni1_disconnect_req(pc, pr, NULL);
2235 pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
2239 l3ni1_t313(struct l3_process *pc, u_char pr, void *arg)
2241 L3DelTimer(&pc->timer);
2243 pc->para.cause = 102;
2244 l3ni1_disconnect_req(pc, pr, NULL);
2245 pc->st->l3.l3l4(pc->st, CC_CONNECT_ERR, pc);
2249 l3ni1_t308_1(struct l3_process *pc, u_char pr, void *arg)
2252 L3DelTimer(&pc->timer);
2253 l3ni1_message(pc, MT_RELEASE);
2254 L3AddTimer(&pc->timer, T308, CC_T308_2);
2258 l3ni1_t308_2(struct l3_process *pc, u_char pr, void *arg)
2260 L3DelTimer(&pc->timer);
2261 pc->st->l3.l3l4(pc->st, CC_RELEASE_ERR, pc);
2262 ni1_release_l3_process(pc);
2266 l3ni1_t318(struct l3_process *pc, u_char pr, void *arg)
2268 L3DelTimer(&pc->timer);
2269 pc->para.cause = 102; /* Timer expiry */
2270 pc->para.loc = 0; /* local */
2271 pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc);
2273 l3ni1_message(pc, MT_RELEASE);
2274 L3AddTimer(&pc->timer, T308, CC_T308_1);
2278 l3ni1_t319(struct l3_process *pc, u_char pr, void *arg)
2280 L3DelTimer(&pc->timer);
2281 pc->para.cause = 102; /* Timer expiry */
2282 pc->para.loc = 0; /* local */
2283 pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc);
2288 l3ni1_restart(struct l3_process *pc, u_char pr, void *arg)
2290 L3DelTimer(&pc->timer);
2291 pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
2292 ni1_release_l3_process(pc);
2296 l3ni1_status(struct l3_process *pc, u_char pr, void *arg)
2299 struct sk_buff *skb = arg;
2301 u_char cause = 0, callState = 0;
2303 if ((ret = l3ni1_get_cause(pc, skb))) {
2304 if (pc->debug & L3_DEB_WARN)
2305 l3_debug(pc->st, "STATUS get_cause ret(%d)", ret);
2311 if ((p = findie(skb->data, skb->len, IE_CALL_STATE, 0))) {
2315 if (!ie_in_set(pc, *p, l3_valid_states))
2321 if (!cause) { /* no error before */
2322 ret = check_infoelements(pc, skb, ie_STATUS);
2323 if (ERR_IE_COMPREHENSION == ret)
2325 else if (ERR_IE_UNRECOGNIZED == ret)
2331 if (pc->debug & L3_DEB_WARN)
2332 l3_debug(pc->st, "STATUS error(%d/%d)", ret, cause);
2333 tmp = pc->para.cause;
2334 pc->para.cause = cause;
2335 l3ni1_status_send(pc, 0, NULL);
2337 pc->para.cause = tmp;
2341 cause = pc->para.cause;
2342 if (((cause & 0x7f) == 111) && (callState == 0)) {
2343 /* ETS 300-104 7.6.1, 8.6.1, 10.6.1...
2344 * if received MT_STATUS with cause == 111 and call
2345 * state == 0, then we must set down layer 3
2347 pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
2349 ni1_release_l3_process(pc);
2354 l3ni1_facility(struct l3_process *pc, u_char pr, void *arg)
2356 struct sk_buff *skb = arg;
2359 ret = check_infoelements(pc, skb, ie_FACILITY);
2360 l3ni1_std_ie_err(pc, ret);
2363 if ((p = findie(skb->data, skb->len, IE_FACILITY, 0)))
2364 l3ni1_parse_facility(pc->st, pc, pc->callref, p);
2369 l3ni1_suspend_req(struct l3_process *pc, u_char pr, void *arg)
2371 struct sk_buff *skb;
2375 u_char *msg = pc->chan->setup.phone;
2377 MsgHead(p, pc->callref, MT_SUSPEND);
2379 if (l && (l <= 10)) { /* Max length 10 octets */
2382 for (i = 0; i < l; i++)
2385 l3_debug(pc->st, "SUS wrong CALL_ID len %d", l);
2389 if (!(skb = l3_alloc_skb(l)))
2391 memcpy(skb_put(skb, l), tmp, l);
2392 l3_msg(pc->st, DL_DATA | REQUEST, skb);
2394 L3AddTimer(&pc->timer, T319, CC_T319);
2398 l3ni1_suspend_ack(struct l3_process *pc, u_char pr, void *arg)
2400 struct sk_buff *skb = arg;
2403 L3DelTimer(&pc->timer);
2405 pc->para.cause = NO_CAUSE;
2406 pc->st->l3.l3l4(pc->st, CC_SUSPEND | CONFIRM, pc);
2407 /* We don't handle suspend_ack for IE errors now */
2408 if ((ret = check_infoelements(pc, skb, ie_SUSPEND_ACKNOWLEDGE)))
2409 if (pc->debug & L3_DEB_WARN)
2410 l3_debug(pc->st, "SUSPACK check ie(%d)", ret);
2411 ni1_release_l3_process(pc);
2415 l3ni1_suspend_rej(struct l3_process *pc, u_char pr, void *arg)
2417 struct sk_buff *skb = arg;
2420 if ((ret = l3ni1_get_cause(pc, skb))) {
2421 if (pc->debug & L3_DEB_WARN)
2422 l3_debug(pc->st, "SUSP_REJ get_cause ret(%d)", ret);
2424 pc->para.cause = 96;
2426 pc->para.cause = 100;
2427 l3ni1_status_send(pc, pr, NULL);
2430 ret = check_infoelements(pc, skb, ie_SUSPEND_REJECT);
2431 if (ERR_IE_COMPREHENSION == ret) {
2432 l3ni1_std_ie_err(pc, ret);
2435 L3DelTimer(&pc->timer);
2436 pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc);
2438 if (ret) /* STATUS for none mandatory IE errors after actions are taken */
2439 l3ni1_std_ie_err(pc, ret);
2443 l3ni1_resume_req(struct l3_process *pc, u_char pr, void *arg)
2445 struct sk_buff *skb;
2449 u_char *msg = pc->para.setup.phone;
2451 MsgHead(p, pc->callref, MT_RESUME);
2454 if (l && (l <= 10)) { /* Max length 10 octets */
2457 for (i = 0; i < l; i++)
2460 l3_debug(pc->st, "RES wrong CALL_ID len %d", l);
2464 if (!(skb = l3_alloc_skb(l)))
2466 memcpy(skb_put(skb, l), tmp, l);
2467 l3_msg(pc->st, DL_DATA | REQUEST, skb);
2469 L3AddTimer(&pc->timer, T318, CC_T318);
2473 l3ni1_resume_ack(struct l3_process *pc, u_char pr, void *arg)
2475 struct sk_buff *skb = arg;
2478 if ((id = l3ni1_get_channel_id(pc, skb)) > 0) {
2479 if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) {
2480 if (pc->debug & L3_DEB_WARN)
2481 l3_debug(pc->st, "resume ack with wrong chid %x", id);
2482 pc->para.cause = 100;
2483 l3ni1_status_send(pc, pr, NULL);
2486 pc->para.bchannel = id;
2487 } else if (1 == pc->state) {
2488 if (pc->debug & L3_DEB_WARN)
2489 l3_debug(pc->st, "resume ack without chid (ret %d)", id);
2490 pc->para.cause = 96;
2491 l3ni1_status_send(pc, pr, NULL);
2494 ret = check_infoelements(pc, skb, ie_RESUME_ACKNOWLEDGE);
2495 if (ERR_IE_COMPREHENSION == ret) {
2496 l3ni1_std_ie_err(pc, ret);
2499 L3DelTimer(&pc->timer);
2500 pc->st->l3.l3l4(pc->st, CC_RESUME | CONFIRM, pc);
2502 if (ret) /* STATUS for none mandatory IE errors after actions are taken */
2503 l3ni1_std_ie_err(pc, ret);
2507 l3ni1_resume_rej(struct l3_process *pc, u_char pr, void *arg)
2509 struct sk_buff *skb = arg;
2512 if ((ret = l3ni1_get_cause(pc, skb))) {
2513 if (pc->debug & L3_DEB_WARN)
2514 l3_debug(pc->st, "RES_REJ get_cause ret(%d)", ret);
2516 pc->para.cause = 96;
2518 pc->para.cause = 100;
2519 l3ni1_status_send(pc, pr, NULL);
2522 ret = check_infoelements(pc, skb, ie_RESUME_REJECT);
2523 if (ERR_IE_COMPREHENSION == ret) {
2524 l3ni1_std_ie_err(pc, ret);
2527 L3DelTimer(&pc->timer);
2528 pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc);
2530 if (ret) /* STATUS for none mandatory IE errors after actions are taken */
2531 l3ni1_std_ie_err(pc, ret);
2532 ni1_release_l3_process(pc);
2536 l3ni1_global_restart(struct l3_process *pc, u_char pr, void *arg)
2540 u_char ri, ch = 0, chan = 0;
2542 struct sk_buff *skb = arg;
2543 struct l3_process *up;
2546 L3DelTimer(&pc->timer);
2548 if ((p = findie(p, skb->len, IE_RESTART_IND, 0))) {
2550 l3_debug(pc->st, "Restart %x", ri);
2552 l3_debug(pc->st, "Restart without restart IE");
2556 if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) {
2559 if (pc->st->l3.debug)
2560 l3_debug(pc->st, "Restart for channel %d", chan);
2563 up = pc->st->l3.proc;
2566 up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);
2567 else if (up->para.bchannel == chan)
2568 up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);
2573 MsgHead(p, pc->callref, MT_RESTART_ACKNOWLEDGE);
2575 *p++ = IE_CHANNEL_ID;
2579 *p++ = 0x79; /* RESTART Ind */
2583 if (!(skb = l3_alloc_skb(l)))
2585 memcpy(skb_put(skb, l), tmp, l);
2587 l3_msg(pc->st, DL_DATA | REQUEST, skb);
2591 l3ni1_dl_reset(struct l3_process *pc, u_char pr, void *arg)
2593 pc->para.cause = 0x29; /* Temporary failure */
2595 l3ni1_disconnect_req(pc, pr, NULL);
2596 pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
2600 l3ni1_dl_release(struct l3_process *pc, u_char pr, void *arg)
2603 pc->para.cause = 0x1b; /* Destination out of order */
2605 pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
2606 release_l3_process(pc);
2610 l3ni1_dl_reestablish(struct l3_process *pc, u_char pr, void *arg)
2612 L3DelTimer(&pc->timer);
2613 L3AddTimer(&pc->timer, T309, CC_T309);
2614 l3_msg(pc->st, DL_ESTABLISH | REQUEST, NULL);
2618 l3ni1_dl_reest_status(struct l3_process *pc, u_char pr, void *arg)
2620 L3DelTimer(&pc->timer);
2622 pc->para.cause = 0x1F; /* normal, unspecified */
2623 l3ni1_status_send(pc, 0, NULL);
2626 static void l3ni1_SendSpid(struct l3_process *pc, u_char pr, struct sk_buff *skb, int iNewState)
2630 struct Channel *pChan = pc->st->lli.userdata;
2636 if (!(pSPID = strchr(pChan->setup.eazmsn, ':')))
2638 printk(KERN_ERR "SPID not supplied in EAZMSN %s\n", pChan->setup.eazmsn);
2640 pc->st->l3.l3l2(pc->st, DL_RELEASE | REQUEST, NULL);
2644 l = strlen(++pSPID);
2645 if (!(skb = l3_alloc_skb(5 + l)))
2647 printk(KERN_ERR "HiSax can't get memory to send SPID\n");
2651 p = skb_put(skb, 5);
2652 *p++ = PROTO_DIS_EURO;
2654 *p++ = MT_INFORMATION;
2658 memcpy(skb_put(skb, l), pSPID, l);
2660 newl3state(pc, iNewState);
2662 L3DelTimer(&pc->timer);
2663 L3AddTimer(&pc->timer, TSPID, CC_TSPID);
2665 pc->st->l3.l3l2(pc->st, DL_DATA | REQUEST, skb);
2668 static void l3ni1_spid_send(struct l3_process *pc, u_char pr, void *arg)
2670 l3ni1_SendSpid(pc, pr, arg, 20);
2673 static void l3ni1_spid_epid(struct l3_process *pc, u_char pr, void *arg)
2675 struct sk_buff *skb = arg;
2677 if (skb->data[1] == 0)
2678 if (skb->data[3] == IE_ENDPOINT_ID)
2680 L3DelTimer(&pc->timer);
2682 l3_msg(pc->st, DL_ESTABLISH | CONFIRM, NULL);
2687 static void l3ni1_spid_tout(struct l3_process *pc, u_char pr, void *arg)
2690 l3ni1_SendSpid(pc, pr, arg, pc->state + 1);
2693 L3DelTimer(&pc->timer);
2696 printk(KERN_ERR "SPID not accepted\n");
2698 pc->st->l3.l3l2(pc->st, DL_RELEASE | REQUEST, NULL);
2703 static struct stateentry downstatelist[] =
2706 CC_SETUP | REQUEST, l3ni1_setup_req},
2708 CC_RESUME | REQUEST, l3ni1_resume_req},
2709 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(25),
2710 CC_DISCONNECT | REQUEST, l3ni1_disconnect_req},
2712 CC_RELEASE | REQUEST, l3ni1_release_req},
2714 CC_RESTART | REQUEST, l3ni1_restart},
2715 {SBIT(6) | SBIT(25),
2716 CC_IGNORE | REQUEST, l3ni1_reset},
2717 {SBIT(6) | SBIT(25),
2718 CC_REJECT | REQUEST, l3ni1_reject_req},
2719 {SBIT(6) | SBIT(25),
2720 CC_PROCEED_SEND | REQUEST, l3ni1_proceed_req},
2722 CC_MORE_INFO | REQUEST, l3ni1_setup_ack_req},
2724 CC_MORE_INFO | REQUEST, l3ni1_dummy},
2725 {SBIT(6) | SBIT(9) | SBIT(25),
2726 CC_ALERTING | REQUEST, l3ni1_alert_req},
2727 {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
2728 CC_SETUP | RESPONSE, l3ni1_setup_rsp},
2730 CC_SUSPEND | REQUEST, l3ni1_suspend_req},
2731 {SBIT(7) | SBIT(9) | SBIT(25),
2732 CC_REDIR | REQUEST, l3ni1_redir_req},
2734 CC_REDIR | REQUEST, l3ni1_redir_req_early},
2735 {SBIT(9) | SBIT(25),
2736 CC_DISCONNECT | REQUEST, l3ni1_disconnect_req},
2738 CC_T302, l3ni1_t302},
2740 CC_T303, l3ni1_t303},
2742 CC_T304, l3ni1_t304},
2744 CC_T310, l3ni1_t310},
2746 CC_T313, l3ni1_t313},
2748 CC_T305, l3ni1_t305},
2750 CC_T319, l3ni1_t319},
2752 CC_T318, l3ni1_t318},
2754 CC_T308_1, l3ni1_t308_1},
2756 CC_T308_2, l3ni1_t308_2},
2758 CC_T309, l3ni1_dl_release},
2759 { SBIT(20) | SBIT(21) | SBIT(22),
2760 CC_TSPID, l3ni1_spid_tout },
2763 static struct stateentry datastatelist[] =
2766 MT_STATUS_ENQUIRY, l3ni1_status_enq},
2768 MT_FACILITY, l3ni1_facility},
2770 MT_STATUS, l3ni1_release_ind},
2772 MT_STATUS, l3ni1_status},
2774 MT_SETUP, l3ni1_setup},
2775 {SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(11) | SBIT(12) |
2776 SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25),
2777 MT_SETUP, l3ni1_dummy},
2779 MT_CALL_PROCEEDING, l3ni1_call_proc},
2781 MT_SETUP_ACKNOWLEDGE, l3ni1_setup_ack},
2783 MT_ALERTING, l3ni1_alerting},
2785 MT_PROGRESS, l3ni1_progress},
2786 {SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) |
2787 SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25),
2788 MT_INFORMATION, l3ni1_information},
2789 {SBIT(10) | SBIT(11) | SBIT(15),
2790 MT_NOTIFY, l3ni1_notify},
2791 {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) |
2792 SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25),
2793 MT_RELEASE_COMPLETE, l3ni1_release_cmpl},
2794 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(25),
2795 MT_RELEASE, l3ni1_release},
2796 {SBIT(19), MT_RELEASE, l3ni1_release_ind},
2797 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(11) | SBIT(15) | SBIT(17) | SBIT(25),
2798 MT_DISCONNECT, l3ni1_disconnect},
2800 MT_DISCONNECT, l3ni1_dummy},
2801 {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4),
2802 MT_CONNECT, l3ni1_connect},
2804 MT_CONNECT_ACKNOWLEDGE, l3ni1_connect_ack},
2806 MT_SUSPEND_ACKNOWLEDGE, l3ni1_suspend_ack},
2808 MT_SUSPEND_REJECT, l3ni1_suspend_rej},
2810 MT_RESUME_ACKNOWLEDGE, l3ni1_resume_ack},
2812 MT_RESUME_REJECT, l3ni1_resume_rej},
2815 static struct stateentry globalmes_list[] =
2818 MT_STATUS, l3ni1_status},
2820 MT_RESTART, l3ni1_global_restart},
2822 MT_RESTART_ACKNOWLEDGE, l3ni1_restart_ack},
2824 { SBIT(0), MT_DL_ESTABLISHED, l3ni1_spid_send },
2825 { SBIT(20) | SBIT(21) | SBIT(22), MT_INFORMATION, l3ni1_spid_epid },
2828 static struct stateentry manstatelist[] =
2831 DL_ESTABLISH | INDICATION, l3ni1_dl_reset},
2833 DL_ESTABLISH | CONFIRM, l3ni1_dl_reest_status},
2835 DL_RELEASE | INDICATION, l3ni1_dl_reestablish},
2837 DL_RELEASE | INDICATION, l3ni1_dl_release},
2844 global_handler(struct PStack *st, int mt, struct sk_buff *skb)
2850 struct l3_process *proc = st->l3.global;
2853 proc->callref = skb->data[2]; /* cr flag */
2856 for (i = 0; i < ARRAY_SIZE(globalmes_list); i++)
2857 if ((mt == globalmes_list[i].primitive) &&
2858 ((1 << proc->state) & globalmes_list[i].state))
2860 if (i == ARRAY_SIZE(globalmes_list)) {
2861 if (st->l3.debug & L3_DEB_STATE) {
2862 l3_debug(st, "ni1 global state %d mt %x unhandled",
2865 MsgHead(p, proc->callref, MT_STATUS);
2869 *p++ = 81 | 0x80; /* invalid cr */
2870 *p++ = 0x14; /* CallState */
2872 *p++ = proc->state & 0x3f;
2874 if (!(skb = l3_alloc_skb(l)))
2876 memcpy(skb_put(skb, l), tmp, l);
2877 l3_msg(proc->st, DL_DATA | REQUEST, skb);
2879 if (st->l3.debug & L3_DEB_STATE) {
2880 l3_debug(st, "ni1 global %d mt %x",
2883 globalmes_list[i].rout(proc, mt, skb);
2888 ni1up(struct PStack *st, int pr, void *arg)
2890 int i, mt, cr, callState;
2893 struct sk_buff *skb = arg;
2894 struct l3_process *proc;
2897 case (DL_DATA | INDICATION):
2898 case (DL_UNIT_DATA | INDICATION):
2900 case (DL_ESTABLISH | INDICATION):
2901 case (DL_RELEASE | INDICATION):
2902 case (DL_RELEASE | CONFIRM):
2903 l3_msg(st, pr, arg);
2907 case (DL_ESTABLISH | CONFIRM):
2908 global_handler(st, MT_DL_ESTABLISHED, NULL);
2912 printk(KERN_ERR "HiSax ni1up unknown pr=%04x\n", pr);
2916 l3_debug(st, "ni1up frame too short(%d)", skb->len);
2921 if (skb->data[0] != PROTO_DIS_EURO) {
2922 if (st->l3.debug & L3_DEB_PROTERR) {
2923 l3_debug(st, "ni1up%sunexpected discriminator %x message len %d",
2924 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
2925 skb->data[0], skb->len);
2930 cr = getcallref(skb->data);
2931 if (skb->len < ((skb->data[1] & 0x0f) + 3)) {
2932 l3_debug(st, "ni1up frame too short(%d)", skb->len);
2936 mt = skb->data[skb->data[1] + 2];
2937 if (st->l3.debug & L3_DEB_STATE)
2938 l3_debug(st, "ni1up cr %d", cr);
2939 if (cr == -2) { /* wrong Callref */
2940 if (st->l3.debug & L3_DEB_WARN)
2941 l3_debug(st, "ni1up wrong Callref");
2944 } else if (cr == -1) { /* Dummy Callref */
2945 if (mt == MT_FACILITY)
2947 if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) {
2948 l3ni1_parse_facility(st, NULL,
2949 (pr == (DL_DATA | INDICATION)) ? -1 : -2, p);
2956 global_handler(st, mt, skb);
2960 if (st->l3.debug & L3_DEB_WARN)
2961 l3_debug(st, "ni1up dummy Callref (no facility msg or ie)");
2964 } else if ((((skb->data[1] & 0x0f) == 1) && (0 == (cr & 0x7f))) ||
2965 (((skb->data[1] & 0x0f) == 2) && (0 == (cr & 0x7fff)))) { /* Global CallRef */
2966 if (st->l3.debug & L3_DEB_STATE)
2967 l3_debug(st, "ni1up Global CallRef");
2968 global_handler(st, mt, skb);
2971 } else if (!(proc = getl3proc(st, cr))) {
2972 /* No transaction process exist, that means no call with
2973 * this callreference is active
2975 if (mt == MT_SETUP) {
2976 /* Setup creates a new transaction process */
2977 if (skb->data[2] & 0x80) {
2978 /* Setup with wrong CREF flag */
2979 if (st->l3.debug & L3_DEB_STATE)
2980 l3_debug(st, "ni1up wrong CRef flag");
2984 if (!(proc = ni1_new_l3_process(st, cr))) {
2985 /* May be to answer with RELEASE_COMPLETE and
2986 * CAUSE 0x2f "Resource unavailable", but this
2987 * need a new_l3_process too ... arghh
2992 } else if (mt == MT_STATUS) {
2993 if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
2999 if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) {
3005 /* ETS 300-104 part 2.4.1
3006 * if setup has not been made and a message type
3007 * MT_STATUS is received with call state == 0,
3008 * we must send nothing
3010 if (callState != 0) {
3011 /* ETS 300-104 part 2.4.2
3012 * if setup has not been made and a message type
3013 * MT_STATUS is received with call state != 0,
3014 * we must send MT_RELEASE_COMPLETE cause 101
3016 if ((proc = ni1_new_l3_process(st, cr))) {
3017 proc->para.cause = 101;
3018 l3ni1_msg_without_setup(proc, 0, NULL);
3023 } else if (mt == MT_RELEASE_COMPLETE) {
3027 /* ETS 300-104 part 2
3028 * if setup has not been made and a message type
3029 * (except MT_SETUP and RELEASE_COMPLETE) is received,
3030 * we must send MT_RELEASE_COMPLETE cause 81 */
3032 if ((proc = ni1_new_l3_process(st, cr))) {
3033 proc->para.cause = 81;
3034 l3ni1_msg_without_setup(proc, 0, NULL);
3039 if (l3ni1_check_messagetype_validity(proc, mt, skb)) {
3043 if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL)
3044 l3ni1_deliver_display(proc, pr, p); /* Display IE included */
3045 for (i = 0; i < ARRAY_SIZE(datastatelist); i++)
3046 if ((mt == datastatelist[i].primitive) &&
3047 ((1 << proc->state) & datastatelist[i].state))
3049 if (i == ARRAY_SIZE(datastatelist)) {
3050 if (st->l3.debug & L3_DEB_STATE) {
3051 l3_debug(st, "ni1up%sstate %d mt %#x unhandled",
3052 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
3055 if ((MT_RELEASE_COMPLETE != mt) && (MT_RELEASE != mt)) {
3056 proc->para.cause = 101;
3057 l3ni1_status_send(proc, pr, skb);
3060 if (st->l3.debug & L3_DEB_STATE) {
3061 l3_debug(st, "ni1up%sstate %d mt %x",
3062 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
3065 datastatelist[i].rout(proc, pr, skb);
3072 ni1down(struct PStack *st, int pr, void *arg)
3075 struct l3_process *proc;
3076 struct Channel *chan;
3078 if ((DL_ESTABLISH | REQUEST) == pr) {
3079 l3_msg(st, pr, NULL);
3081 } else if (((CC_SETUP | REQUEST) == pr) || ((CC_RESUME | REQUEST) == pr)) {
3085 if ((proc = ni1_new_l3_process(st, cr))) {
3088 memcpy(&proc->para.setup, &chan->setup, sizeof(setup_parm));
3095 printk(KERN_ERR "HiSax ni1down without proc pr=%04x\n", pr);
3099 if (pr == (CC_TNI1_IO | REQUEST)) {
3100 l3ni1_io_timer(proc); /* timer expires */
3104 for (i = 0; i < ARRAY_SIZE(downstatelist); i++)
3105 if ((pr == downstatelist[i].primitive) &&
3106 ((1 << proc->state) & downstatelist[i].state))
3108 if (i == ARRAY_SIZE(downstatelist)) {
3109 if (st->l3.debug & L3_DEB_STATE) {
3110 l3_debug(st, "ni1down state %d prim %#x unhandled",
3114 if (st->l3.debug & L3_DEB_STATE) {
3115 l3_debug(st, "ni1down state %d prim %#x",
3118 downstatelist[i].rout(proc, pr, arg);
3123 ni1man(struct PStack *st, int pr, void *arg)
3126 struct l3_process *proc = arg;
3129 printk(KERN_ERR "HiSax ni1man without proc pr=%04x\n", pr);
3132 for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
3133 if ((pr == manstatelist[i].primitive) &&
3134 ((1 << proc->state) & manstatelist[i].state))
3136 if (i == ARRAY_SIZE(manstatelist)) {
3137 if (st->l3.debug & L3_DEB_STATE) {
3138 l3_debug(st, "cr %d ni1man state %d prim %#x unhandled",
3139 proc->callref & 0x7f, proc->state, pr);
3142 if (st->l3.debug & L3_DEB_STATE) {
3143 l3_debug(st, "cr %d ni1man state %d prim %#x",
3144 proc->callref & 0x7f, proc->state, pr);
3146 manstatelist[i].rout(proc, pr, arg);
3151 setstack_ni1(struct PStack *st)
3156 st->lli.l4l3 = ni1down;
3157 st->lli.l4l3_proto = l3ni1_cmd_global;
3158 st->l2.l2l3 = ni1up;
3159 st->l3.l3ml3 = ni1man;
3161 st->prot.ni1.last_invoke_id = 0;
3162 st->prot.ni1.invoke_used[0] = 1; /* Bit 0 must always be set to 1 */
3165 st->prot.ni1.invoke_used[i++] = 0;
3167 if (!(st->l3.global = kmalloc(sizeof(struct l3_process), GFP_ATOMIC))) {
3168 printk(KERN_ERR "HiSax can't get memory for ni1 global CR\n");
3170 st->l3.global->state = 0;
3171 st->l3.global->callref = 0;
3172 st->l3.global->next = NULL;
3173 st->l3.global->debug = L3_DEB_WARN;
3174 st->l3.global->st = st;
3175 st->l3.global->N303 = 1;
3176 st->l3.global->prot.ni1.invoke_id = 0;
3178 L3InitTimer(st->l3.global, &st->l3.global->timer);
3180 strcpy(tmp, ni1_revision);
3181 printk(KERN_INFO "HiSax: National ISDN-1 Rev. %s\n", HiSax_getrev(tmp));