2005-04-17 02:20:36 +04:00
/* $Id: l3_1tr6.c,v 2.15.2.3 2004/01/13 14:31:25 keil Exp $
*
* German 1 TR6 D - channel protocol
*
* Author Karsten Keil
* Copyright by Karsten Keil < keil @ isdn4linux . de >
2012-02-20 07:52:38 +04:00
*
2005-04-17 02:20:36 +04:00
* This software may be used and distributed according to the terms
* of the GNU General Public License , incorporated herein by reference .
*
* For changes and modifications please read
* Documentation / isdn / HiSax . cert
*
*/
# include "hisax.h"
# include "l3_1tr6.h"
# include "isdnl3.h"
# include <linux/ctype.h>
extern char * HiSax_getrev ( const char * revision ) ;
2005-06-26 01:59:18 +04:00
static const char * l3_1tr6_revision = " $Revision: 2.15.2.3 $ " ;
2005-04-17 02:20:36 +04:00
2012-02-20 07:52:38 +04:00
# define MsgHead(ptr, cref, mty, dis) \
* ptr + + = dis ; \
* ptr + + = 0x1 ; \
* ptr + + = cref ^ 0x80 ; \
2005-04-17 02:20:36 +04:00
* ptr + + = mty
static void
l3_1TR6_message ( struct l3_process * pc , u_char mt , u_char pd )
{
struct sk_buff * skb ;
u_char * p ;
if ( ! ( skb = l3_alloc_skb ( 4 ) ) )
return ;
p = skb_put ( skb , 4 ) ;
MsgHead ( p , pc - > callref , mt , pd ) ;
l3_msg ( pc - > st , DL_DATA | REQUEST , skb ) ;
}
static void
l3_1tr6_release_req ( struct l3_process * pc , u_char pr , void * arg )
{
StopAllL3Timer ( pc ) ;
newl3state ( pc , 19 ) ;
l3_1TR6_message ( pc , MT_N1_REL , PROTO_DIS_N1 ) ;
L3AddTimer ( & pc - > timer , T308 , CC_T308_1 ) ;
}
static void
l3_1tr6_invalid ( struct l3_process * pc , u_char pr , void * arg )
{
struct sk_buff * skb = arg ;
dev_kfree_skb ( skb ) ;
l3_1tr6_release_req ( pc , 0 , NULL ) ;
}
static void
l3_1tr6_error ( struct l3_process * pc , u_char * msg , struct sk_buff * skb )
{
dev_kfree_skb ( skb ) ;
if ( pc - > st - > l3 . debug & L3_DEB_WARN )
2013-09-14 01:52:04 +04:00
l3_debug ( pc - > st , " %s " , msg ) ;
2005-04-17 02:20:36 +04:00
l3_1tr6_release_req ( pc , 0 , NULL ) ;
}
static void
l3_1tr6_setup_req ( struct l3_process * pc , u_char pr , void * arg )
{
struct sk_buff * skb ;
u_char tmp [ 128 ] ;
u_char * p = tmp ;
u_char * teln ;
u_char * eaz ;
u_char channel = 0 ;
int l ;
MsgHead ( p , pc - > callref , MT_N1_SETUP , PROTO_DIS_N1 ) ;
teln = pc - > para . setup . phone ;
pc - > para . spv = 0 ;
if ( ! isdigit ( * teln ) ) {
switch ( 0x5f & * teln ) {
2012-02-20 07:52:38 +04:00
case ' S ' :
pc - > para . spv = 1 ;
break ;
case ' C ' :
channel = 0x08 ;
2018-07-04 00:17:31 +03:00
/* fall through */
2012-02-20 07:52:38 +04:00
case ' P ' :
channel | = 0x80 ;
teln + + ;
if ( * teln = = ' 1 ' )
channel | = 0x01 ;
else
channel | = 0x02 ;
break ;
default :
if ( pc - > st - > l3 . debug & L3_DEB_WARN )
l3_debug ( pc - > st , " Wrong MSN Code " ) ;
break ;
2005-04-17 02:20:36 +04:00
}
teln + + ;
}
if ( channel ) {
* p + + = 0x18 ; /* channel indicator */
* p + + = 1 ;
* p + + = channel ;
}
if ( pc - > para . spv ) { /* SPV ? */
/* NSF SPV */
* p + + = WE0_netSpecFac ;
* p + + = 4 ; /* Laenge */
* p + + = 0 ;
* p + + = FAC_SPV ; /* SPV */
* p + + = pc - > para . setup . si1 ; /* 0 for all Services */
* p + + = pc - > para . setup . si2 ; /* 0 for all Services */
* p + + = WE0_netSpecFac ;
* p + + = 4 ; /* Laenge */
* p + + = 0 ;
* p + + = FAC_Activate ; /* aktiviere SPV (default) */
* p + + = pc - > para . setup . si1 ; /* 0 for all Services */
* p + + = pc - > para . setup . si2 ; /* 0 for all Services */
}
eaz = pc - > para . setup . eazmsn ;
if ( * eaz ) {
* p + + = WE0_origAddr ;
* p + + = strlen ( eaz ) + 1 ;
/* Classify as AnyPref. */
* p + + = 0x81 ; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
while ( * eaz )
* p + + = * eaz + + & 0x7f ;
}
* p + + = WE0_destAddr ;
* p + + = strlen ( teln ) + 1 ;
/* Classify as AnyPref. */
* p + + = 0x81 ; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
while ( * teln )
* p + + = * teln + + & 0x7f ;
* p + + = WE_Shift_F6 ;
/* Codesatz 6 fuer Service */
* p + + = WE6_serviceInd ;
* p + + = 2 ; /* len=2 info,info2 */
* p + + = pc - > para . setup . si1 ;
* p + + = pc - > para . setup . si2 ;
l = p - tmp ;
if ( ! ( skb = l3_alloc_skb ( l ) ) )
return ;
networking: introduce and use skb_put_data()
A common pattern with skb_put() is to just want to memcpy()
some data into the new space, introduce skb_put_data() for
this.
An spatch similar to the one for skb_put_zero() converts many
of the places using it:
@@
identifier p, p2;
expression len, skb, data;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_data(skb, data, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_data(skb, data, len);
)
(
p2 = (t2)p;
-memcpy(p2, data, len);
|
-memcpy(p, data, len);
)
@@
type t, t2;
identifier p, p2;
expression skb, data;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_data(skb, data, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_data(skb, data, sizeof(t));
)
(
p2 = (t2)p;
-memcpy(p2, data, sizeof(*p));
|
-memcpy(p, data, sizeof(*p));
)
@@
expression skb, len, data;
@@
-memcpy(skb_put(skb, len), data, len);
+skb_put_data(skb, data, len);
(again, manually post-processed to retain some comments)
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:20 +03:00
skb_put_data ( skb , tmp , l ) ;
2005-04-17 02:20:36 +04:00
L3DelTimer ( & pc - > timer ) ;
L3AddTimer ( & pc - > timer , T303 , CC_T303 ) ;
newl3state ( pc , 1 ) ;
l3_msg ( pc - > st , DL_DATA | REQUEST , skb ) ;
}
static void
l3_1tr6_setup ( struct l3_process * pc , u_char pr , void * arg )
{
u_char * p ;
int bcfound = 0 ;
struct sk_buff * skb = arg ;
/* Channel Identification */
2010-10-26 06:20:56 +04:00
p = findie ( skb - > data , skb - > len , WE0_chanID , 0 ) ;
if ( p ) {
2005-04-17 02:20:36 +04:00
if ( p [ 1 ] ! = 1 ) {
l3_1tr6_error ( pc , " setup wrong chanID len " , skb ) ;
return ;
}
if ( ( p [ 2 ] & 0xf4 ) ! = 0x80 ) {
l3_1tr6_error ( pc , " setup wrong WE0_chanID " , skb ) ;
return ;
}
if ( ( pc - > para . bchannel = p [ 2 ] & 0x3 ) )
2012-02-20 07:52:38 +04:00
bcfound + + ;
2005-04-17 02:20:36 +04:00
} else {
l3_1tr6_error ( pc , " missing setup chanID " , skb ) ;
return ;
}
p = skb - > data ;
if ( ( p = findie ( p , skb - > len , WE6_serviceInd , 6 ) ) ) {
pc - > para . setup . si1 = p [ 2 ] ;
pc - > para . setup . si2 = p [ 3 ] ;
} else {
l3_1tr6_error ( pc , " missing setup SI " , skb ) ;
return ;
}
p = skb - > data ;
if ( ( p = findie ( p , skb - > len , WE0_destAddr , 0 ) ) )
iecpy ( pc - > para . setup . eazmsn , p , 1 ) ;
else
pc - > para . setup . eazmsn [ 0 ] = 0 ;
p = skb - > data ;
if ( ( p = findie ( p , skb - > len , WE0_origAddr , 0 ) ) ) {
iecpy ( pc - > para . setup . phone , p , 1 ) ;
} else
pc - > para . setup . phone [ 0 ] = 0 ;
p = skb - > data ;
pc - > para . spv = 0 ;
if ( ( p = findie ( p , skb - > len , WE0_netSpecFac , 0 ) ) ) {
if ( ( FAC_SPV = = p [ 3 ] ) | | ( FAC_Activate = = p [ 3 ] ) )
pc - > para . spv = 1 ;
}
dev_kfree_skb ( skb ) ;
/* Signal all services, linklevel takes care of Service-Indicator */
if ( bcfound ) {
if ( ( pc - > para . setup . si1 ! = 7 ) & & ( pc - > st - > l3 . debug & L3_DEB_WARN ) ) {
2013-09-14 01:52:04 +04:00
l3_debug ( pc - > st , " non-digital call: %s -> %s " ,
2005-04-17 02:20:36 +04:00
pc - > para . setup . phone ,
pc - > para . setup . eazmsn ) ;
}
newl3state ( pc , 6 ) ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_SETUP | INDICATION , pc ) ;
} else
release_l3_process ( pc ) ;
}
static void
l3_1tr6_setup_ack ( struct l3_process * pc , u_char pr , void * arg )
{
u_char * p ;
struct sk_buff * skb = arg ;
L3DelTimer ( & pc - > timer ) ;
p = skb - > data ;
newl3state ( pc , 2 ) ;
if ( ( p = findie ( p , skb - > len , WE0_chanID , 0 ) ) ) {
if ( p [ 1 ] ! = 1 ) {
l3_1tr6_error ( pc , " setup_ack wrong chanID len " , skb ) ;
return ;
}
if ( ( p [ 2 ] & 0xf4 ) ! = 0x80 ) {
l3_1tr6_error ( pc , " setup_ack wrong WE0_chanID " , skb ) ;
return ;
}
pc - > para . bchannel = p [ 2 ] & 0x3 ;
} else {
l3_1tr6_error ( pc , " missing setup_ack WE0_chanID " , skb ) ;
return ;
}
dev_kfree_skb ( skb ) ;
L3AddTimer ( & pc - > timer , T304 , CC_T304 ) ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_MORE_INFO | INDICATION , pc ) ;
}
static void
l3_1tr6_call_sent ( struct l3_process * pc , u_char pr , void * arg )
{
u_char * p ;
struct sk_buff * skb = arg ;
L3DelTimer ( & pc - > timer ) ;
p = skb - > data ;
if ( ( p = findie ( p , skb - > len , WE0_chanID , 0 ) ) ) {
if ( p [ 1 ] ! = 1 ) {
l3_1tr6_error ( pc , " call sent wrong chanID len " , skb ) ;
return ;
}
if ( ( p [ 2 ] & 0xf4 ) ! = 0x80 ) {
l3_1tr6_error ( pc , " call sent wrong WE0_chanID " , skb ) ;
return ;
}
if ( ( pc - > state = = 2 ) & & ( pc - > para . bchannel ! = ( p [ 2 ] & 0x3 ) ) ) {
l3_1tr6_error ( pc , " call sent wrong chanID value " , skb ) ;
return ;
}
pc - > para . bchannel = p [ 2 ] & 0x3 ;
} else {
l3_1tr6_error ( pc , " missing call sent WE0_chanID " , skb ) ;
return ;
}
dev_kfree_skb ( skb ) ;
L3AddTimer ( & pc - > timer , T310 , CC_T310 ) ;
newl3state ( pc , 3 ) ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_PROCEEDING | INDICATION , pc ) ;
}
static void
l3_1tr6_alert ( struct l3_process * pc , u_char pr , void * arg )
{
struct sk_buff * skb = arg ;
dev_kfree_skb ( skb ) ;
L3DelTimer ( & pc - > timer ) ; /* T304 */
newl3state ( pc , 4 ) ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_ALERTING | INDICATION , pc ) ;
}
static void
l3_1tr6_info ( struct l3_process * pc , u_char pr , void * arg )
{
u_char * p ;
int i , tmpcharge = 0 ;
2013-09-14 01:52:04 +04:00
char a_charge [ 8 ] ;
2005-04-17 02:20:36 +04:00
struct sk_buff * skb = arg ;
p = skb - > data ;
if ( ( p = findie ( p , skb - > len , WE6_chargingInfo , 6 ) ) ) {
iecpy ( a_charge , p , 1 ) ;
for ( i = 0 ; i < strlen ( a_charge ) ; i + + ) {
tmpcharge * = 10 ;
tmpcharge + = a_charge [ i ] & 0xf ;
}
if ( tmpcharge > pc - > para . chargeinfo ) {
pc - > para . chargeinfo = tmpcharge ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_CHARGE | INDICATION , pc ) ;
}
if ( pc - > st - > l3 . debug & L3_DEB_CHARGE ) {
2013-09-14 01:52:04 +04:00
l3_debug ( pc - > st , " charging info %d " ,
pc - > para . chargeinfo ) ;
2005-04-17 02:20:36 +04:00
}
} else if ( pc - > st - > l3 . debug & L3_DEB_CHARGE )
l3_debug ( pc - > st , " charging info not found " ) ;
dev_kfree_skb ( skb ) ;
}
static void
l3_1tr6_info_s2 ( struct l3_process * pc , u_char pr , void * arg )
{
struct sk_buff * skb = arg ;
dev_kfree_skb ( skb ) ;
}
static void
l3_1tr6_connect ( struct l3_process * pc , u_char pr , void * arg )
{
struct sk_buff * skb = arg ;
L3DelTimer ( & pc - > timer ) ; /* T310 */
if ( ! findie ( skb - > data , skb - > len , WE6_date , 6 ) ) {
l3_1tr6_error ( pc , " missing connect date " , skb ) ;
return ;
}
newl3state ( pc , 10 ) ;
dev_kfree_skb ( skb ) ;
pc - > para . chargeinfo = 0 ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_SETUP | CONFIRM , pc ) ;
}
static void
l3_1tr6_rel ( struct l3_process * pc , u_char pr , void * arg )
{
struct sk_buff * skb = arg ;
u_char * p ;
p = skb - > data ;
if ( ( p = findie ( p , skb - > len , WE0_cause , 0 ) ) ) {
if ( p [ 1 ] > 0 ) {
pc - > para . cause = p [ 2 ] ;
if ( p [ 1 ] > 1 )
pc - > para . loc = p [ 3 ] ;
else
pc - > para . loc = 0 ;
} else {
pc - > para . cause = 0 ;
pc - > para . loc = 0 ;
}
} else {
pc - > para . cause = NO_CAUSE ;
l3_1tr6_error ( pc , " missing REL cause " , skb ) ;
return ;
}
dev_kfree_skb ( skb ) ;
StopAllL3Timer ( pc ) ;
newl3state ( pc , 0 ) ;
l3_1TR6_message ( pc , MT_N1_REL_ACK , PROTO_DIS_N1 ) ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_RELEASE | INDICATION , pc ) ;
release_l3_process ( pc ) ;
}
static void
l3_1tr6_rel_ack ( struct l3_process * pc , u_char pr , void * arg )
{
struct sk_buff * skb = arg ;
dev_kfree_skb ( skb ) ;
StopAllL3Timer ( pc ) ;
newl3state ( pc , 0 ) ;
pc - > para . cause = NO_CAUSE ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_RELEASE | CONFIRM , pc ) ;
release_l3_process ( pc ) ;
}
static void
l3_1tr6_disc ( struct l3_process * pc , u_char pr , void * arg )
{
struct sk_buff * skb = arg ;
u_char * p ;
int i , tmpcharge = 0 ;
2013-09-14 01:52:04 +04:00
char a_charge [ 8 ] ;
2005-04-17 02:20:36 +04:00
StopAllL3Timer ( pc ) ;
p = skb - > data ;
if ( ( p = findie ( p , skb - > len , WE6_chargingInfo , 6 ) ) ) {
iecpy ( a_charge , p , 1 ) ;
for ( i = 0 ; i < strlen ( a_charge ) ; i + + ) {
tmpcharge * = 10 ;
tmpcharge + = a_charge [ i ] & 0xf ;
}
if ( tmpcharge > pc - > para . chargeinfo ) {
pc - > para . chargeinfo = tmpcharge ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_CHARGE | INDICATION , pc ) ;
}
if ( pc - > st - > l3 . debug & L3_DEB_CHARGE ) {
2013-09-14 01:52:04 +04:00
l3_debug ( pc - > st , " charging info %d " ,
pc - > para . chargeinfo ) ;
2005-04-17 02:20:36 +04:00
}
} else if ( pc - > st - > l3 . debug & L3_DEB_CHARGE )
l3_debug ( pc - > st , " charging info not found " ) ;
p = skb - > data ;
if ( ( p = findie ( p , skb - > len , WE0_cause , 0 ) ) ) {
if ( p [ 1 ] > 0 ) {
pc - > para . cause = p [ 2 ] ;
if ( p [ 1 ] > 1 )
pc - > para . loc = p [ 3 ] ;
else
pc - > para . loc = 0 ;
} else {
pc - > para . cause = 0 ;
pc - > para . loc = 0 ;
}
} else {
if ( pc - > st - > l3 . debug & L3_DEB_WARN )
l3_debug ( pc - > st , " cause not found " ) ;
pc - > para . cause = NO_CAUSE ;
}
if ( ! findie ( skb - > data , skb - > len , WE6_date , 6 ) ) {
l3_1tr6_error ( pc , " missing connack date " , skb ) ;
return ;
}
dev_kfree_skb ( skb ) ;
newl3state ( pc , 12 ) ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_DISCONNECT | INDICATION , pc ) ;
}
static void
l3_1tr6_connect_ack ( struct l3_process * pc , u_char pr , void * arg )
{
struct sk_buff * skb = arg ;
if ( ! findie ( skb - > data , skb - > len , WE6_date , 6 ) ) {
l3_1tr6_error ( pc , " missing connack date " , skb ) ;
return ;
}
dev_kfree_skb ( skb ) ;
newl3state ( pc , 10 ) ;
pc - > para . chargeinfo = 0 ;
L3DelTimer ( & pc - > timer ) ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_SETUP_COMPL | INDICATION , pc ) ;
}
static void
l3_1tr6_alert_req ( struct l3_process * pc , u_char pr , void * arg )
{
newl3state ( pc , 7 ) ;
l3_1TR6_message ( pc , MT_N1_ALERT , PROTO_DIS_N1 ) ;
}
static void
l3_1tr6_setup_rsp ( struct l3_process * pc , u_char pr , void * arg )
{
struct sk_buff * skb ;
u_char tmp [ 24 ] ;
u_char * p = tmp ;
int l ;
MsgHead ( p , pc - > callref , MT_N1_CONN , PROTO_DIS_N1 ) ;
if ( pc - > para . spv ) { /* SPV ? */
/* NSF SPV */
* p + + = WE0_netSpecFac ;
* p + + = 4 ; /* Laenge */
* p + + = 0 ;
* p + + = FAC_SPV ; /* SPV */
* p + + = pc - > para . setup . si1 ;
* p + + = pc - > para . setup . si2 ;
* p + + = WE0_netSpecFac ;
* p + + = 4 ; /* Laenge */
* p + + = 0 ;
* p + + = FAC_Activate ; /* aktiviere SPV */
* p + + = pc - > para . setup . si1 ;
* p + + = pc - > para . setup . si2 ;
}
newl3state ( pc , 8 ) ;
l = p - tmp ;
if ( ! ( skb = l3_alloc_skb ( l ) ) )
return ;
networking: introduce and use skb_put_data()
A common pattern with skb_put() is to just want to memcpy()
some data into the new space, introduce skb_put_data() for
this.
An spatch similar to the one for skb_put_zero() converts many
of the places using it:
@@
identifier p, p2;
expression len, skb, data;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_data(skb, data, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_data(skb, data, len);
)
(
p2 = (t2)p;
-memcpy(p2, data, len);
|
-memcpy(p, data, len);
)
@@
type t, t2;
identifier p, p2;
expression skb, data;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_data(skb, data, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_data(skb, data, sizeof(t));
)
(
p2 = (t2)p;
-memcpy(p2, data, sizeof(*p));
|
-memcpy(p, data, sizeof(*p));
)
@@
expression skb, len, data;
@@
-memcpy(skb_put(skb, len), data, len);
+skb_put_data(skb, data, len);
(again, manually post-processed to retain some comments)
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:20 +03:00
skb_put_data ( skb , tmp , l ) ;
2005-04-17 02:20:36 +04:00
l3_msg ( pc - > st , DL_DATA | REQUEST , skb ) ;
L3DelTimer ( & pc - > timer ) ;
L3AddTimer ( & pc - > timer , T313 , CC_T313 ) ;
}
static void
l3_1tr6_reset ( struct l3_process * pc , u_char pr , void * arg )
{
release_l3_process ( pc ) ;
}
static void
l3_1tr6_disconnect_req ( struct l3_process * pc , u_char pr , void * arg )
{
struct sk_buff * skb ;
u_char tmp [ 16 ] ;
u_char * p = tmp ;
int l ;
u_char cause = 0x10 ;
u_char clen = 1 ;
if ( pc - > para . cause > 0 )
cause = pc - > para . cause ;
/* Map DSS1 causes */
switch ( cause & 0x7f ) {
2012-02-20 07:52:38 +04:00
case 0x10 :
clen = 0 ;
break ;
case 0x11 :
cause = CAUSE_UserBusy ;
break ;
case 0x15 :
cause = CAUSE_CallRejected ;
break ;
2005-04-17 02:20:36 +04:00
}
StopAllL3Timer ( pc ) ;
MsgHead ( p , pc - > callref , MT_N1_DISC , PROTO_DIS_N1 ) ;
* p + + = WE0_cause ;
* p + + = clen ; /* Laenge */
if ( clen )
* p + + = cause | 0x80 ;
newl3state ( pc , 11 ) ;
l = p - tmp ;
if ( ! ( skb = l3_alloc_skb ( l ) ) )
return ;
networking: introduce and use skb_put_data()
A common pattern with skb_put() is to just want to memcpy()
some data into the new space, introduce skb_put_data() for
this.
An spatch similar to the one for skb_put_zero() converts many
of the places using it:
@@
identifier p, p2;
expression len, skb, data;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_data(skb, data, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_data(skb, data, len);
)
(
p2 = (t2)p;
-memcpy(p2, data, len);
|
-memcpy(p, data, len);
)
@@
type t, t2;
identifier p, p2;
expression skb, data;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_data(skb, data, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_data(skb, data, sizeof(t));
)
(
p2 = (t2)p;
-memcpy(p2, data, sizeof(*p));
|
-memcpy(p, data, sizeof(*p));
)
@@
expression skb, len, data;
@@
-memcpy(skb_put(skb, len), data, len);
+skb_put_data(skb, data, len);
(again, manually post-processed to retain some comments)
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:20 +03:00
skb_put_data ( skb , tmp , l ) ;
2005-04-17 02:20:36 +04:00
l3_msg ( pc - > st , DL_DATA | REQUEST , skb ) ;
L3AddTimer ( & pc - > timer , T305 , CC_T305 ) ;
}
static void
l3_1tr6_t303 ( struct l3_process * pc , u_char pr , void * arg )
{
if ( pc - > N303 > 0 ) {
pc - > N303 - - ;
L3DelTimer ( & pc - > timer ) ;
l3_1tr6_setup_req ( pc , pr , arg ) ;
} else {
L3DelTimer ( & pc - > timer ) ;
pc - > para . cause = 0 ;
l3_1tr6_disconnect_req ( pc , 0 , NULL ) ;
}
}
static void
l3_1tr6_t304 ( struct l3_process * pc , u_char pr , void * arg )
{
L3DelTimer ( & pc - > timer ) ;
pc - > para . cause = 0xE6 ;
l3_1tr6_disconnect_req ( pc , pr , NULL ) ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_SETUP_ERR , pc ) ;
}
static void
l3_1tr6_t305 ( struct l3_process * pc , u_char pr , void * arg )
{
struct sk_buff * skb ;
u_char tmp [ 16 ] ;
u_char * p = tmp ;
int l ;
u_char cause = 0x90 ;
u_char clen = 1 ;
L3DelTimer ( & pc - > timer ) ;
if ( pc - > para . cause ! = NO_CAUSE )
cause = pc - > para . cause ;
/* Map DSS1 causes */
switch ( cause & 0x7f ) {
2012-02-20 07:52:38 +04:00
case 0x10 :
clen = 0 ;
break ;
case 0x15 :
cause = CAUSE_CallRejected ;
break ;
2005-04-17 02:20:36 +04:00
}
MsgHead ( p , pc - > callref , MT_N1_REL , PROTO_DIS_N1 ) ;
* p + + = WE0_cause ;
* p + + = clen ; /* Laenge */
if ( clen )
* p + + = cause ;
newl3state ( pc , 19 ) ;
l = p - tmp ;
if ( ! ( skb = l3_alloc_skb ( l ) ) )
return ;
networking: introduce and use skb_put_data()
A common pattern with skb_put() is to just want to memcpy()
some data into the new space, introduce skb_put_data() for
this.
An spatch similar to the one for skb_put_zero() converts many
of the places using it:
@@
identifier p, p2;
expression len, skb, data;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_data(skb, data, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_data(skb, data, len);
)
(
p2 = (t2)p;
-memcpy(p2, data, len);
|
-memcpy(p, data, len);
)
@@
type t, t2;
identifier p, p2;
expression skb, data;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_data(skb, data, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_data(skb, data, sizeof(t));
)
(
p2 = (t2)p;
-memcpy(p2, data, sizeof(*p));
|
-memcpy(p, data, sizeof(*p));
)
@@
expression skb, len, data;
@@
-memcpy(skb_put(skb, len), data, len);
+skb_put_data(skb, data, len);
(again, manually post-processed to retain some comments)
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:20 +03:00
skb_put_data ( skb , tmp , l ) ;
2005-04-17 02:20:36 +04:00
l3_msg ( pc - > st , DL_DATA | REQUEST , skb ) ;
L3AddTimer ( & pc - > timer , T308 , CC_T308_1 ) ;
}
static void
l3_1tr6_t310 ( struct l3_process * pc , u_char pr , void * arg )
{
L3DelTimer ( & pc - > timer ) ;
pc - > para . cause = 0xE6 ;
l3_1tr6_disconnect_req ( pc , pr , NULL ) ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_SETUP_ERR , pc ) ;
}
static void
l3_1tr6_t313 ( struct l3_process * pc , u_char pr , void * arg )
{
L3DelTimer ( & pc - > timer ) ;
pc - > para . cause = 0xE6 ;
l3_1tr6_disconnect_req ( pc , pr , NULL ) ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_CONNECT_ERR , pc ) ;
}
static void
l3_1tr6_t308_1 ( struct l3_process * pc , u_char pr , void * arg )
{
L3DelTimer ( & pc - > timer ) ;
l3_1TR6_message ( pc , MT_N1_REL , PROTO_DIS_N1 ) ;
L3AddTimer ( & pc - > timer , T308 , CC_T308_2 ) ;
newl3state ( pc , 19 ) ;
}
static void
l3_1tr6_t308_2 ( struct l3_process * pc , u_char pr , void * arg )
{
L3DelTimer ( & pc - > timer ) ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_RELEASE_ERR , pc ) ;
release_l3_process ( pc ) ;
}
static void
l3_1tr6_dl_reset ( struct l3_process * pc , u_char pr , void * arg )
{
2012-02-20 07:52:38 +04:00
pc - > para . cause = CAUSE_LocalProcErr ;
l3_1tr6_disconnect_req ( pc , pr , NULL ) ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_SETUP_ERR , pc ) ;
2005-04-17 02:20:36 +04:00
}
static void
l3_1tr6_dl_release ( struct l3_process * pc , u_char pr , void * arg )
{
2012-02-20 07:52:38 +04:00
newl3state ( pc , 0 ) ;
pc - > para . cause = 0x1b ; /* Destination out of order */
pc - > para . loc = 0 ;
pc - > st - > l3 . l3l4 ( pc - > st , CC_RELEASE | INDICATION , pc ) ;
release_l3_process ( pc ) ;
2005-04-17 02:20:36 +04:00
}
/* *INDENT-OFF* */
static struct stateentry downstl [ ] =
{
{ SBIT ( 0 ) ,
CC_SETUP | REQUEST , l3_1tr6_setup_req } ,
2012-02-20 07:52:38 +04:00
{ SBIT ( 1 ) | SBIT ( 2 ) | SBIT ( 3 ) | SBIT ( 4 ) | SBIT ( 6 ) | SBIT ( 7 ) | SBIT ( 8 ) |
SBIT ( 10 ) ,
CC_DISCONNECT | REQUEST , l3_1tr6_disconnect_req } ,
2005-04-17 02:20:36 +04:00
{ SBIT ( 12 ) ,
CC_RELEASE | REQUEST , l3_1tr6_release_req } ,
{ SBIT ( 6 ) ,
CC_IGNORE | REQUEST , l3_1tr6_reset } ,
{ SBIT ( 6 ) ,
CC_REJECT | REQUEST , l3_1tr6_disconnect_req } ,
{ SBIT ( 6 ) ,
CC_ALERTING | REQUEST , l3_1tr6_alert_req } ,
{ SBIT ( 6 ) | SBIT ( 7 ) ,
CC_SETUP | RESPONSE , l3_1tr6_setup_rsp } ,
{ SBIT ( 1 ) ,
CC_T303 , l3_1tr6_t303 } ,
{ SBIT ( 2 ) ,
CC_T304 , l3_1tr6_t304 } ,
{ SBIT ( 3 ) ,
CC_T310 , l3_1tr6_t310 } ,
{ SBIT ( 8 ) ,
CC_T313 , l3_1tr6_t313 } ,
{ SBIT ( 11 ) ,
CC_T305 , l3_1tr6_t305 } ,
{ SBIT ( 19 ) ,
CC_T308_1 , l3_1tr6_t308_1 } ,
{ SBIT ( 19 ) ,
CC_T308_2 , l3_1tr6_t308_2 } ,
} ;
static struct stateentry datastln1 [ ] =
{
{ SBIT ( 0 ) ,
MT_N1_INVALID , l3_1tr6_invalid } ,
{ SBIT ( 0 ) ,
MT_N1_SETUP , l3_1tr6_setup } ,
{ SBIT ( 1 ) ,
MT_N1_SETUP_ACK , l3_1tr6_setup_ack } ,
{ SBIT ( 1 ) | SBIT ( 2 ) ,
MT_N1_CALL_SENT , l3_1tr6_call_sent } ,
{ SBIT ( 1 ) | SBIT ( 2 ) | SBIT ( 3 ) | SBIT ( 4 ) | SBIT ( 7 ) | SBIT ( 8 ) | SBIT ( 10 ) ,
MT_N1_DISC , l3_1tr6_disc } ,
{ SBIT ( 2 ) | SBIT ( 3 ) | SBIT ( 4 ) ,
MT_N1_ALERT , l3_1tr6_alert } ,
{ SBIT ( 2 ) | SBIT ( 3 ) | SBIT ( 4 ) ,
MT_N1_CONN , l3_1tr6_connect } ,
{ SBIT ( 2 ) ,
MT_N1_INFO , l3_1tr6_info_s2 } ,
{ SBIT ( 8 ) ,
MT_N1_CONN_ACK , l3_1tr6_connect_ack } ,
{ SBIT ( 10 ) ,
MT_N1_INFO , l3_1tr6_info } ,
{ SBIT ( 0 ) | SBIT ( 1 ) | SBIT ( 2 ) | SBIT ( 3 ) | SBIT ( 4 ) | SBIT ( 7 ) | SBIT ( 8 ) |
SBIT ( 10 ) | SBIT ( 11 ) | SBIT ( 12 ) | SBIT ( 15 ) | SBIT ( 17 ) ,
MT_N1_REL , l3_1tr6_rel } ,
{ SBIT ( 19 ) ,
MT_N1_REL , l3_1tr6_rel_ack } ,
{ SBIT ( 0 ) | SBIT ( 1 ) | SBIT ( 2 ) | SBIT ( 3 ) | SBIT ( 4 ) | SBIT ( 7 ) | SBIT ( 8 ) |
SBIT ( 10 ) | SBIT ( 11 ) | SBIT ( 12 ) | SBIT ( 15 ) | SBIT ( 17 ) ,
MT_N1_REL_ACK , l3_1tr6_invalid } ,
{ SBIT ( 19 ) ,
MT_N1_REL_ACK , l3_1tr6_rel_ack }
} ;
static struct stateentry manstatelist [ ] =
{
2012-02-20 07:52:38 +04:00
{ SBIT ( 2 ) ,
DL_ESTABLISH | INDICATION , l3_1tr6_dl_reset } ,
{ ALL_STATES ,
DL_RELEASE | INDICATION , l3_1tr6_dl_release } ,
2005-04-17 02:20:36 +04:00
} ;
2012-02-20 07:52:38 +04:00
2005-04-17 02:20:36 +04:00
/* *INDENT-ON* */
static void
up1tr6 ( struct PStack * st , int pr , void * arg )
{
int i , mt , cr ;
struct l3_process * proc ;
struct sk_buff * skb = arg ;
switch ( pr ) {
2012-02-20 07:52:38 +04:00
case ( DL_DATA | INDICATION ) :
case ( DL_UNIT_DATA | INDICATION ) :
break ;
case ( DL_ESTABLISH | CONFIRM ) :
case ( DL_ESTABLISH | INDICATION ) :
case ( DL_RELEASE | INDICATION ) :
case ( DL_RELEASE | CONFIRM ) :
l3_msg ( st , pr , arg ) ;
return ;
break ;
2005-04-17 02:20:36 +04:00
}
if ( skb - > len < 4 ) {
if ( st - > l3 . debug & L3_DEB_PROTERR ) {
2013-09-14 01:52:04 +04:00
l3_debug ( st , " up1tr6 len only %d " , skb - > len ) ;
2005-04-17 02:20:36 +04:00
}
dev_kfree_skb ( skb ) ;
return ;
}
if ( ( skb - > data [ 0 ] & 0xfe ) ! = PROTO_DIS_N0 ) {
if ( st - > l3 . debug & L3_DEB_PROTERR ) {
2013-09-14 01:52:04 +04:00
l3_debug ( st , " up1tr6%sunexpected discriminator %x message len %d " ,
2005-04-17 02:20:36 +04:00
( pr = = ( DL_DATA | INDICATION ) ) ? " " : " (broadcast) " ,
skb - > data [ 0 ] , skb - > len ) ;
}
dev_kfree_skb ( skb ) ;
return ;
}
if ( skb - > data [ 1 ] ! = 1 ) {
if ( st - > l3 . debug & L3_DEB_PROTERR ) {
2013-09-14 01:52:04 +04:00
l3_debug ( st , " up1tr6 CR len not 1 " ) ;
2005-04-17 02:20:36 +04:00
}
dev_kfree_skb ( skb ) ;
return ;
}
cr = skb - > data [ 2 ] ;
mt = skb - > data [ 3 ] ;
if ( skb - > data [ 0 ] = = PROTO_DIS_N0 ) {
dev_kfree_skb ( skb ) ;
if ( st - > l3 . debug & L3_DEB_STATE ) {
2013-09-14 01:52:04 +04:00
l3_debug ( st , " up1tr6%s N0 mt %x unhandled " ,
2012-02-20 07:52:38 +04:00
( pr = = ( DL_DATA | INDICATION ) ) ? " " : " (broadcast) " , mt ) ;
2005-04-17 02:20:36 +04:00
}
} else if ( skb - > data [ 0 ] = = PROTO_DIS_N1 ) {
if ( ! ( proc = getl3proc ( st , cr ) ) ) {
2012-02-20 07:52:38 +04:00
if ( mt = = MT_N1_SETUP ) {
2005-04-17 02:20:36 +04:00
if ( cr < 128 ) {
if ( ! ( proc = new_l3_process ( st , cr ) ) ) {
if ( st - > l3 . debug & L3_DEB_PROTERR ) {
2013-09-14 01:52:04 +04:00
l3_debug ( st , " up1tr6 no roc mem " ) ;
2005-04-17 02:20:36 +04:00
}
dev_kfree_skb ( skb ) ;
return ;
}
} else {
dev_kfree_skb ( skb ) ;
return ;
}
} else if ( ( mt = = MT_N1_REL ) | | ( mt = = MT_N1_REL_ACK ) | |
2012-02-20 07:52:38 +04:00
( mt = = MT_N1_CANC_ACK ) | | ( mt = = MT_N1_CANC_REJ ) | |
( mt = = MT_N1_REG_ACK ) | | ( mt = = MT_N1_REG_REJ ) | |
( mt = = MT_N1_SUSP_ACK ) | | ( mt = = MT_N1_RES_REJ ) | |
( mt = = MT_N1_INFO ) ) {
2005-04-17 02:20:36 +04:00
dev_kfree_skb ( skb ) ;
return ;
} else {
if ( ! ( proc = new_l3_process ( st , cr ) ) ) {
if ( st - > l3 . debug & L3_DEB_PROTERR ) {
2013-09-14 01:52:04 +04:00
l3_debug ( st , " up1tr6 no roc mem " ) ;
2005-04-17 02:20:36 +04:00
}
dev_kfree_skb ( skb ) ;
return ;
}
mt = MT_N1_INVALID ;
}
}
2009-07-24 20:26:08 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( datastln1 ) ; i + + )
2005-04-17 02:20:36 +04:00
if ( ( mt = = datastln1 [ i ] . primitive ) & &
( ( 1 < < proc - > state ) & datastln1 [ i ] . state ) )
break ;
2009-07-24 20:26:08 +04:00
if ( i = = ARRAY_SIZE ( datastln1 ) ) {
2005-04-17 02:20:36 +04:00
dev_kfree_skb ( skb ) ;
if ( st - > l3 . debug & L3_DEB_STATE ) {
2013-09-14 01:52:04 +04:00
l3_debug ( st , " up1tr6%sstate %d mt %x unhandled " ,
2012-02-20 07:52:38 +04:00
( pr = = ( DL_DATA | INDICATION ) ) ? " " : " (broadcast) " ,
2005-04-17 02:20:36 +04:00
proc - > state , mt ) ;
}
return ;
} else {
if ( st - > l3 . debug & L3_DEB_STATE ) {
2013-09-14 01:52:04 +04:00
l3_debug ( st , " up1tr6%sstate %d mt %x " ,
2012-02-20 07:52:38 +04:00
( pr = = ( DL_DATA | INDICATION ) ) ? " " : " (broadcast) " ,
2005-04-17 02:20:36 +04:00
proc - > state , mt ) ;
}
datastln1 [ i ] . rout ( proc , pr , skb ) ;
}
}
}
static void
down1tr6 ( struct PStack * st , int pr , void * arg )
{
int i , cr ;
struct l3_process * proc ;
struct Channel * chan ;
2012-02-20 07:52:38 +04:00
if ( ( DL_ESTABLISH | REQUEST ) = = pr ) {
2005-04-17 02:20:36 +04:00
l3_msg ( st , pr , NULL ) ;
return ;
} else if ( ( CC_SETUP | REQUEST ) = = pr ) {
chan = arg ;
cr = newcallref ( ) ;
cr | = 0x80 ;
if ( ! ( proc = new_l3_process ( st , cr ) ) ) {
return ;
} else {
proc - > chan = chan ;
chan - > proc = proc ;
memcpy ( & proc - > para . setup , & chan - > setup , sizeof ( setup_parm ) ) ;
proc - > callref = cr ;
}
} else {
proc = arg ;
}
2009-07-24 20:26:08 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( downstl ) ; i + + )
2005-04-17 02:20:36 +04:00
if ( ( pr = = downstl [ i ] . primitive ) & &
( ( 1 < < proc - > state ) & downstl [ i ] . state ) )
break ;
2009-07-24 20:26:08 +04:00
if ( i = = ARRAY_SIZE ( downstl ) ) {
2005-04-17 02:20:36 +04:00
if ( st - > l3 . debug & L3_DEB_STATE ) {
2013-09-14 01:52:04 +04:00
l3_debug ( st , " down1tr6 state %d prim %d unhandled " ,
2005-04-17 02:20:36 +04:00
proc - > state , pr ) ;
}
} else {
if ( st - > l3 . debug & L3_DEB_STATE ) {
2013-09-14 01:52:04 +04:00
l3_debug ( st , " down1tr6 state %d prim %d " ,
2005-04-17 02:20:36 +04:00
proc - > state , pr ) ;
}
downstl [ i ] . rout ( proc , pr , arg ) ;
}
}
static void
man1tr6 ( struct PStack * st , int pr , void * arg )
{
2012-02-20 07:52:38 +04:00
int i ;
struct l3_process * proc = arg ;
if ( ! proc ) {
printk ( KERN_ERR " HiSax man1tr6 without proc pr=%04x \n " , pr ) ;
return ;
}
for ( i = 0 ; i < ARRAY_SIZE ( manstatelist ) ; i + + )
if ( ( pr = = manstatelist [ i ] . primitive ) & &
( ( 1 < < proc - > state ) & manstatelist [ i ] . state ) )
break ;
if ( i = = ARRAY_SIZE ( manstatelist ) ) {
if ( st - > l3 . debug & L3_DEB_STATE ) {
l3_debug ( st , " cr %d man1tr6 state %d prim %d unhandled " ,
proc - > callref & 0x7f , proc - > state , pr ) ;
}
} else {
if ( st - > l3 . debug & L3_DEB_STATE ) {
l3_debug ( st , " cr %d man1tr6 state %d prim %d " ,
proc - > callref & 0x7f , proc - > state , pr ) ;
}
manstatelist [ i ] . rout ( proc , pr , arg ) ;
}
}
2005-04-17 02:20:36 +04:00
void
setstack_1tr6 ( struct PStack * st )
{
char tmp [ 64 ] ;
st - > lli . l4l3 = down1tr6 ;
st - > l2 . l2l3 = up1tr6 ;
st - > l3 . l3ml3 = man1tr6 ;
st - > l3 . N303 = 0 ;
strcpy ( tmp , l3_1tr6_revision ) ;
printk ( KERN_INFO " HiSax: 1TR6 Rev. %s \n " , HiSax_getrev ( tmp ) ) ;
}