aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/mISDN/tei.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/mISDN/tei.c')
-rw-r--r--drivers/isdn/mISDN/tei.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
index c75af762a067..55a7c3dac3c2 100644
--- a/drivers/isdn/mISDN/tei.c
+++ b/drivers/isdn/mISDN/tei.c
@@ -426,7 +426,7 @@ done:
426} 426}
427 427
428static void 428static void
429put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, u_char tei) 429put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, int tei)
430{ 430{
431 struct sk_buff *skb; 431 struct sk_buff *skb;
432 u_char bp[8]; 432 u_char bp[8];
@@ -440,9 +440,8 @@ put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, u_char tei)
440 bp[4] = ri >> 8; 440 bp[4] = ri >> 8;
441 bp[5] = ri & 0xff; 441 bp[5] = ri & 0xff;
442 bp[6] = m_id; 442 bp[6] = m_id;
443 bp[7] = (tei << 1) | 1; 443 bp[7] = ((tei << 1) & 0xff) | 1;
444 skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr), 444 skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr), 8, bp, GFP_ATOMIC);
445 8, bp, GFP_ATOMIC);
446 if (!skb) { 445 if (!skb) {
447 printk(KERN_WARNING "%s: no skb for tei msg\n", __func__); 446 printk(KERN_WARNING "%s: no skb for tei msg\n", __func__);
448 return; 447 return;
@@ -777,7 +776,7 @@ tei_ph_data_ind(struct teimgr *tm, u_int mt, u_char *dp, int len)
777} 776}
778 777
779static struct layer2 * 778static struct layer2 *
780create_new_tei(struct manager *mgr, int tei) 779create_new_tei(struct manager *mgr, int tei, int sapi)
781{ 780{
782 u_long opt = 0; 781 u_long opt = 0;
783 u_long flags; 782 u_long flags;
@@ -786,12 +785,12 @@ create_new_tei(struct manager *mgr, int tei)
786 785
787 if (!mgr->up) 786 if (!mgr->up)
788 return NULL; 787 return NULL;
789 if (tei < 64) 788 if ((tei >= 0) && (tei < 64))
790 test_and_set_bit(OPTION_L2_FIXEDTEI, &opt); 789 test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
791 if (mgr->ch.st->dev->Dprotocols 790 if (mgr->ch.st->dev->Dprotocols
792 & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1))) 791 & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
793 test_and_set_bit(OPTION_L2_PMX, &opt); 792 test_and_set_bit(OPTION_L2_PMX, &opt);
794 l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, (u_int)opt, (u_long)tei); 793 l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, opt, tei, sapi);
795 if (!l2) { 794 if (!l2) {
796 printk(KERN_WARNING "%s:no memory for layer2\n", __func__); 795 printk(KERN_WARNING "%s:no memory for layer2\n", __func__);
797 return NULL; 796 return NULL;
@@ -839,12 +838,17 @@ new_tei_req(struct manager *mgr, u_char *dp)
839 ri += dp[1]; 838 ri += dp[1];
840 if (!mgr->up) 839 if (!mgr->up)
841 goto denied; 840 goto denied;
842 tei = get_free_tei(mgr); 841 if (!(dp[3] & 1)) /* Extension bit != 1 */
842 goto denied;
843 if (dp[3] != 0xff)
844 tei = dp[3] >> 1; /* 3GPP TS 08.56 6.1.11.2 */
845 else
846 tei = get_free_tei(mgr);
843 if (tei < 0) { 847 if (tei < 0) {
844 printk(KERN_WARNING "%s:No free tei\n", __func__); 848 printk(KERN_WARNING "%s:No free tei\n", __func__);
845 goto denied; 849 goto denied;
846 } 850 }
847 l2 = create_new_tei(mgr, tei); 851 l2 = create_new_tei(mgr, tei, CTRL_SAPI);
848 if (!l2) 852 if (!l2)
849 goto denied; 853 goto denied;
850 else 854 else
@@ -976,8 +980,6 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
976 __func__, dev_name(&mgr->ch.st->dev->dev), 980 __func__, dev_name(&mgr->ch.st->dev->dev),
977 crq->protocol, crq->adr.dev, crq->adr.channel, 981 crq->protocol, crq->adr.dev, crq->adr.channel,
978 crq->adr.sapi, crq->adr.tei); 982 crq->adr.sapi, crq->adr.tei);
979 if (crq->adr.sapi != 0) /* not supported yet */
980 return -EINVAL;
981 if (crq->adr.tei > GROUP_TEI) 983 if (crq->adr.tei > GROUP_TEI)
982 return -EINVAL; 984 return -EINVAL;
983 if (crq->adr.tei < 64) 985 if (crq->adr.tei < 64)
@@ -1024,8 +1026,8 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
1024 } 1026 }
1025 return 0; 1027 return 0;
1026 } 1028 }
1027 l2 = create_l2(crq->ch, crq->protocol, (u_int)opt, 1029 l2 = create_l2(crq->ch, crq->protocol, opt,
1028 (u_long)crq->adr.tei); 1030 crq->adr.tei, crq->adr.sapi);
1029 if (!l2) 1031 if (!l2)
1030 return -ENOMEM; 1032 return -ENOMEM;
1031 l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL); 1033 l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL);
@@ -1166,7 +1168,7 @@ static int
1166check_data(struct manager *mgr, struct sk_buff *skb) 1168check_data(struct manager *mgr, struct sk_buff *skb)
1167{ 1169{
1168 struct mISDNhead *hh = mISDN_HEAD_P(skb); 1170 struct mISDNhead *hh = mISDN_HEAD_P(skb);
1169 int ret, tei; 1171 int ret, tei, sapi;
1170 struct layer2 *l2; 1172 struct layer2 *l2;
1171 1173
1172 if (*debug & DEBUG_L2_CTRL) 1174 if (*debug & DEBUG_L2_CTRL)
@@ -1178,18 +1180,18 @@ check_data(struct manager *mgr, struct sk_buff *skb)
1178 return -ENOTCONN; 1180 return -ENOTCONN;
1179 if (skb->len != 3) 1181 if (skb->len != 3)
1180 return -ENOTCONN; 1182 return -ENOTCONN;
1181 if (skb->data[0] != 0) 1183 if (skb->data[0] & 3) /* EA0 and CR must be 0 */
1182 /* only SAPI 0 command */ 1184 return -EINVAL;
1183 return -ENOTCONN; 1185 sapi = skb->data[0] >> 2;
1184 if (!(skb->data[1] & 1)) /* invalid EA1 */ 1186 if (!(skb->data[1] & 1)) /* invalid EA1 */
1185 return -EINVAL; 1187 return -EINVAL;
1186 tei = skb->data[1] >> 0; 1188 tei = skb->data[1] >> 1;
1187 if (tei > 63) /* not a fixed tei */ 1189 if (tei > 63) /* not a fixed tei */
1188 return -ENOTCONN; 1190 return -ENOTCONN;
1189 if ((skb->data[2] & ~0x10) != SABME) 1191 if ((skb->data[2] & ~0x10) != SABME)
1190 return -ENOTCONN; 1192 return -ENOTCONN;
1191 /* We got a SABME for a fixed TEI */ 1193 /* We got a SABME for a fixed TEI */
1192 l2 = create_new_tei(mgr, tei); 1194 l2 = create_new_tei(mgr, tei, sapi);
1193 if (!l2) 1195 if (!l2)
1194 return -ENOMEM; 1196 return -ENOMEM;
1195 ret = l2->ch.send(&l2->ch, skb); 1197 ret = l2->ch.send(&l2->ch, skb);