Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*********************************************************************
  2  *
  3  * Filename:      ircomm_event.c
  4  * Version:       1.0
  5  * Description:   IrCOMM layer state machine
  6  * Status:        Stable
  7  * Author:        Dag Brattli <dagb@cs.uit.no>
  8  * Created at:    Sun Jun  6 20:33:11 1999
  9  * Modified at:   Sun Dec 12 13:44:32 1999
 10  * Modified by:   Dag Brattli <dagb@cs.uit.no>
 11  *
 12  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
 13  *
 14  *     This program is free software; you can redistribute it and/or
 15  *     modify it under the terms of the GNU General Public License as
 16  *     published by the Free Software Foundation; either version 2 of
 17  *     the License, or (at your option) any later version.
 18  *
 19  *     This program is distributed in the hope that it will be useful,
 20  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 21  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 22  *     GNU General Public License for more details.
 23  *
 24  *     You should have received a copy of the GNU General Public License
 25  *     along with this program; if not, write to the Free Software
 26  *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 27  *     MA 02111-1307 USA
 28  *
 29  ********************************************************************/
 30 
 31 #include <linux/proc_fs.h>
 32 #include <linux/init.h>
 33 
 34 #include <net/irda/irda.h>
 35 #include <net/irda/irlmp.h>
 36 #include <net/irda/iriap.h>
 37 #include <net/irda/irttp.h>
 38 #include <net/irda/irias_object.h>
 39 
 40 #include <net/irda/ircomm_core.h>
 41 #include <net/irda/ircomm_event.h>
 42 
 43 static int ircomm_state_idle(struct ircomm_cb *self, IRCOMM_EVENT event,
 44                              struct sk_buff *skb, struct ircomm_info *info);
 45 static int ircomm_state_waiti(struct ircomm_cb *self, IRCOMM_EVENT event,
 46                               struct sk_buff *skb, struct ircomm_info *info);
 47 static int ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event,
 48                               struct sk_buff *skb, struct ircomm_info *info);
 49 static int ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event,
 50                              struct sk_buff *skb, struct ircomm_info *info);
 51 
 52 char *ircomm_state[] = {
 53         "IRCOMM_IDLE",
 54         "IRCOMM_WAITI",
 55         "IRCOMM_WAITR",
 56         "IRCOMM_CONN",
 57 };
 58 
 59 #ifdef CONFIG_IRDA_DEBUG
 60 static char *ircomm_event[] = {
 61         "IRCOMM_CONNECT_REQUEST",
 62         "IRCOMM_CONNECT_RESPONSE",
 63         "IRCOMM_TTP_CONNECT_INDICATION",
 64         "IRCOMM_LMP_CONNECT_INDICATION",
 65         "IRCOMM_TTP_CONNECT_CONFIRM",
 66         "IRCOMM_LMP_CONNECT_CONFIRM",
 67 
 68         "IRCOMM_LMP_DISCONNECT_INDICATION",
 69         "IRCOMM_TTP_DISCONNECT_INDICATION",
 70         "IRCOMM_DISCONNECT_REQUEST",
 71 
 72         "IRCOMM_TTP_DATA_INDICATION",
 73         "IRCOMM_LMP_DATA_INDICATION",
 74         "IRCOMM_DATA_REQUEST",
 75         "IRCOMM_CONTROL_REQUEST",
 76         "IRCOMM_CONTROL_INDICATION",
 77 };
 78 #endif /* CONFIG_IRDA_DEBUG */
 79 
 80 static int (*state[])(struct ircomm_cb *self, IRCOMM_EVENT event,
 81                       struct sk_buff *skb, struct ircomm_info *info) =
 82 {
 83         ircomm_state_idle,
 84         ircomm_state_waiti,
 85         ircomm_state_waitr,
 86         ircomm_state_conn,
 87 };
 88 
 89 /*
 90  * Function ircomm_state_idle (self, event, skb)
 91  *
 92  *    IrCOMM is currently idle
 93  *
 94  */
 95 static int ircomm_state_idle(struct ircomm_cb *self, IRCOMM_EVENT event,
 96                              struct sk_buff *skb, struct ircomm_info *info)
 97 {
 98         int ret = 0;
 99 
100         switch (event) {
101         case IRCOMM_CONNECT_REQUEST:
102                 ircomm_next_state(self, IRCOMM_WAITI);
103                 ret = self->issue.connect_request(self, skb, info);
104                 break;
105         case IRCOMM_TTP_CONNECT_INDICATION:
106         case IRCOMM_LMP_CONNECT_INDICATION:
107                 ircomm_next_state(self, IRCOMM_WAITR);
108                 ircomm_connect_indication(self, skb, info);
109                 break;
110         default:
111                 IRDA_DEBUG(4, "%s(), unknown event: %s\n", __FUNCTION__ ,
112                            ircomm_event[event]);
113                 ret = -EINVAL;
114         }
115         return ret;
116 }
117 
118 /*
119  * Function ircomm_state_waiti (self, event, skb)
120  *
121  *    The IrCOMM user has requested an IrCOMM connection to the remote
122  *    device and is awaiting confirmation
123  */
124 static int ircomm_state_waiti(struct ircomm_cb *self, IRCOMM_EVENT event,
125                               struct sk_buff *skb, struct ircomm_info *info)
126 {
127         int ret = 0;
128 
129         switch (event) {
130         case IRCOMM_TTP_CONNECT_CONFIRM:
131         case IRCOMM_LMP_CONNECT_CONFIRM:
132                 ircomm_next_state(self, IRCOMM_CONN);
133                 ircomm_connect_confirm(self, skb, info);
134                 break;
135         case IRCOMM_TTP_DISCONNECT_INDICATION:
136         case IRCOMM_LMP_DISCONNECT_INDICATION:
137                 ircomm_next_state(self, IRCOMM_IDLE);
138                 ircomm_disconnect_indication(self, skb, info);
139                 break;
140         default:
141                 IRDA_DEBUG(0, "%s(), unknown event: %s\n", __FUNCTION__ ,
142                            ircomm_event[event]);
143                 ret = -EINVAL;
144         }
145         return ret;
146 }
147 
148 /*
149  * Function ircomm_state_waitr (self, event, skb)
150  *
151  *    IrCOMM has received an incoming connection request and is awaiting
152  *    response from the user
153  */
154 static int ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event,
155                               struct sk_buff *skb, struct ircomm_info *info)
156 {
157         int ret = 0;
158 
159         switch (event) {
160         case IRCOMM_CONNECT_RESPONSE:
161                 ircomm_next_state(self, IRCOMM_CONN);
162                 ret = self->issue.connect_response(self, skb);
163                 break;
164         case IRCOMM_DISCONNECT_REQUEST:
165                 ircomm_next_state(self, IRCOMM_IDLE);
166                 ret = self->issue.disconnect_request(self, skb, info);
167                 break;
168         case IRCOMM_TTP_DISCONNECT_INDICATION:
169         case IRCOMM_LMP_DISCONNECT_INDICATION:
170                 ircomm_next_state(self, IRCOMM_IDLE);
171                 ircomm_disconnect_indication(self, skb, info);
172                 break;
173         default:
174                 IRDA_DEBUG(0, "%s(), unknown event = %s\n", __FUNCTION__ ,
175                            ircomm_event[event]);
176                 ret = -EINVAL;
177         }
178         return ret;
179 }
180 
181 /*
182  * Function ircomm_state_conn (self, event, skb)
183  *
184  *    IrCOMM is connected to the peer IrCOMM device
185  *
186  */
187 static int ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event,
188                              struct sk_buff *skb, struct ircomm_info *info)
189 {
190         int ret = 0;
191 
192         switch (event) {
193         case IRCOMM_DATA_REQUEST:
194                 ret = self->issue.data_request(self, skb, 0);
195                 break;
196         case IRCOMM_TTP_DATA_INDICATION:
197                 ircomm_process_data(self, skb);
198                 break;
199         case IRCOMM_LMP_DATA_INDICATION:
200                 ircomm_data_indication(self, skb);
201                 break;
202         case IRCOMM_CONTROL_REQUEST:
203                 /* Just send a separate frame for now */
204                 ret = self->issue.data_request(self, skb, skb->len);
205                 break;
206         case IRCOMM_TTP_DISCONNECT_INDICATION:
207         case IRCOMM_LMP_DISCONNECT_INDICATION:
208                 ircomm_next_state(self, IRCOMM_IDLE);
209                 ircomm_disconnect_indication(self, skb, info);
210                 break;
211         case IRCOMM_DISCONNECT_REQUEST:
212                 ircomm_next_state(self, IRCOMM_IDLE);
213                 ret = self->issue.disconnect_request(self, skb, info);
214                 break;
215         default:
216                 IRDA_DEBUG(0, "%s(), unknown event = %s\n", __FUNCTION__ ,
217                            ircomm_event[event]);
218                 ret = -EINVAL;
219         }
220         return ret;
221 }
222 
223 /*
224  * Function ircomm_do_event (self, event, skb)
225  *
226  *    Process event
227  *
228  */
229 int ircomm_do_event(struct ircomm_cb *self, IRCOMM_EVENT event,
230                     struct sk_buff *skb, struct ircomm_info *info)
231 {
232         IRDA_DEBUG(4, "%s: state=%s, event=%s\n", __FUNCTION__ ,
233                    ircomm_state[self->state], ircomm_event[event]);
234 
235         return (*state[self->state])(self, event, skb, info);
236 }
237 
238 /*
239  * Function ircomm_next_state (self, state)
240  *
241  *    Switch state
242  *
243  */
244 void ircomm_next_state(struct ircomm_cb *self, IRCOMM_STATE state)
245 {
246         self->state = state;
247 
248         IRDA_DEBUG(4, "%s: next state=%s, service type=%d\n", __FUNCTION__ ,
249                    ircomm_state[self->state], self->service_type);
250 }
251 
  This page was automatically generated by the LXR engine.