24 #include <linux/ctype.h>
25 #include <linux/slab.h>
28 static const char *ni1_revision =
"$Revision: 2.8.2.3 $";
30 #define EXT_BEARER_CAPS 1
32 #define MsgHead(ptr, cref, mty) \
47 static unsigned char new_invoke_id(
struct PStack *
p)
54 retval = p->prot.ni1.last_invoke_id + 1;
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));
72 static void free_invoke_id(
struct PStack *
p,
unsigned char id)
77 p->prot.ni1.invoke_used[
id >> 3] &= ~(1 << (
id & 7));
84 static struct l3_process
85 *ni1_new_l3_process(
struct PStack *
st,
int cr)
86 {
struct l3_process *proc;
91 proc->prot.ni1.invoke_id = 0;
92 proc->prot.ni1.remote_operation = 0;
93 proc->prot.ni1.uus1_data[0] =
'\0';
102 ni1_release_l3_process(
struct l3_process *p)
104 free_invoke_id(p->st, p->prot.ni1.invoke_id);
111 static struct l3_process *
112 l3ni1_search_dummy_proc(
struct PStack *st,
int id)
113 {
struct l3_process *
pc = st->l3.proc;
115 if (!
id)
return (
NULL);
118 {
if ((pc->callref == -1) && (pc->prot.ni1.invoke_id ==
id))
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)))
138 cs = pc->st->l1.hardware;
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;
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);
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)))
171 cs = pc->st->l1.hardware;
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;
179 ic.
parm.ni1_io.datalen = 0;
181 free_invoke_id(pc->st, pc->prot.ni1.invoke_id);
182 pc->prot.ni1.invoke_id = 0;
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);
196 l3ni1_dummy_invoke(
struct PStack *st,
int cr,
int id,
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;
205 cs = st->l1.hardware;
209 ic.
parm.ni1_io.hl_id =
id;
210 ic.
parm.ni1_io.ll_id = 0;
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);
220 l3ni1_parse_facility(
struct PStack *st,
struct l3_process *pc,
224 unsigned char nlen = 0, ilen, cp_tag;
231 if ((!st) || (cr >= 0))
return;
239 if ((*p & 0x1F) != 0x11) {
240 l3_debug(st,
"supplementary service != 0x11");
243 while (qd_len > 0 && !(*p & 0x80)) {
253 if ((*p & 0xE0) != 0xA0) {
254 l3_debug(st,
"class and form != 0xA0");
269 if ((qd_len-- < ((!nlen) ? 3 : (1 + nlen))) ||
271 {
l3_debug(st,
"length format error or not implemented");
280 if ((*(p + qd_len)) || (*(p + qd_len + 1)))
281 {
l3_debug(st,
"length format indefinite error");
303 l3_debug(st,
"invoke identifier tag !=0x02");
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);
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);
362 l3ni1_dummy_return_result(st,
id, p, nlen);
365 if ((pc->prot.ni1.invoke_id) && (pc->prot.ni1.invoke_id ==
id))
367 free_invoke_id(st, pc->prot.ni1.invoke_id);
368 pc->prot.ni1.remote_result = 0;
369 pc->prot.ni1.invoke_id = 0;
370 pc->redir_result = pc->prot.ni1.remote_result;
373 l3_debug(st,
"return error unknown identifier");
378 {
l3_debug(st,
"return error nlen < 2");
383 l3_debug(st,
"invoke error tag !=0x02");
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);
407 l3ni1_dummy_error_return(st,
id, err_ret);
410 if ((pc->prot.ni1.invoke_id) && (pc->prot.ni1.invoke_id ==
id))
412 free_invoke_id(st, pc->prot.ni1.invoke_id);
413 pc->prot.ni1.remote_result = err_ret;
414 pc->prot.ni1.invoke_id = 0;
415 pc->redir_result = pc->prot.ni1.remote_result;
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)
441 l3ni1_message_plus_chid(
struct l3_process *pc,
u_char mt)
449 chid = (
u_char)(pc->para.bchannel & 0x03) | 0x88;
483 l3ni1_status_send(
struct l3_process *pc,
u_char pr,
void *
arg)
495 *p++ = pc->para.cause | 0x80;
499 *p++ = pc->state & 0x3f;
509 l3ni1_msg_without_setup(
struct l3_process *pc,
u_char pr,
void *arg)
520 switch (pc->para.cause) {
530 *p++ = pc->para.cause | 0x80;
542 ni1_release_l3_process(pc);
578 static int ie_STATUS_ENQUIRY[] = {
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[] = {
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;
681 while ((p - skb->
data) < skb->
len) {
682 if ((*p & 0xf0) == 0x90) {
683 old_codeset = codeset;
690 l3_debug(pc->st,
"check IE shift%scodeset %d->%d",
691 codelock ?
" locking " :
" ", old_codeset, codeset);
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)))
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) {
730 l3_debug(pc->st,
"check IE MT(%x) %d/%d/%d/%d",
731 mt, err_compr, err_ureg, err_len, err_seq);
746 l3ni1_check_messagetype_validity(
struct l3_process *pc,
int mt,
void *arg)
773 l3_debug(pc->st,
"l3ni1_check_messagetype_validity mt(%x) OK", mt);
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) {
791 l3_debug(pc->st,
"check_infoelements ret %d", ret);
797 l3ni1_status_send(pc, 0,
NULL);
801 l3ni1_status_send(pc, 0,
NULL);
804 pc->para.cause = 100;
805 l3ni1_status_send(pc, 0,
NULL);
814 l3ni1_get_channel_id(
struct l3_process *pc,
struct sk_buff *skb) {
822 l3_debug(pc->st,
"wrong chid len %d", *p);
828 l3_debug(pc->st,
"wrong chid %x", *p);
837 l3ni1_get_cause(
struct l3_process *pc,
struct sk_buff *skb) {
855 if (l && !(pc->para.loc & 0x80)) {
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)
885 if (pc->prot.ni1.uus1_data[0])
887 *p++ =
strlen(pc->prot.ni1.uus1_data) + 1;
889 strcpy(p, pc->prot.ni1.uus1_data);
890 p +=
strlen(pc->prot.ni1.uus1_data);
891 pc->prot.ni1.uus1_data[0] =
'\0';
902 l3ni1_release_req(
struct l3_process *pc,
u_char pr,
void *arg)
906 if (!pc->prot.ni1.uus1_data[0])
914 l3ni1_release_cmpl(
struct l3_process *pc,
u_char pr,
void *arg)
919 if ((ret = l3ni1_get_cause(pc, skb)) > 0) {
921 l3_debug(pc->st,
"RELCMPL get_cause ret(%d)", ret);
923 pc->para.cause = NO_CAUSE;
927 ni1_release_l3_process(pc);
960 switch (si2 & 0x07) {
1083 if ((info & 16) && (!(info & 8)))
1087 if ((info & 96) == 96)
1091 if ((info & 2) && (!(info & 1)))
1141 DecodeSI2(
struct sk_buff *skb)
1146 switch (p[4] & 0x0f) {
1150 return DecodeSyncParams(160, p[5]);
1152 else if (p[1] == 0x06)
1154 return DecodeASyncParams(192, p);
1159 return DecodeSyncParams(176, p[5]);
1170 l3ni1_setup_req(
struct l3_process *pc,
u_char pr,
1184 teln = pc->para.setup.phone;
1190 switch (pc->para.setup.si1) {
1221 *p++ = (*teln++) & 0x7F;
1227 if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) {
1234 *p++ = EncodeSyncParams(pc->para.setup.si2 - 160, 0x80);
1235 }
else if ((pc->para.setup.si2 >= 176) && (pc->para.setup.si2 <= 191)) {
1242 *p++ = EncodeSyncParams(pc->para.setup.si2 - 176, 0);
1244 }
else if (pc->para.setup.si2 >= 192) {
1251 p = EncodeASyncParams(p, pc->para.setup.si2 - 192);
1253 switch (pc->para.setup.si1) {
1285 l3ni1_call_proc(
struct l3_process *pc,
u_char pr,
void *arg)
1290 if ((
id = l3ni1_get_channel_id(pc, skb)) >= 0) {
1291 if ((0 ==
id) || ((3 ==
id) && (0x10 == pc->para.moderate))) {
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) {
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);
1310 ret = check_infoelements(pc, skb, ie_CALL_PROCEEDING);
1312 l3ni1_std_ie_err(pc, ret);
1319 l3ni1_std_ie_err(pc, ret);
1324 l3ni1_setup_ack(
struct l3_process *pc,
u_char pr,
void *arg)
1329 if ((
id = l3ni1_get_channel_id(pc, skb)) >= 0) {
1330 if ((0 ==
id) || ((3 ==
id) && (0x10 == pc->para.moderate))) {
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;
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);
1349 ret = check_infoelements(pc, skb, ie_SETUP_ACKNOWLEDGE);
1351 l3ni1_std_ie_err(pc, ret);
1358 l3ni1_std_ie_err(pc, ret);
1363 l3ni1_disconnect(
struct l3_process *pc,
u_char pr,
void *arg)
1371 if ((ret = l3ni1_get_cause(pc, skb))) {
1373 l3_debug(pc->st,
"DISC get_cause ret(%d)", ret);
1380 l3ni1_parse_facility(pc->st, pc, pc->callref, p);
1381 ret = check_infoelements(pc, skb, ie_DISCONNECT);
1393 l3ni1_release_req(pc, pr,
NULL);
1401 l3ni1_connect(
struct l3_process *pc,
u_char pr,
void *arg)
1406 ret = check_infoelements(pc, skb, ie_CONNECT);
1408 l3ni1_std_ie_err(pc, ret);
1413 pc->para.chargeinfo = 0;
1416 l3ni1_std_ie_err(pc, ret);
1421 l3ni1_alerting(
struct l3_process *pc,
u_char pr,
void *arg)
1426 ret = check_infoelements(pc, skb, ie_ALERTING);
1428 l3ni1_std_ie_err(pc, ret);
1434 l3ni1_std_ie_err(pc, ret);
1439 l3ni1_setup(
struct l3_process *pc,
u_char pr,
void *arg)
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) {
1461 pc->para.setup.si1 = 1;
1464 pc->para.setup.si1 = 7;
1467 pc->para.setup.si2 = DecodeSI2(skb);
1471 pc->para.setup.si1 = 2;
1477 pc->para.setup.si1 = 3;
1480 pc->para.setup.si1 = 4;
1486 switch (p[3] & 0x7f) {
1488 pc->para.setup.si1 = 8;
1495 pc->para.moderate = p[3] & 0x7f;
1504 pc->para.setup.si1, pc->para.setup.si2);
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);
1515 l3_debug(pc->st,
"setup without bearer capabilities");
1517 pc->para.cause = 96;
1518 l3ni1_msg_without_setup(pc, pr,
NULL);
1524 if ((
id = l3ni1_get_channel_id(pc, skb)) >= 0) {
1525 if ((pc->para.bchannel =
id)) {
1526 if ((3 ==
id) && (0x10 == pc->para.moderate)) {
1528 l3_debug(pc->st,
"setup with wrong chid %x",
1530 pc->para.cause = 100;
1531 l3ni1_msg_without_setup(pc, pr,
NULL);
1537 l3_debug(pc->st,
"setup without bchannel, call waiting");
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);
1551 err = check_infoelements(pc, skb, ie_SETUP);
1553 pc->para.cause = 96;
1554 l3ni1_msg_without_setup(pc, pr,
NULL);
1559 iecpy(pc->para.setup.eazmsn, p, 1);
1561 pc->para.setup.eazmsn[0] = 0;
1564 if ((p =
findie(p, skb->
len, 0x71, 0))) {
1566 if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) {
1568 iecpy(&tmp[1], p, 2);
1569 strcat(pc->para.setup.eazmsn, tmp);
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))) {
1591 if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) {
1593 iecpy(&tmp[1], p, 2);
1594 strcat(pc->para.setup.phone, tmp);
1596 l3_debug(pc->st,
"wrong calling subaddress");
1600 l3ni1_std_ie_err(pc, err);
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)
1619 if (pc->para.cause != NO_CAUSE)
1620 cause = pc->para.cause;
1629 *p++ = cause | 0x80;
1631 if (pc->prot.ni1.uus1_data[0])
1633 *p++ =
strlen(pc->prot.ni1.uus1_data) + 1;
1635 strcpy(p, pc->prot.ni1.uus1_data);
1636 p +=
strlen(pc->prot.ni1.uus1_data);
1637 pc->prot.ni1.uus1_data[0] =
'\0';
1650 l3ni1_setup_rsp(
struct l3_process *pc,
u_char pr,
1653 if (!pc->para.bchannel)
1655 l3_debug(pc->st,
"D-chan connect for waiting call");
1656 l3ni1_disconnect_req(pc, pr, arg);
1661 l3_debug(pc->st,
"D-chan connect for waiting call");
1668 l3ni1_connect_ack(
struct l3_process *pc,
u_char pr,
void *arg)
1673 ret = check_infoelements(pc, skb, ie_CONNECT_ACKNOWLEDGE);
1675 l3ni1_std_ie_err(pc, ret);
1681 l3ni1_std_ie_err(pc, ret);
1686 l3ni1_reject_req(
struct l3_process *pc,
u_char pr,
void *arg)
1694 if (pc->para.cause != NO_CAUSE)
1695 cause = pc->para.cause;
1702 *p++ = cause | 0x80;
1711 ni1_release_l3_process(pc);
1715 l3ni1_release(
struct l3_process *pc,
u_char pr,
void *arg)
1722 if ((ret = l3ni1_get_cause(pc, skb)) > 0) {
1724 l3_debug(pc->st,
"REL get_cause ret(%d)", ret);
1726 pc->para.cause = NO_CAUSE;
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);
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])
1760 l3ni1_proceed_req(
struct l3_process *pc,
u_char pr,
1769 l3ni1_setup_ack_req(
struct l3_process *pc,
u_char pr,
1782 l3ni1_deliver_display(
struct l3_process *pc,
int pr,
u_char *infp)
1785 struct IsdnCardState *
cs;
1789 if ((len = *infp++) > 80)
return;
1790 if (!pc->chan)
return;
1797 cs = pc->st->l1.hardware;
1799 ic.
arg = pc->chan->chan;
1800 cs->iif.statcallb(&ic);
1805 l3ni1_progress(
struct l3_process *pc,
u_char pr,
void *arg)
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;
1849 l3_debug(pc->st,
"progress error %d", err);
1850 l3ni1_status_send(pc, pr,
NULL);
1854 err = check_infoelements(pc, skb, ie_PROGRESS);
1856 l3ni1_std_ie_err(pc, err);
1862 l3ni1_notify(
struct l3_process *pc,
u_char pr,
void *arg)
1871 pc->para.cause = 100;
1879 pc->para.cause = 100;
1885 pc->para.cause = 96;
1890 l3_debug(pc->st,
"notify error %d", err);
1891 l3ni1_status_send(pc, pr,
NULL);
1895 err = check_infoelements(pc, skb, ie_NOTIFY);
1897 l3ni1_std_ie_err(pc, err);
1903 l3ni1_status_enq(
struct l3_process *pc,
u_char pr,
void *arg)
1908 ret = check_infoelements(pc, skb, ie_STATUS_ENQUIRY);
1909 l3ni1_std_ie_err(pc, ret);
1910 pc->para.cause = 30;
1911 l3ni1_status_send(pc, pr,
NULL);
1915 l3ni1_information(
struct l3_process *pc,
u_char pr,
void *arg)
1922 ret = check_infoelements(pc, skb, ie_INFORMATION);
1924 l3ni1_std_ie_err(pc, ret);
1925 if (pc->state == 25) {
1928 if ((p =
findie(p, skb->
len, 0x70, 0))) {
1930 strcat(pc->para.setup.eazmsn, tmp);
1940 static void l3ni1_redir_req(
struct l3_process *pc,
u_char pr,
void *arg)
1951 strcpy(pc->prot.ni1.uus1_data, pc->chan->setup.eazmsn);
1952 if (!pc->chan->setup.phone[0])
1953 { pc->para.cause = -1;
1954 l3ni1_disconnect_req(pc, pr, arg);
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)))
1966 for (subp = pc->chan->setup.phone; (*subp) && (*subp !=
'.'); subp++) len_phone++;
1967 if (*subp++ ==
'.') len_sub =
strlen(subp) + 2;
1970 *p++ = len_phone + len_sub + 2 + 2 + 8 + 3 + 3;
1974 *p++ = len_phone + len_sub + 2 + 2 + 8 + 3;
1977 *p++ = pc->prot.ni1.invoke_id;
1983 *p++ = len_phone + 2 + 2 + 3 + len_sub;
1986 *p++ = len_phone + 2 + len_sub;
1989 for (l = 0; l < len_phone; l++)
1990 *p++ = pc->chan->setup.phone[l];
1995 while (*subp) *p++ = *subp++;
2000 *p++ = pc->chan->setup.screen;
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);
2023 static int l3ni1_cmd_global(
struct PStack *st,
isdn_ctrl *ic)
2029 struct l3_process *pc =
NULL;
2033 if (ic->
parm.ni1_io.datalen < 0)
return (-2);
2035 for (proc_len = 1, i = ic->
parm.ni1_io.proc >> 8; i; i++)
2037 l = ic->
parm.ni1_io.datalen + proc_len + 8;
2041 if (!(
id = new_invoke_id(st)))
2057 for (i = proc_len;
i; i--)
2058 *p++ = (ic->
parm.ni1_io.proc >> (i - 1)) & 0xFF;
2060 l = (p -
temp) + ic->
parm.ni1_io.datalen;
2062 if (ic->
parm.ni1_io.timeout > 0)
2063 if (!(pc = ni1_new_l3_process(st, -1)))
2064 { free_invoke_id(st,
id);
2067 pc->prot.ni1.ll_id = ic->
parm.ni1_io.ll_id;
2068 pc->prot.ni1.proc = ic->
parm.ni1_io.proc;
2071 { free_invoke_id(st,
id);
2072 if (pc) ni1_release_l3_process(pc);
2078 { pc->prot.ni1.invoke_id =
id;
2083 ic->
parm.ni1_io.hl_id =
id;
2087 if ((pc = l3ni1_search_dummy_proc(st, ic->
parm.ni1_io.hl_id)))
2089 ni1_release_l3_process(pc);
2093 {
l3_debug(st,
"l3ni1_cmd_global abort unknown id");
2099 l3_debug(st,
"l3ni1_cmd_global unknown cmd 0x%lx", ic->
arg);
2106 l3ni1_io_timer(
struct l3_process *pc)
2108 struct IsdnCardState *cs = pc->st->l1.hardware;
2115 ic.
parm.ni1_io.hl_id = pc->prot.ni1.invoke_id;
2116 ic.
parm.ni1_io.ll_id = pc->prot.ni1.ll_id;
2117 ic.
parm.ni1_io.proc = pc->prot.ni1.proc;
2118 ic.
parm.ni1_io.timeout = -1;
2119 ic.
parm.ni1_io.datalen = 0;
2121 free_invoke_id(pc->st, pc->prot.ni1.invoke_id);
2122 pc->prot.ni1.invoke_id = 0;
2124 cs->iif.statcallb(&ic);
2126 ni1_release_l3_process(pc);
2130 l3ni1_release_ind(
struct l3_process *pc,
u_char pr,
void *arg)
2142 if (callState == 0) {
2148 ni1_release_l3_process(pc);
2155 l3ni1_dummy(
struct l3_process *pc,
u_char pr,
void *arg)
2160 l3ni1_t302(
struct l3_process *pc,
u_char pr,
void *arg)
2164 pc->para.cause = 28;
2165 l3ni1_disconnect_req(pc, pr,
NULL);
2170 l3ni1_t303(
struct l3_process *pc,
u_char pr,
void *arg)
2175 l3ni1_setup_req(pc, pr, arg);
2180 ni1_release_l3_process(pc);
2185 l3ni1_t304(
struct l3_process *pc,
u_char pr,
void *arg)
2189 pc->para.cause = 102;
2190 l3ni1_disconnect_req(pc, pr,
NULL);
2196 l3ni1_t305(
struct l3_process *pc,
u_char pr,
void *arg)
2205 if (pc->para.cause != NO_CAUSE)
2206 cause = pc->para.cause;
2213 *p++ = cause | 0x80;
2225 l3ni1_t310(
struct l3_process *pc,
u_char pr,
void *arg)
2229 pc->para.cause = 102;
2230 l3ni1_disconnect_req(pc, pr,
NULL);
2235 l3ni1_t313(
struct l3_process *pc,
u_char pr,
void *arg)
2239 pc->para.cause = 102;
2240 l3ni1_disconnect_req(pc, pr,
NULL);
2245 l3ni1_t308_1(
struct l3_process *pc,
u_char pr,
void *arg)
2254 l3ni1_t308_2(
struct l3_process *pc,
u_char pr,
void *arg)
2258 ni1_release_l3_process(pc);
2262 l3ni1_t318(
struct l3_process *pc,
u_char pr,
void *arg)
2265 pc->para.cause = 102;
2274 l3ni1_t319(
struct l3_process *pc,
u_char pr,
void *arg)
2277 pc->para.cause = 102;
2284 l3ni1_restart(
struct l3_process *pc,
u_char pr,
void *arg)
2288 ni1_release_l3_process(pc);
2292 l3ni1_status(
struct l3_process *pc,
u_char pr,
void *arg)
2297 u_char cause = 0, callState = 0;
2299 if ((ret = l3ni1_get_cause(pc, skb))) {
2301 l3_debug(pc->st,
"STATUS get_cause ret(%d)", ret);
2311 if (!ie_in_set(pc, *p, l3_valid_states))
2318 ret = check_infoelements(pc, skb, ie_STATUS);
2328 l3_debug(pc->st,
"STATUS error(%d/%d)", ret, cause);
2329 tmp = pc->para.cause;
2330 pc->para.cause =
cause;
2331 l3ni1_status_send(pc, 0,
NULL);
2333 pc->para.cause =
tmp;
2337 cause = pc->para.cause;
2338 if (((cause & 0x7f) == 111) && (callState == 0)) {
2345 ni1_release_l3_process(pc);
2350 l3ni1_facility(
struct l3_process *pc,
u_char pr,
void *arg)
2355 ret = check_infoelements(pc, skb, ie_FACILITY);
2356 l3ni1_std_ie_err(pc, ret);
2360 l3ni1_parse_facility(pc->st, pc, pc->callref, p);
2365 l3ni1_suspend_req(
struct l3_process *pc,
u_char pr,
void *arg)
2375 if (l && (l <= 10)) {
2378 for (i = 0; i <
l; i++)
2381 l3_debug(pc->st,
"SUS wrong CALL_ID len %d", l);
2394 l3ni1_suspend_ack(
struct l3_process *pc,
u_char pr,
void *arg)
2401 pc->para.cause = NO_CAUSE;
2404 if ((ret = check_infoelements(pc, skb, ie_SUSPEND_ACKNOWLEDGE)))
2406 l3_debug(pc->st,
"SUSPACK check ie(%d)", ret);
2407 ni1_release_l3_process(pc);
2411 l3ni1_suspend_rej(
struct l3_process *pc,
u_char pr,
void *arg)
2416 if ((ret = l3ni1_get_cause(pc, skb))) {
2418 l3_debug(pc->st,
"SUSP_REJ get_cause ret(%d)", ret);
2420 pc->para.cause = 96;
2422 pc->para.cause = 100;
2423 l3ni1_status_send(pc, pr,
NULL);
2426 ret = check_infoelements(pc, skb, ie_SUSPEND_REJECT);
2428 l3ni1_std_ie_err(pc, ret);
2435 l3ni1_std_ie_err(pc, ret);
2439 l3ni1_resume_req(
struct l3_process *pc,
u_char pr,
void *arg)
2445 u_char *msg = pc->para.setup.phone;
2450 if (l && (l <= 10)) {
2453 for (i = 0; i <
l; i++)
2456 l3_debug(pc->st,
"RES wrong CALL_ID len %d", l);
2469 l3ni1_resume_ack(
struct l3_process *pc,
u_char pr,
void *arg)
2474 if ((
id = l3ni1_get_channel_id(pc, skb)) > 0) {
2475 if ((0 ==
id) || ((3 ==
id) && (0x10 == pc->para.moderate))) {
2477 l3_debug(pc->st,
"resume ack with wrong chid %x",
id);
2478 pc->para.cause = 100;
2479 l3ni1_status_send(pc, pr,
NULL);
2482 pc->para.bchannel =
id;
2483 }
else if (1 == pc->state) {
2485 l3_debug(pc->st,
"resume ack without chid (ret %d)",
id);
2486 pc->para.cause = 96;
2487 l3ni1_status_send(pc, pr,
NULL);
2490 ret = check_infoelements(pc, skb, ie_RESUME_ACKNOWLEDGE);
2492 l3ni1_std_ie_err(pc, ret);
2499 l3ni1_std_ie_err(pc, ret);
2503 l3ni1_resume_rej(
struct l3_process *pc,
u_char pr,
void *arg)
2508 if ((ret = l3ni1_get_cause(pc, skb))) {
2510 l3_debug(pc->st,
"RES_REJ get_cause ret(%d)", ret);
2512 pc->para.cause = 96;
2514 pc->para.cause = 100;
2515 l3ni1_status_send(pc, pr,
NULL);
2518 ret = check_infoelements(pc, skb, ie_RESUME_REJECT);
2520 l3ni1_std_ie_err(pc, ret);
2527 l3ni1_std_ie_err(pc, ret);
2528 ni1_release_l3_process(pc);
2532 l3ni1_global_restart(
struct l3_process *pc,
u_char pr,
void *arg)
2539 struct l3_process *
up;
2546 l3_debug(pc->st,
"Restart %x", ri);
2548 l3_debug(pc->st,
"Restart without restart IE");
2555 if (pc->st->l3.debug)
2559 up = pc->st->l3.proc;
2563 else if (up->para.bchannel ==
chan)
2587 l3ni1_dl_reset(
struct l3_process *pc,
u_char pr,
void *arg)
2589 pc->para.cause = 0x29;
2591 l3ni1_disconnect_req(pc, pr,
NULL);
2596 l3ni1_dl_release(
struct l3_process *pc,
u_char pr,
void *arg)
2599 pc->para.cause = 0x1b;
2606 l3ni1_dl_reestablish(
struct l3_process *pc,
u_char pr,
void *arg)
2614 l3ni1_dl_reest_status(
struct l3_process *pc,
u_char pr,
void *arg)
2618 pc->para.cause = 0x1F;
2619 l3ni1_status_send(pc, 0,
NULL);
2622 static void l3ni1_SendSpid(
struct l3_process *pc,
u_char pr,
struct sk_buff *skb,
int iNewState)
2626 struct Channel *pChan = pc->st->lli.userdata;
2632 if (!(pSPID =
strchr(pChan->setup.eazmsn,
':')))
2634 printk(
KERN_ERR "SPID not supplied in EAZMSN %s\n", pChan->setup.eazmsn);
2664 static void l3ni1_spid_send(
struct l3_process *pc,
u_char pr,
void *arg)
2666 l3ni1_SendSpid(pc, pr, arg, 20);
2669 static void l3ni1_spid_epid(
struct l3_process *pc,
u_char pr,
void *arg)
2673 if (skb->
data[1] == 0)
2683 static void l3ni1_spid_tout(
struct l3_process *pc,
u_char pr,
void *arg)
2686 l3ni1_SendSpid(pc, pr, arg, pc->state + 1);
2840 global_handler(
struct PStack *st,
int mt,
struct sk_buff *skb)
2846 struct l3_process *proc = st->l3.global;
2849 proc->callref = skb->
data[2];
2852 for (i = 0; i <
ARRAY_SIZE(globalmes_list); i++)
2853 if ((mt == globalmes_list[i].primitive) &&
2854 ((1 << proc->state) & globalmes_list[i].
state))
2858 l3_debug(st,
"ni1 global state %d mt %x unhandled",
2868 *p++ = proc->state & 0x3f;
2876 l3_debug(st,
"ni1 global %d mt %x",
2879 globalmes_list[
i].
rout(proc, mt, skb);
2884 ni1up(
struct PStack *st,
int pr,
void *arg)
2886 int i, mt,
cr, callState;
2890 struct l3_process *proc;
2912 l3_debug(st,
"ni1up frame too short(%d)", skb->
len);
2919 l3_debug(st,
"ni1up%sunexpected discriminator %x message len %d",
2927 if (skb->
len < ((skb->
data[1] & 0x0f) + 3)) {
2928 l3_debug(st,
"ni1up frame too short(%d)", skb->
len);
2937 l3_debug(st,
"ni1up wrong Callref");
2940 }
else if (cr == -1) {
2944 l3ni1_parse_facility(st,
NULL,
2952 global_handler(st, mt, skb);
2957 l3_debug(st,
"ni1up dummy Callref (no facility msg or ie)");
2960 }
else if ((((skb->
data[1] & 0x0f) == 1) && (0 == (cr & 0x7f))) ||
2961 (((skb->
data[1] & 0x0f) == 2) && (0 == (cr & 0x7fff)))) {
2963 l3_debug(st,
"ni1up Global CallRef");
2964 global_handler(st, mt, skb);
2967 }
else if (!(proc =
getl3proc(st, cr))) {
2973 if (skb->
data[2] & 0x80) {
2976 l3_debug(st,
"ni1up wrong CRef flag");
2980 if (!(proc = ni1_new_l3_process(st, cr))) {
3006 if (callState != 0) {
3012 if ((proc = ni1_new_l3_process(st, cr))) {
3013 proc->para.cause = 101;
3014 l3ni1_msg_without_setup(proc, 0,
NULL);
3028 if ((proc = ni1_new_l3_process(st, cr))) {
3029 proc->para.cause = 81;
3030 l3ni1_msg_without_setup(proc, 0,
NULL);
3035 if (l3ni1_check_messagetype_validity(proc, mt, skb)) {
3040 l3ni1_deliver_display(proc, pr, p);
3041 for (i = 0; i <
ARRAY_SIZE(datastatelist); i++)
3042 if ((mt == datastatelist[i].primitive) &&
3043 ((1 << proc->state) & datastatelist[i].state))
3047 l3_debug(st,
"ni1up%sstate %d mt %#x unhandled",
3052 proc->para.cause = 101;
3053 l3ni1_status_send(proc, pr, skb);
3057 l3_debug(st,
"ni1up%sstate %d mt %x",
3061 datastatelist[
i].
rout(proc, pr, skb);
3068 ni1down(
struct PStack *st,
int pr,
void *arg)
3071 struct l3_process *proc;
3081 if ((proc = ni1_new_l3_process(st, cr))) {
3096 l3ni1_io_timer(proc);
3100 for (i = 0; i <
ARRAY_SIZE(downstatelist); i++)
3101 if ((pr == downstatelist[i].primitive) &&
3102 ((1 << proc->state) & downstatelist[i].state))
3106 l3_debug(st,
"ni1down state %d prim %#x unhandled",
3111 l3_debug(st,
"ni1down state %d prim %#x",
3114 downstatelist[
i].
rout(proc, pr, arg);
3119 ni1man(
struct PStack *st,
int pr,
void *arg)
3122 struct l3_process *proc =
arg;
3128 for (i = 0; i <
ARRAY_SIZE(manstatelist); i++)
3129 if ((pr == manstatelist[i].primitive) &&
3130 ((1 << proc->state) & manstatelist[i].state))
3134 l3_debug(st,
"cr %d ni1man state %d prim %#x unhandled",
3135 proc->callref & 0x7f, proc->state, pr);
3139 l3_debug(st,
"cr %d ni1man state %d prim %#x",
3140 proc->callref & 0x7f, proc->state, pr);
3142 manstatelist[
i].
rout(proc, pr, arg);
3152 st->lli.l4l3 = ni1down;
3153 st->lli.l4l3_proto = l3ni1_cmd_global;
3154 st->l2.l2l3 = ni1up;
3155 st->l3.l3ml3 = ni1man;
3157 st->prot.ni1.last_invoke_id = 0;
3158 st->prot.ni1.invoke_used[0] = 1;
3161 st->prot.ni1.invoke_used[i++] = 0;
3166 st->l3.global->state = 0;
3167 st->l3.global->callref = 0;
3168 st->l3.global->next =
NULL;
3170 st->l3.global->st =
st;
3171 st->l3.global->N303 = 1;
3172 st->l3.global->prot.ni1.invoke_id = 0;
3174 L3InitTimer(st->l3.global, &st->l3.global->timer);
3176 strcpy(tmp, ni1_revision);