2005-04-17 02:20:36 +04:00
/*********************************************************************
2007-02-09 17:24:53 +03:00
*
2005-04-17 02:20:36 +04:00
* Filename : irlan_provider_event . c
* Version : 0.9
* Description : IrLAN provider state machine )
* Status : Experimental .
* Author : Dag Brattli < dagb @ cs . uit . no >
* Created at : Sun Aug 31 20 : 14 : 37 1997
* Modified at : Sat Oct 30 12 : 52 : 41 1999
* Modified by : Dag Brattli < dagb @ cs . uit . no >
2007-02-09 17:24:53 +03:00
*
2005-04-17 02:20:36 +04:00
* Copyright ( c ) 1998 - 1999 Dag Brattli < dagb @ cs . uit . no > , All Rights Reserved .
2007-02-09 17:24:53 +03:00
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation ; either version 2 of
2005-04-17 02:20:36 +04:00
* the License , or ( at your option ) any later version .
*
2007-10-20 01:21:04 +04:00
* Neither Dag Brattli nor University of Tromsø admit liability nor
2007-02-09 17:24:53 +03:00
* provide warranty for any of this software . This material is
2005-04-17 02:20:36 +04:00
* provided " AS-IS " and at no charge .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <net/irda/irda.h>
# include <net/irda/iriap.h>
# include <net/irda/irlmp.h>
# include <net/irda/irttp.h>
# include <net/irda/irlan_provider.h>
# include <net/irda/irlan_event.h>
2007-02-09 17:24:53 +03:00
static int irlan_provider_state_idle ( struct irlan_cb * self , IRLAN_EVENT event ,
2005-04-17 02:20:36 +04:00
struct sk_buff * skb ) ;
2007-02-09 17:24:53 +03:00
static int irlan_provider_state_info ( struct irlan_cb * self , IRLAN_EVENT event ,
2005-04-17 02:20:36 +04:00
struct sk_buff * skb ) ;
2007-02-09 17:24:53 +03:00
static int irlan_provider_state_open ( struct irlan_cb * self , IRLAN_EVENT event ,
2005-04-17 02:20:36 +04:00
struct sk_buff * skb ) ;
2007-02-09 17:24:53 +03:00
static int irlan_provider_state_data ( struct irlan_cb * self , IRLAN_EVENT event ,
2005-04-17 02:20:36 +04:00
struct sk_buff * skb ) ;
2007-02-09 17:24:53 +03:00
static int ( * state [ ] ) ( struct irlan_cb * self , IRLAN_EVENT event ,
struct sk_buff * skb ) =
{
2005-04-17 02:20:36 +04:00
irlan_provider_state_idle ,
NULL , /* Query */
NULL , /* Info */
irlan_provider_state_info ,
NULL , /* Media */
irlan_provider_state_open ,
NULL , /* Wait */
NULL , /* Arb */
irlan_provider_state_data ,
NULL , /* Close */
NULL , /* Sync */
} ;
2007-02-09 17:24:53 +03:00
void irlan_do_provider_event ( struct irlan_cb * self , IRLAN_EVENT event ,
struct sk_buff * skb )
2005-04-17 02:20:36 +04:00
{
IRDA_ASSERT ( * state [ self - > provider . state ] ! = NULL , return ; ) ;
( * state [ self - > provider . state ] ) ( self , event , skb ) ;
}
/*
* Function irlan_provider_state_idle ( event , skb , info )
*
* IDLE , We are waiting for an indication that there is a provider
* available .
*/
static int irlan_provider_state_idle ( struct irlan_cb * self , IRLAN_EVENT event ,
struct sk_buff * skb )
{
2008-03-06 07:47:47 +03:00
IRDA_DEBUG ( 4 , " %s() \n " , __func__ ) ;
2007-02-09 17:24:53 +03:00
2005-04-17 02:20:36 +04:00
IRDA_ASSERT ( self ! = NULL , return - 1 ; ) ;
2007-02-09 17:24:53 +03:00
2005-04-17 02:20:36 +04:00
switch ( event ) {
case IRLAN_CONNECT_INDICATION :
irlan_provider_connect_response ( self , self - > provider . tsap_ctrl ) ;
irlan_next_provider_state ( self , IRLAN_INFO ) ;
break ;
default :
2008-03-06 07:47:47 +03:00
IRDA_DEBUG ( 4 , " %s(), Unknown event %d \n " , __func__ , event ) ;
2005-04-17 02:20:36 +04:00
break ;
}
if ( skb )
dev_kfree_skb ( skb ) ;
return 0 ;
}
/*
* Function irlan_provider_state_info ( self , event , skb , info )
*
* INFO , We have issued a GetInfo command and is awaiting a reply .
*/
2007-02-09 17:24:53 +03:00
static int irlan_provider_state_info ( struct irlan_cb * self , IRLAN_EVENT event ,
struct sk_buff * skb )
2005-04-17 02:20:36 +04:00
{
int ret ;
2008-03-06 07:47:47 +03:00
IRDA_DEBUG ( 4 , " %s() \n " , __func__ ) ;
2007-02-09 17:24:53 +03:00
2005-04-17 02:20:36 +04:00
IRDA_ASSERT ( self ! = NULL , return - 1 ; ) ;
switch ( event ) {
case IRLAN_GET_INFO_CMD :
/* Be sure to use 802.3 in case of peer mode */
if ( self - > provider . access_type = = ACCESS_PEER ) {
self - > media = MEDIA_802_3 ;
2007-02-09 17:24:53 +03:00
2005-04-17 02:20:36 +04:00
/* Check if client has started yet */
if ( self - > client . state = = IRLAN_IDLE ) {
/* This should get the client going */
irlmp_discovery_request ( 8 ) ;
}
}
2007-02-09 17:24:53 +03:00
irlan_provider_send_reply ( self , CMD_GET_PROVIDER_INFO ,
2005-04-17 02:20:36 +04:00
RSP_SUCCESS ) ;
/* Keep state */
break ;
2007-02-09 17:24:53 +03:00
case IRLAN_GET_MEDIA_CMD :
irlan_provider_send_reply ( self , CMD_GET_MEDIA_CHAR ,
2005-04-17 02:20:36 +04:00
RSP_SUCCESS ) ;
/* Keep state */
2007-02-09 17:24:53 +03:00
break ;
2005-04-17 02:20:36 +04:00
case IRLAN_OPEN_DATA_CMD :
ret = irlan_parse_open_data_cmd ( self , skb ) ;
if ( self - > provider . access_type = = ACCESS_PEER ) {
/* FIXME: make use of random functions! */
self - > provider . send_arb_val = ( jiffies & 0xffff ) ;
}
irlan_provider_send_reply ( self , CMD_OPEN_DATA_CHANNEL , ret ) ;
if ( ret = = RSP_SUCCESS ) {
irlan_next_provider_state ( self , IRLAN_OPEN ) ;
/* Signal client that we are now open */
irlan_do_client_event ( self , IRLAN_PROVIDER_SIGNAL , NULL ) ;
}
break ;
case IRLAN_LMP_DISCONNECT : /* FALLTHROUGH */
case IRLAN_LAP_DISCONNECT :
irlan_next_provider_state ( self , IRLAN_IDLE ) ;
break ;
default :
2008-03-06 07:47:47 +03:00
IRDA_DEBUG ( 0 , " %s(), Unknown event %d \n " , __func__ , event ) ;
2005-04-17 02:20:36 +04:00
break ;
}
if ( skb )
dev_kfree_skb ( skb ) ;
2007-02-09 17:24:53 +03:00
2005-04-17 02:20:36 +04:00
return 0 ;
}
/*
* Function irlan_provider_state_open ( self , event , skb , info )
*
* OPEN , The client has issued a OpenData command and is awaiting a
* reply
*
*/
2007-02-09 17:24:53 +03:00
static int irlan_provider_state_open ( struct irlan_cb * self , IRLAN_EVENT event ,
2005-04-17 02:20:36 +04:00
struct sk_buff * skb )
{
2008-03-06 07:47:47 +03:00
IRDA_DEBUG ( 4 , " %s() \n " , __func__ ) ;
2005-04-17 02:20:36 +04:00
IRDA_ASSERT ( self ! = NULL , return - 1 ; ) ;
switch ( event ) {
case IRLAN_FILTER_CONFIG_CMD :
irlan_provider_parse_command ( self , CMD_FILTER_OPERATION , skb ) ;
2007-02-09 17:24:53 +03:00
irlan_provider_send_reply ( self , CMD_FILTER_OPERATION ,
2005-04-17 02:20:36 +04:00
RSP_SUCCESS ) ;
/* Keep state */
break ;
2007-02-09 17:24:53 +03:00
case IRLAN_DATA_CONNECT_INDICATION :
2005-04-17 02:20:36 +04:00
irlan_next_provider_state ( self , IRLAN_DATA ) ;
irlan_provider_connect_response ( self , self - > tsap_data ) ;
break ;
case IRLAN_LMP_DISCONNECT : /* FALLTHROUGH */
case IRLAN_LAP_DISCONNECT :
irlan_next_provider_state ( self , IRLAN_IDLE ) ;
break ;
default :
2008-03-06 07:47:47 +03:00
IRDA_DEBUG ( 2 , " %s(), Unknown event %d \n " , __func__ , event ) ;
2005-04-17 02:20:36 +04:00
break ;
}
if ( skb )
dev_kfree_skb ( skb ) ;
return 0 ;
}
/*
* Function irlan_provider_state_data ( self , event , skb , info )
*
* DATA , The data channel is connected , allowing data transfers between
* the local and remote machines .
*
*/
2007-02-09 17:24:53 +03:00
static int irlan_provider_state_data ( struct irlan_cb * self , IRLAN_EVENT event ,
struct sk_buff * skb )
2005-04-17 02:20:36 +04:00
{
2008-03-06 07:47:47 +03:00
IRDA_DEBUG ( 4 , " %s() \n " , __func__ ) ;
2005-04-17 02:20:36 +04:00
IRDA_ASSERT ( self ! = NULL , return - 1 ; ) ;
IRDA_ASSERT ( self - > magic = = IRLAN_MAGIC , return - 1 ; ) ;
switch ( event ) {
case IRLAN_FILTER_CONFIG_CMD :
irlan_provider_parse_command ( self , CMD_FILTER_OPERATION , skb ) ;
2007-02-09 17:24:53 +03:00
irlan_provider_send_reply ( self , CMD_FILTER_OPERATION ,
2005-04-17 02:20:36 +04:00
RSP_SUCCESS ) ;
break ;
case IRLAN_LMP_DISCONNECT : /* FALLTHROUGH */
case IRLAN_LAP_DISCONNECT :
irlan_next_provider_state ( self , IRLAN_IDLE ) ;
break ;
default :
2008-03-06 07:47:47 +03:00
IRDA_DEBUG ( 0 , " %s(), Unknown event %d \n " , __func__ , event ) ;
2005-04-17 02:20:36 +04:00
break ;
}
if ( skb )
dev_kfree_skb ( skb ) ;
2007-02-09 17:24:53 +03:00
2005-04-17 02:20:36 +04:00
return 0 ;
}