25 #include <linux/ctype.h>
26 #include <linux/slab.h>
29 static const char *dss1_revision =
"$Revision: 2.32.2.3 $";
31 #define EXT_BEARER_CAPS 1
33 #define MsgHead(ptr, cref, mty) \
48 static unsigned char new_invoke_id(
struct PStack *
p)
55 retval = p->prot.dss1.last_invoke_id + 1;
56 while ((i) && (p->prot.dss1.invoke_used[retval >> 3] == 0xFF)) {
57 p->prot.dss1.last_invoke_id = (retval & 0xF8) + 8;
61 while (p->prot.dss1.invoke_used[retval >> 3] & (1 << (retval & 7)))
65 p->prot.dss1.last_invoke_id =
retval;
66 p->prot.dss1.invoke_used[retval >> 3] |= (1 << (retval & 7));
73 static void free_invoke_id(
struct PStack *
p,
unsigned char id)
78 p->prot.dss1.invoke_used[
id >> 3] &= ~(1 << (
id & 7));
85 static struct l3_process
86 *dss1_new_l3_process(
struct PStack *
st,
int cr)
87 {
struct l3_process *proc;
92 proc->prot.dss1.invoke_id = 0;
93 proc->prot.dss1.remote_operation = 0;
94 proc->prot.dss1.uus1_data[0] =
'\0';
103 dss1_release_l3_process(
struct l3_process *p)
105 free_invoke_id(p->st, p->prot.dss1.invoke_id);
112 static struct l3_process *
113 l3dss1_search_dummy_proc(
struct PStack *st,
int id)
114 {
struct l3_process *
pc = st->l3.proc;
116 if (!
id)
return (
NULL);
119 {
if ((pc->callref == -1) && (pc->prot.dss1.invoke_id ==
id))
131 l3dss1_dummy_return_result(
struct PStack *st,
int id,
u_char *p,
u_char nlen)
133 struct IsdnCardState *
cs;
134 struct l3_process *pc =
NULL;
136 if ((pc = l3dss1_search_dummy_proc(st,
id)))
139 cs = pc->st->l1.hardware;
143 ic.
parm.dss1_io.hl_id = pc->prot.dss1.invoke_id;
144 ic.
parm.dss1_io.ll_id = pc->prot.dss1.ll_id;
145 ic.
parm.dss1_io.proc = pc->prot.dss1.proc;
146 ic.
parm.dss1_io.timeout = 0;
147 ic.
parm.dss1_io.datalen = nlen;
148 ic.
parm.dss1_io.data =
p;
149 free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
150 pc->prot.dss1.invoke_id = 0;
152 cs->iif.statcallb(&ic);
153 dss1_release_l3_process(pc);
156 l3_debug(st,
"dummy return result id=0x%x result len=%d",
id, nlen);
164 l3dss1_dummy_error_return(
struct PStack *st,
int id,
ulong error)
166 struct IsdnCardState *
cs;
167 struct l3_process *pc =
NULL;
169 if ((pc = l3dss1_search_dummy_proc(st,
id)))
172 cs = pc->st->l1.hardware;
176 ic.
parm.dss1_io.hl_id = pc->prot.dss1.invoke_id;
177 ic.
parm.dss1_io.ll_id = pc->prot.dss1.ll_id;
178 ic.
parm.dss1_io.proc = pc->prot.dss1.proc;
180 ic.
parm.dss1_io.datalen = 0;
182 free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
183 pc->prot.dss1.invoke_id = 0;
185 cs->iif.statcallb(&ic);
186 dss1_release_l3_process(pc);
189 l3_debug(st,
"dummy return error id=0x%x error=0x%lx",
id, error);
197 l3dss1_dummy_invoke(
struct PStack *st,
int cr,
int id,
200 struct IsdnCardState *
cs;
202 l3_debug(st,
"dummy invoke %s id=0x%x ident=0x%x datalen=%d",
203 (cr == -1) ?
"local" :
"broadcast",
id, ident, nlen);
204 if (cr >= -1)
return;
206 cs = st->l1.hardware;
210 ic.
parm.dss1_io.hl_id =
id;
211 ic.
parm.dss1_io.ll_id = 0;
213 ic.
parm.dss1_io.timeout = 0;
214 ic.
parm.dss1_io.datalen = nlen;
215 ic.
parm.dss1_io.data =
p;
217 cs->iif.statcallb(&ic);
221 l3dss1_parse_facility(
struct PStack *st,
struct l3_process *pc,
225 unsigned char nlen = 0, ilen, cp_tag;
232 if ((!st) || (cr >= 0))
return;
240 if ((*p & 0x1F) != 0x11) {
241 l3_debug(st,
"supplementary service != 0x11");
244 while (qd_len > 0 && !(*p & 0x80)) {
254 if ((*p & 0xE0) != 0xA0) {
255 l3_debug(st,
"class and form != 0xA0");
270 if ((qd_len-- < ((!nlen) ? 3 : (1 + nlen))) ||
272 {
l3_debug(st,
"length format error or not implemented");
281 if ((*(p + qd_len)) || (*(p + qd_len + 1)))
282 {
l3_debug(st,
"length format indefinite error");
304 l3_debug(st,
"invoke identifier tag !=0x02");
311 l3_debug(st,
"invoke id length format 2");
316 if (ilen > nlen || ilen == 0)
317 {
l3_debug(st,
"ilen > nlen || ilen == 0");
323 {
id = (
id << 8) | (*p++ & 0xFF);
334 l3_debug(st,
"operation value !=0x02");
341 if (ilen > nlen || ilen == 0) {
342 l3_debug(st,
"ilen > nlen || ilen == 0 22");
348 ident = (ident << 8) | (*p++ & 0xFF);
353 { l3dss1_dummy_invoke(st, cr,
id, ident, p, nlen);
359 #define FOO1(s, a, b) \
362 if (nlen < ilen + 2) { \
363 l3_debug(st, "FOO1 nlen < ilen+2"); \
367 if ((*p & 0xFF) == (a)) { \
378 FOO1(
"1A", 0x30, FOO1(
"1C", 0xA1, FOO1(
"1D", 0x30, FOO1(
"1E", 0x02, ( {
380 nlen = (nlen) ? nlen : 0;
382 ident = (ident << 8) | *p++;
385 if (ident > pc->para.chargeinfo) {
386 pc->para.chargeinfo = ident;
391 l3_debug(st,
"charging info during %d", pc->para.chargeinfo);
394 l3_debug(st,
"charging info final %d", pc->para.chargeinfo);
401 FOO1(
"2A", 0x30, FOO1(
"2B", 0x30, FOO1(
"2C", 0xA1, FOO1(
"2D", 0x30, FOO1(
"2E", 0x02, ( {
403 nlen = (nlen) ? nlen : 0;
405 ident = (ident << 8) | *p++;
408 if (ident > pc->para.chargeinfo) {
409 pc->para.chargeinfo = ident;
413 l3_debug(st,
"charging info final %d", pc->para.chargeinfo);
433 l3dss1_dummy_return_result(st,
id, p, nlen);
436 if ((pc->prot.dss1.invoke_id) && (pc->prot.dss1.invoke_id ==
id))
438 free_invoke_id(st, pc->prot.dss1.invoke_id);
439 pc->prot.dss1.remote_result = 0;
440 pc->prot.dss1.invoke_id = 0;
441 pc->redir_result = pc->prot.dss1.remote_result;
444 l3_debug(st,
"return error unknown identifier");
449 {
l3_debug(st,
"return error nlen < 2");
454 l3_debug(st,
"invoke error tag !=0x02");
461 l3_debug(st,
"invoke return errlen > 4 ");
466 if (ilen > nlen || ilen == 0)
467 {
l3_debug(st,
"error return ilen > nlen || ilen == 0");
472 { err_ret = (err_ret << 8) | (*p++ & 0xFF);
478 l3dss1_dummy_error_return(st,
id, err_ret);
481 if ((pc->prot.dss1.invoke_id) && (pc->prot.dss1.invoke_id ==
id))
483 free_invoke_id(st, pc->prot.dss1.invoke_id);
484 pc->prot.dss1.remote_result = err_ret;
485 pc->prot.dss1.invoke_id = 0;
486 pc->redir_result = pc->prot.dss1.remote_result;
490 l3_debug(st,
"return result unknown identifier");
493 l3_debug(st,
"facility default break tag=0x%02x", cp_tag);
499 l3dss1_message(
struct l3_process *pc,
u_char mt)
533 l3dss1_status_send(
struct l3_process *pc,
u_char pr,
void *
arg)
545 *p++ = pc->para.cause | 0x80;
549 *p++ = pc->state & 0x3f;
559 l3dss1_msg_without_setup(
struct l3_process *pc,
u_char pr,
void *arg)
570 switch (pc->para.cause) {
580 *p++ = pc->para.cause | 0x80;
583 printk(
KERN_ERR "HiSax l3dss1_msg_without_setup wrong cause %d\n",
592 dss1_release_l3_process(pc);
628 static int ie_STATUS_ENQUIRY[] = {
IE_DISPLAY, -1};
639 static int comp_required[] = {1, 2, 3, 5, 6, 7, 9, 10, 11, 14, 15, -1};
640 static int l3_valid_states[] = {0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 15, 17, 19, 25, -1};
648 struct ie_len max_ie_len[] = {
687 while (max_ie_len[i].ie != -1) {
688 if (max_ie_len[i].ie == ie)
689 return (max_ie_len[i].
len);
696 ie_in_set(
struct l3_process *pc,
u_char ie,
int *checklist) {
699 while (*checklist != -1) {
700 if ((*checklist & 0xff) == ie) {
713 check_infoelements(
struct l3_process *pc,
struct sk_buff *skb,
int *checklist)
718 int l, newpos, oldpos;
719 int err_seq = 0, err_len = 0, err_compr = 0, err_ureg = 0;
731 while ((p - skb->
data) < skb->
len) {
732 if ((*p & 0xf0) == 0x90) {
733 old_codeset = codeset;
740 l3_debug(pc->st,
"check IE shift%scodeset %d->%d",
741 codelock ?
" locking " :
" ", old_codeset, codeset);
746 if ((newpos = ie_in_set(pc, *p, cl))) {
754 if (ie_in_set(pc, *p, comp_required))
768 if (!codeset && (l > getmax_ie_len(ie)))
772 l3_debug(pc->st,
"check IE shift back codeset %d->%d",
773 codeset, old_codeset);
774 codeset = old_codeset;
778 if (err_compr | err_ureg | err_len | err_seq) {
780 l3_debug(pc->st,
"check IE MT(%x) %d/%d/%d/%d",
781 mt, err_compr, err_ureg, err_len, err_seq);
796 l3dss1_check_messagetype_validity(
struct l3_process *pc,
int mt,
void *arg)
823 l3_debug(pc->st,
"l3dss1_check_messagetype_validity mt(%x) OK", mt);
829 l3_debug(pc->st,
"l3dss1_check_messagetype_validity mt(%x) fail", mt);
831 l3dss1_status_send(pc, 0,
NULL);
838 l3dss1_std_ie_err(
struct l3_process *pc,
int ret) {
841 l3_debug(pc->st,
"check_infoelements ret %d", ret);
847 l3dss1_status_send(pc, 0,
NULL);
851 l3dss1_status_send(pc, 0,
NULL);
854 pc->para.cause = 100;
855 l3dss1_status_send(pc, 0,
NULL);
864 l3dss1_get_channel_id(
struct l3_process *pc,
struct sk_buff *skb) {
872 l3_debug(pc->st,
"wrong chid len %d", *p);
878 l3_debug(pc->st,
"wrong chid %x", *p);
887 l3dss1_get_cause(
struct l3_process *pc,
struct sk_buff *skb) {
905 if (l && !(pc->para.loc & 0x80)) {
910 pc->para.cause = *p++;
912 if (!(pc->para.cause & 0x80))
916 while (l && (i < 6)) {
917 pc->para.diag[i++] = *p++;
926 l3dss1_msg_with_uus(
struct l3_process *pc,
u_char cmd)
935 if (pc->prot.dss1.uus1_data[0])
937 *p++ =
strlen(pc->prot.dss1.uus1_data) + 1;
939 strcpy(p, pc->prot.dss1.uus1_data);
940 p +=
strlen(pc->prot.dss1.uus1_data);
941 pc->prot.dss1.uus1_data[0] =
'\0';
952 l3dss1_release_req(
struct l3_process *pc,
u_char pr,
void *arg)
956 if (!pc->prot.dss1.uus1_data[0])
964 l3dss1_release_cmpl(
struct l3_process *pc,
u_char pr,
void *arg)
969 if ((ret = l3dss1_get_cause(pc, skb)) > 0) {
971 l3_debug(pc->st,
"RELCMPL get_cause ret(%d)", ret);
973 pc->para.cause = NO_CAUSE;
977 dss1_release_l3_process(pc);
980 #ifdef EXT_BEARER_CAPS
1010 switch (si2 & 0x07) {
1133 if ((info & 16) && (!(info & 8)))
1137 if ((info & 96) == 96)
1141 if ((info & 2) && (!(info & 1)))
1191 DecodeSI2(
struct sk_buff *skb)
1196 switch (p[4] & 0x0f) {
1200 return DecodeSyncParams(160, p[5]);
1202 else if (p[1] == 0x06)
1204 return DecodeASyncParams(192, p);
1209 return DecodeSyncParams(176, p[5]);
1220 l3dss1_setup_req(
struct l3_process *pc,
u_char pr,
1238 teln = pc->para.setup.phone;
1239 #ifndef CONFIG_HISAX_NO_KEYPAD
1240 send_keypad = (
strchr(teln,
'*') ||
strchr(teln,
'#')) ? 1 : 0;
1244 #ifndef CONFIG_HISAX_NO_SENDCOMPLETE
1251 switch (pc->para.setup.si1) {
1273 *p++ = (*teln++) & 0x7F;
1279 if ((*teln) && (!send_keypad)) {
1282 switch (0x5f & *teln) {
1302 l3_debug(pc->st,
"Wrong MSN Code");
1313 msn = pc->para.setup.eazmsn;
1325 *p++ =
strlen(msn) + (screen ? 2 : 1);
1333 *p++ = *msn++ & 0x7f;
1342 *p++ = *sub++ & 0x7f;
1360 *p++ = *teln++ & 0x7f;
1369 *p++ = *sub++ & 0x7f;
1372 #ifdef EXT_BEARER_CAPS
1373 if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) {
1380 *p++ = EncodeSyncParams(pc->para.setup.si2 - 160, 0x80);
1381 }
else if ((pc->para.setup.si2 >= 176) && (pc->para.setup.si2 <= 191)) {
1388 *p++ = EncodeSyncParams(pc->para.setup.si2 - 176, 0);
1390 }
else if (pc->para.setup.si2 >= 192) {
1397 p = EncodeASyncParams(p, pc->para.setup.si2 - 192);
1398 #ifndef CONFIG_HISAX_NO_LLC
1400 switch (pc->para.setup.si1) {
1431 l3dss1_call_proc(
struct l3_process *pc,
u_char pr,
void *arg)
1436 if ((
id = l3dss1_get_channel_id(pc, skb)) >= 0) {
1437 if ((0 ==
id) || ((3 ==
id) && (0x10 == pc->para.moderate))) {
1439 l3_debug(pc->st,
"setup answer with wrong chid %x",
id);
1440 pc->para.cause = 100;
1441 l3dss1_status_send(pc, pr,
NULL);
1444 pc->para.bchannel =
id;
1445 }
else if (1 == pc->state) {
1447 l3_debug(pc->st,
"setup answer wrong chid (ret %d)",
id);
1449 pc->para.cause = 96;
1451 pc->para.cause = 100;
1452 l3dss1_status_send(pc, pr,
NULL);
1456 ret = check_infoelements(pc, skb, ie_CALL_PROCEEDING);
1458 l3dss1_std_ie_err(pc, ret);
1465 l3dss1_std_ie_err(pc, ret);
1470 l3dss1_setup_ack(
struct l3_process *pc,
u_char pr,
void *arg)
1475 if ((
id = l3dss1_get_channel_id(pc, skb)) >= 0) {
1476 if ((0 ==
id) || ((3 ==
id) && (0x10 == pc->para.moderate))) {
1478 l3_debug(pc->st,
"setup answer with wrong chid %x",
id);
1479 pc->para.cause = 100;
1480 l3dss1_status_send(pc, pr,
NULL);
1483 pc->para.bchannel =
id;
1486 l3_debug(pc->st,
"setup answer wrong chid (ret %d)",
id);
1488 pc->para.cause = 96;
1490 pc->para.cause = 100;
1491 l3dss1_status_send(pc, pr,
NULL);
1495 ret = check_infoelements(pc, skb, ie_SETUP_ACKNOWLEDGE);
1497 l3dss1_std_ie_err(pc, ret);
1504 l3dss1_std_ie_err(pc, ret);
1509 l3dss1_disconnect(
struct l3_process *pc,
u_char pr,
void *arg)
1517 if ((ret = l3dss1_get_cause(pc, skb))) {
1519 l3_debug(pc->st,
"DISC get_cause ret(%d)", ret);
1526 l3dss1_parse_facility(pc->st, pc, pc->callref, p);
1527 ret = check_infoelements(pc, skb, ie_DISCONNECT);
1539 l3dss1_release_req(pc, pr,
NULL);
1547 l3dss1_connect(
struct l3_process *pc,
u_char pr,
void *arg)
1552 ret = check_infoelements(pc, skb, ie_CONNECT);
1554 l3dss1_std_ie_err(pc, ret);
1559 pc->para.chargeinfo = 0;
1562 l3dss1_std_ie_err(pc, ret);
1567 l3dss1_alerting(
struct l3_process *pc,
u_char pr,
void *arg)
1572 ret = check_infoelements(pc, skb, ie_ALERTING);
1574 l3dss1_std_ie_err(pc, ret);
1580 l3dss1_std_ie_err(pc, ret);
1585 l3dss1_setup(
struct l3_process *pc,
u_char pr,
void *arg)
1599 if ((p =
findie(p, skb->
len, 0x04, 0))) {
1600 if ((p[1] < 2) || (p[1] > 11))
1603 pc->para.setup.si2 = 0;
1604 switch (p[2] & 0x7f) {
1607 pc->para.setup.si1 = 1;
1610 pc->para.setup.si1 = 7;
1612 #ifdef EXT_BEARER_CAPS
1613 pc->para.setup.si2 = DecodeSI2(skb);
1617 pc->para.setup.si1 = 2;
1623 pc->para.setup.si1 = 3;
1626 pc->para.setup.si1 = 4;
1632 switch (p[3] & 0x7f) {
1634 pc->para.setup.si1 = 8;
1641 pc->para.moderate = p[3] & 0x7f;
1650 pc->para.setup.si1, pc->para.setup.si2);
1653 l3_debug(pc->st,
"setup with wrong bearer(l=%d:%x,%x)",
1655 pc->para.cause = 100;
1656 l3dss1_msg_without_setup(pc, pr,
NULL);
1661 l3_debug(pc->st,
"setup without bearer capabilities");
1663 pc->para.cause = 96;
1664 l3dss1_msg_without_setup(pc, pr,
NULL);
1670 if ((
id = l3dss1_get_channel_id(pc, skb)) >= 0) {
1671 if ((pc->para.bchannel =
id)) {
1672 if ((3 ==
id) && (0x10 == pc->para.moderate)) {
1674 l3_debug(pc->st,
"setup with wrong chid %x",
1676 pc->para.cause = 100;
1677 l3dss1_msg_without_setup(pc, pr,
NULL);
1683 l3_debug(pc->st,
"setup without bchannel, call waiting");
1688 l3_debug(pc->st,
"setup with wrong chid ret %d",
id);
1690 pc->para.cause = 96;
1692 pc->para.cause = 100;
1693 l3dss1_msg_without_setup(pc, pr,
NULL);
1697 err = check_infoelements(pc, skb, ie_SETUP);
1699 pc->para.cause = 96;
1700 l3dss1_msg_without_setup(pc, pr,
NULL);
1705 iecpy(pc->para.setup.eazmsn, p, 1);
1707 pc->para.setup.eazmsn[0] = 0;
1710 if ((p =
findie(p, skb->
len, 0x71, 0))) {
1712 if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) {
1714 iecpy(&tmp[1], p, 2);
1715 strcat(pc->para.setup.eazmsn, tmp);
1717 l3_debug(pc->st,
"wrong called subaddress");
1720 if ((p =
findie(p, skb->
len, 0x6c, 0))) {
1721 pc->para.setup.plan = p[2];
1723 iecpy(pc->para.setup.phone, p, 1);
1724 pc->para.setup.screen = 0;
1726 iecpy(pc->para.setup.phone, p, 2);
1727 pc->para.setup.screen = p[3];
1730 pc->para.setup.phone[0] = 0;
1731 pc->para.setup.plan = 0;
1732 pc->para.setup.screen = 0;
1735 if ((p =
findie(p, skb->
len, 0x6d, 0))) {
1737 if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) {
1739 iecpy(&tmp[1], p, 2);
1740 strcat(pc->para.setup.phone, tmp);
1742 l3_debug(pc->st,
"wrong calling subaddress");
1746 l3dss1_std_ie_err(pc, err);
1751 l3dss1_reset(
struct l3_process *pc,
u_char pr,
void *arg)
1753 dss1_release_l3_process(pc);
1757 l3dss1_disconnect_req(
struct l3_process *pc,
u_char pr,
void *arg)
1765 if (pc->para.cause != NO_CAUSE)
1766 cause = pc->para.cause;
1775 *p++ = cause | 0x80;
1777 if (pc->prot.dss1.uus1_data[0])
1779 *p++ =
strlen(pc->prot.dss1.uus1_data) + 1;
1781 strcpy(p, pc->prot.dss1.uus1_data);
1782 p +=
strlen(pc->prot.dss1.uus1_data);
1783 pc->prot.dss1.uus1_data[0] =
'\0';
1796 l3dss1_setup_rsp(
struct l3_process *pc,
u_char pr,
1799 if (!pc->para.bchannel)
1801 l3_debug(pc->st,
"D-chan connect for waiting call");
1802 l3dss1_disconnect_req(pc, pr, arg);
1812 l3dss1_connect_ack(
struct l3_process *pc,
u_char pr,
void *arg)
1817 ret = check_infoelements(pc, skb, ie_CONNECT_ACKNOWLEDGE);
1819 l3dss1_std_ie_err(pc, ret);
1825 l3dss1_std_ie_err(pc, ret);
1830 l3dss1_reject_req(
struct l3_process *pc,
u_char pr,
void *arg)
1838 if (pc->para.cause != NO_CAUSE)
1839 cause = pc->para.cause;
1846 *p++ = cause | 0x80;
1855 dss1_release_l3_process(pc);
1859 l3dss1_release(
struct l3_process *pc,
u_char pr,
void *arg)
1866 if ((ret = l3dss1_get_cause(pc, skb)) > 0) {
1868 l3_debug(pc->st,
"REL get_cause ret(%d)", ret);
1870 pc->para.cause = NO_CAUSE;
1872 l3dss1_parse_facility(pc->st, pc, pc->callref, p);
1874 if ((ret < 0) && (pc->state != 11))
1878 ret = check_infoelements(pc, skb, ie_RELEASE);
1889 dss1_release_l3_process(pc);
1893 l3dss1_alert_req(
struct l3_process *pc,
u_char pr,
1897 if (!pc->prot.dss1.uus1_data[0])
1904 l3dss1_proceed_req(
struct l3_process *pc,
u_char pr,
1913 l3dss1_setup_ack_req(
struct l3_process *pc,
u_char pr,
1926 l3dss1_deliver_display(
struct l3_process *pc,
int pr,
u_char *infp)
1929 struct IsdnCardState *
cs;
1933 if ((len = *infp++) > 80)
return;
1934 if (!pc->chan)
return;
1941 cs = pc->st->l1.hardware;
1943 ic.
arg = pc->chan->chan;
1944 cs->iif.statcallb(&ic);
1949 l3dss1_progress(
struct l3_process *pc,
u_char pr,
void *arg)
1958 pc->para.cause = 100;
1959 }
else if (!(p[2] & 0x70)) {
1977 pc->para.cause = 100;
1983 pc->para.cause = 100;
1988 pc->para.cause = 96;
1993 l3_debug(pc->st,
"progress error %d", err);
1994 l3dss1_status_send(pc, pr,
NULL);
1998 err = check_infoelements(pc, skb, ie_PROGRESS);
2000 l3dss1_std_ie_err(pc, err);
2006 l3dss1_notify(
struct l3_process *pc,
u_char pr,
void *arg)
2015 pc->para.cause = 100;
2023 pc->para.cause = 100;
2029 pc->para.cause = 96;
2034 l3_debug(pc->st,
"notify error %d", err);
2035 l3dss1_status_send(pc, pr,
NULL);
2039 err = check_infoelements(pc, skb, ie_NOTIFY);
2041 l3dss1_std_ie_err(pc, err);
2047 l3dss1_status_enq(
struct l3_process *pc,
u_char pr,
void *arg)
2052 ret = check_infoelements(pc, skb, ie_STATUS_ENQUIRY);
2053 l3dss1_std_ie_err(pc, ret);
2054 pc->para.cause = 30;
2055 l3dss1_status_send(pc, pr,
NULL);
2059 l3dss1_information(
struct l3_process *pc,
u_char pr,
void *arg)
2066 ret = check_infoelements(pc, skb, ie_INFORMATION);
2068 l3dss1_std_ie_err(pc, ret);
2069 if (pc->state == 25) {
2072 if ((p =
findie(p, skb->
len, 0x70, 0))) {
2074 strcat(pc->para.setup.eazmsn, tmp);
2084 static void l3dss1_redir_req(
struct l3_process *pc,
u_char pr,
void *arg)
2095 strcpy(pc->prot.dss1.uus1_data, pc->chan->setup.eazmsn);
2096 if (!pc->chan->setup.phone[0])
2097 { pc->para.cause = -1;
2098 l3dss1_disconnect_req(pc, pr, arg);
2102 if (pc->prot.dss1.invoke_id)
2103 free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
2105 if (!(pc->prot.dss1.invoke_id = new_invoke_id(pc->st)))
2110 for (subp = pc->chan->setup.phone; (*subp) && (*subp !=
'.'); subp++) len_phone++;
2111 if (*subp++ ==
'.') len_sub =
strlen(subp) + 2;
2114 *p++ = len_phone + len_sub + 2 + 2 + 8 + 3 + 3;
2118 *p++ = len_phone + len_sub + 2 + 2 + 8 + 3;
2121 *p++ = pc->prot.dss1.invoke_id;
2127 *p++ = len_phone + 2 + 2 + 3 + len_sub;
2130 *p++ = len_phone + 2 + len_sub;
2133 for (l = 0; l < len_phone; l++)
2134 *p++ = pc->chan->setup.phone[l];
2139 while (*subp) *p++ = *subp++;
2144 *p++ = pc->chan->setup.screen;
2156 static void l3dss1_redir_req_early(
struct l3_process *pc,
u_char pr,
void *arg)
2158 l3dss1_proceed_req(pc, pr, arg);
2159 l3dss1_redir_req(pc, pr, arg);
2167 static int l3dss1_cmd_global(
struct PStack *st,
isdn_ctrl *ic)
2173 struct l3_process *pc =
NULL;
2177 if (ic->
parm.dss1_io.datalen < 0)
return (-2);
2179 for (proc_len = 1, i = ic->
parm.dss1_io.proc >> 8; i; i++)
2181 l = ic->
parm.dss1_io.datalen + proc_len + 8;
2185 if (!(
id = new_invoke_id(st)))
2201 for (i = proc_len;
i; i--)
2202 *p++ = (ic->
parm.dss1_io.proc >> (i - 1)) & 0xFF;
2204 l = (p -
temp) + ic->
parm.dss1_io.datalen;
2206 if (ic->
parm.dss1_io.timeout > 0)
2207 if (!(pc = dss1_new_l3_process(st, -1)))
2208 { free_invoke_id(st,
id);
2211 pc->prot.dss1.ll_id = ic->
parm.dss1_io.ll_id;
2212 pc->prot.dss1.proc = ic->
parm.dss1_io.proc;
2215 { free_invoke_id(st,
id);
2216 if (pc) dss1_release_l3_process(pc);
2222 { pc->prot.dss1.invoke_id =
id;
2227 ic->
parm.dss1_io.hl_id =
id;
2231 if ((pc = l3dss1_search_dummy_proc(st, ic->
parm.dss1_io.hl_id)))
2233 dss1_release_l3_process(pc);
2237 {
l3_debug(st,
"l3dss1_cmd_global abort unknown id");
2243 l3_debug(st,
"l3dss1_cmd_global unknown cmd 0x%lx", ic->
arg);
2250 l3dss1_io_timer(
struct l3_process *pc)
2252 struct IsdnCardState *cs = pc->st->l1.hardware;
2259 ic.
parm.dss1_io.hl_id = pc->prot.dss1.invoke_id;
2260 ic.
parm.dss1_io.ll_id = pc->prot.dss1.ll_id;
2261 ic.
parm.dss1_io.proc = pc->prot.dss1.proc;
2262 ic.
parm.dss1_io.timeout = -1;
2263 ic.
parm.dss1_io.datalen = 0;
2265 free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
2266 pc->prot.dss1.invoke_id = 0;
2268 cs->iif.statcallb(&ic);
2270 dss1_release_l3_process(pc);
2274 l3dss1_release_ind(
struct l3_process *pc,
u_char pr,
void *arg)
2286 if (callState == 0) {
2292 dss1_release_l3_process(pc);
2299 l3dss1_dummy(
struct l3_process *pc,
u_char pr,
void *arg)
2304 l3dss1_t302(
struct l3_process *pc,
u_char pr,
void *arg)
2308 pc->para.cause = 28;
2309 l3dss1_disconnect_req(pc, pr,
NULL);
2314 l3dss1_t303(
struct l3_process *pc,
u_char pr,
void *arg)
2319 l3dss1_setup_req(pc, pr, arg);
2324 dss1_release_l3_process(pc);
2329 l3dss1_t304(
struct l3_process *pc,
u_char pr,
void *arg)
2333 pc->para.cause = 102;
2334 l3dss1_disconnect_req(pc, pr,
NULL);
2340 l3dss1_t305(
struct l3_process *pc,
u_char pr,
void *arg)
2349 if (pc->para.cause != NO_CAUSE)
2350 cause = pc->para.cause;
2357 *p++ = cause | 0x80;
2369 l3dss1_t310(
struct l3_process *pc,
u_char pr,
void *arg)
2373 pc->para.cause = 102;
2374 l3dss1_disconnect_req(pc, pr,
NULL);
2379 l3dss1_t313(
struct l3_process *pc,
u_char pr,
void *arg)
2383 pc->para.cause = 102;
2384 l3dss1_disconnect_req(pc, pr,
NULL);
2389 l3dss1_t308_1(
struct l3_process *pc,
u_char pr,
void *arg)
2398 l3dss1_t308_2(
struct l3_process *pc,
u_char pr,
void *arg)
2402 dss1_release_l3_process(pc);
2406 l3dss1_t318(
struct l3_process *pc,
u_char pr,
void *arg)
2409 pc->para.cause = 102;
2418 l3dss1_t319(
struct l3_process *pc,
u_char pr,
void *arg)
2421 pc->para.cause = 102;
2428 l3dss1_restart(
struct l3_process *pc,
u_char pr,
void *arg)
2432 dss1_release_l3_process(pc);
2436 l3dss1_status(
struct l3_process *pc,
u_char pr,
void *arg)
2441 u_char cause = 0, callState = 0;
2443 if ((ret = l3dss1_get_cause(pc, skb))) {
2445 l3_debug(pc->st,
"STATUS get_cause ret(%d)", ret);
2455 if (!ie_in_set(pc, *p, l3_valid_states))
2462 ret = check_infoelements(pc, skb, ie_STATUS);
2472 l3_debug(pc->st,
"STATUS error(%d/%d)", ret, cause);
2473 tmp = pc->para.cause;
2474 pc->para.cause =
cause;
2475 l3dss1_status_send(pc, 0,
NULL);
2477 pc->para.cause =
tmp;
2481 cause = pc->para.cause;
2482 if (((cause & 0x7f) == 111) && (callState == 0)) {
2489 dss1_release_l3_process(pc);
2494 l3dss1_facility(
struct l3_process *pc,
u_char pr,
void *arg)
2499 ret = check_infoelements(pc, skb, ie_FACILITY);
2500 l3dss1_std_ie_err(pc, ret);
2504 l3dss1_parse_facility(pc->st, pc, pc->callref, p);
2509 l3dss1_suspend_req(
struct l3_process *pc,
u_char pr,
void *arg)
2519 if (l && (l <= 10)) {
2522 for (i = 0; i <
l; i++)
2525 l3_debug(pc->st,
"SUS wrong CALL_ID len %d", l);
2538 l3dss1_suspend_ack(
struct l3_process *pc,
u_char pr,
void *arg)
2545 pc->para.cause = NO_CAUSE;
2548 if ((ret = check_infoelements(pc, skb, ie_SUSPEND_ACKNOWLEDGE)))
2550 l3_debug(pc->st,
"SUSPACK check ie(%d)", ret);
2551 dss1_release_l3_process(pc);
2555 l3dss1_suspend_rej(
struct l3_process *pc,
u_char pr,
void *arg)
2560 if ((ret = l3dss1_get_cause(pc, skb))) {
2562 l3_debug(pc->st,
"SUSP_REJ get_cause ret(%d)", ret);
2564 pc->para.cause = 96;
2566 pc->para.cause = 100;
2567 l3dss1_status_send(pc, pr,
NULL);
2570 ret = check_infoelements(pc, skb, ie_SUSPEND_REJECT);
2572 l3dss1_std_ie_err(pc, ret);
2579 l3dss1_std_ie_err(pc, ret);
2583 l3dss1_resume_req(
struct l3_process *pc,
u_char pr,
void *arg)
2589 u_char *msg = pc->para.setup.phone;
2594 if (l && (l <= 10)) {
2597 for (i = 0; i <
l; i++)
2600 l3_debug(pc->st,
"RES wrong CALL_ID len %d", l);
2613 l3dss1_resume_ack(
struct l3_process *pc,
u_char pr,
void *arg)
2618 if ((
id = l3dss1_get_channel_id(pc, skb)) > 0) {
2619 if ((0 ==
id) || ((3 ==
id) && (0x10 == pc->para.moderate))) {
2621 l3_debug(pc->st,
"resume ack with wrong chid %x",
id);
2622 pc->para.cause = 100;
2623 l3dss1_status_send(pc, pr,
NULL);
2626 pc->para.bchannel =
id;
2627 }
else if (1 == pc->state) {
2629 l3_debug(pc->st,
"resume ack without chid (ret %d)",
id);
2630 pc->para.cause = 96;
2631 l3dss1_status_send(pc, pr,
NULL);
2634 ret = check_infoelements(pc, skb, ie_RESUME_ACKNOWLEDGE);
2636 l3dss1_std_ie_err(pc, ret);
2643 l3dss1_std_ie_err(pc, ret);
2647 l3dss1_resume_rej(
struct l3_process *pc,
u_char pr,
void *arg)
2652 if ((ret = l3dss1_get_cause(pc, skb))) {
2654 l3_debug(pc->st,
"RES_REJ get_cause ret(%d)", ret);
2656 pc->para.cause = 96;
2658 pc->para.cause = 100;
2659 l3dss1_status_send(pc, pr,
NULL);
2662 ret = check_infoelements(pc, skb, ie_RESUME_REJECT);
2664 l3dss1_std_ie_err(pc, ret);
2671 l3dss1_std_ie_err(pc, ret);
2672 dss1_release_l3_process(pc);
2676 l3dss1_global_restart(
struct l3_process *pc,
u_char pr,
void *arg)
2683 struct l3_process *
up;
2690 l3_debug(pc->st,
"Restart %x", ri);
2692 l3_debug(pc->st,
"Restart without restart IE");
2699 if (pc->st->l3.debug)
2703 up = pc->st->l3.proc;
2707 else if (up->para.bchannel ==
chan)
2730 l3dss1_dl_reset(
struct l3_process *pc,
u_char pr,
void *arg)
2732 pc->para.cause = 0x29;
2734 l3dss1_disconnect_req(pc, pr,
NULL);
2739 l3dss1_dl_release(
struct l3_process *pc,
u_char pr,
void *arg)
2742 pc->para.cause = 0x1b;
2749 l3dss1_dl_reestablish(
struct l3_process *pc,
u_char pr,
void *arg)
2757 l3dss1_dl_reest_status(
struct l3_process *pc,
u_char pr,
void *arg)
2761 pc->para.cause = 0x1F;
2762 l3dss1_status_send(pc, 0,
NULL);
2903 global_handler(
struct PStack *st,
int mt,
struct sk_buff *skb)
2909 struct l3_process *proc = st->l3.global;
2911 proc->callref = skb->
data[2];
2912 for (i = 0; i <
ARRAY_SIZE(globalmes_list); i++)
2913 if ((mt == globalmes_list[i].primitive) &&
2914 ((1 << proc->state) & globalmes_list[i].
state))
2918 l3_debug(st,
"dss1 global state %d mt %x unhandled",
2928 *p++ = proc->state & 0x3f;
2936 l3_debug(st,
"dss1 global %d mt %x",
2939 globalmes_list[
i].
rout(proc, mt, skb);
2944 dss1up(
struct PStack *st,
int pr,
void *arg)
2946 int i, mt,
cr, callState;
2950 struct l3_process *proc;
2968 l3_debug(st,
"dss1up frame too short(%d)", skb->
len);
2975 l3_debug(st,
"dss1up%sunexpected discriminator %x message len %d",
2983 if (skb->
len < ((skb->
data[1] & 0x0f) + 3)) {
2984 l3_debug(st,
"dss1up frame too short(%d)", skb->
len);
2993 l3_debug(st,
"dss1up wrong Callref");
2996 }
else if (cr == -1) {
2999 l3dss1_parse_facility(st,
NULL,
3005 l3_debug(st,
"dss1up dummy Callref (no facility msg or ie)");
3008 }
else if ((((skb->
data[1] & 0x0f) == 1) && (0 == (cr & 0x7f))) ||
3009 (((skb->
data[1] & 0x0f) == 2) && (0 == (cr & 0x7fff)))) {
3011 l3_debug(st,
"dss1up Global CallRef");
3012 global_handler(st, mt, skb);
3015 }
else if (!(proc =
getl3proc(st, cr))) {
3021 if (skb->
data[2] & 0x80) {
3024 l3_debug(st,
"dss1up wrong CRef flag");
3028 if (!(proc = dss1_new_l3_process(st, cr))) {
3054 if (callState != 0) {
3060 if ((proc = dss1_new_l3_process(st, cr))) {
3061 proc->para.cause = 101;
3062 l3dss1_msg_without_setup(proc, 0,
NULL);
3076 if ((proc = dss1_new_l3_process(st, cr))) {
3077 proc->para.cause = 81;
3078 l3dss1_msg_without_setup(proc, 0,
NULL);
3083 if (l3dss1_check_messagetype_validity(proc, mt, skb)) {
3088 l3dss1_deliver_display(proc, pr, p);
3089 for (i = 0; i <
ARRAY_SIZE(datastatelist); i++)
3090 if ((mt == datastatelist[i].primitive) &&
3091 ((1 << proc->state) & datastatelist[i].state))
3095 l3_debug(st,
"dss1up%sstate %d mt %#x unhandled",
3100 proc->para.cause = 101;
3101 l3dss1_status_send(proc, pr, skb);
3105 l3_debug(st,
"dss1up%sstate %d mt %x",
3109 datastatelist[
i].
rout(proc, pr, skb);
3116 dss1down(
struct PStack *st,
int pr,
void *arg)
3119 struct l3_process *proc;
3129 if ((proc = dss1_new_l3_process(st, cr))) {
3144 l3dss1_io_timer(proc);
3148 for (i = 0; i <
ARRAY_SIZE(downstatelist); i++)
3149 if ((pr == downstatelist[i].primitive) &&
3150 ((1 << proc->state) & downstatelist[i].state))
3154 l3_debug(st,
"dss1down state %d prim %#x unhandled",
3159 l3_debug(st,
"dss1down state %d prim %#x",
3162 downstatelist[
i].
rout(proc, pr, arg);
3167 dss1man(
struct PStack *st,
int pr,
void *arg)
3170 struct l3_process *proc =
arg;
3176 for (i = 0; i <
ARRAY_SIZE(manstatelist); i++)
3177 if ((pr == manstatelist[i].primitive) &&
3178 ((1 << proc->state) & manstatelist[i].state))
3182 l3_debug(st,
"cr %d dss1man state %d prim %#x unhandled",
3183 proc->callref & 0x7f, proc->state, pr);
3187 l3_debug(st,
"cr %d dss1man state %d prim %#x",
3188 proc->callref & 0x7f, proc->state, pr);
3190 manstatelist[
i].
rout(proc, pr, arg);
3200 st->lli.l4l3 = dss1down;
3201 st->lli.l4l3_proto = l3dss1_cmd_global;
3202 st->l2.l2l3 = dss1up;
3203 st->l3.l3ml3 = dss1man;
3205 st->prot.dss1.last_invoke_id = 0;
3206 st->prot.dss1.invoke_used[0] = 1;
3209 st->prot.dss1.invoke_used[i++] = 0;
3214 st->l3.global->state = 0;
3215 st->l3.global->callref = 0;
3216 st->l3.global->next =
NULL;
3218 st->l3.global->st =
st;
3219 st->l3.global->N303 = 1;
3220 st->l3.global->prot.dss1.invoke_id = 0;
3222 L3InitTimer(st->l3.global, &st->l3.global->timer);
3224 strcpy(tmp, dss1_revision);