blob: 8d5a8ebc444fcbd56db51e28241f58a27efc9ed9 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*********************************************************************
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +09002 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 * Filename: irlan_client_event.c
4 * Version: 0.9
5 * Description: IrLAN client state machine
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Aug 31 20:14:37 1997
9 * Modified at: Sun Dec 26 21:52:24 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090011 *
12 * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 * All Rights Reserved.
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090014 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 * the License, or (at your option) any later version.
19 *
Marcin Garskidb955172007-10-19 23:22:11 +020020 * Neither Dag Brattli nor University of Tromsø admit liability nor
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090021 * provide warranty for any of this software. This material is
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 * provided "AS-IS" and at no charge.
23 *
24 ********************************************************************/
25
26#include <linux/skbuff.h>
27
28#include <net/irda/irda.h>
29#include <net/irda/timer.h>
30#include <net/irda/irmod.h>
31#include <net/irda/iriap.h>
32#include <net/irda/irlmp.h>
33#include <net/irda/irttp.h>
34
35#include <net/irda/irlan_common.h>
36#include <net/irda/irlan_client.h>
37#include <net/irda/irlan_event.h>
38
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090039static int irlan_client_state_idle (struct irlan_cb *self, IRLAN_EVENT event,
Linus Torvalds1da177e2005-04-16 15:20:36 -070040 struct sk_buff *skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090041static int irlan_client_state_query(struct irlan_cb *self, IRLAN_EVENT event,
Linus Torvalds1da177e2005-04-16 15:20:36 -070042 struct sk_buff *skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090043static int irlan_client_state_conn (struct irlan_cb *self, IRLAN_EVENT event,
Linus Torvalds1da177e2005-04-16 15:20:36 -070044 struct sk_buff *skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090045static int irlan_client_state_info (struct irlan_cb *self, IRLAN_EVENT event,
Linus Torvalds1da177e2005-04-16 15:20:36 -070046 struct sk_buff *skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090047static int irlan_client_state_media(struct irlan_cb *self, IRLAN_EVENT event,
Linus Torvalds1da177e2005-04-16 15:20:36 -070048 struct sk_buff *skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090049static int irlan_client_state_open (struct irlan_cb *self, IRLAN_EVENT event,
Linus Torvalds1da177e2005-04-16 15:20:36 -070050 struct sk_buff *skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090051static int irlan_client_state_wait (struct irlan_cb *self, IRLAN_EVENT event,
Linus Torvalds1da177e2005-04-16 15:20:36 -070052 struct sk_buff *skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090053static int irlan_client_state_arb (struct irlan_cb *self, IRLAN_EVENT event,
Linus Torvalds1da177e2005-04-16 15:20:36 -070054 struct sk_buff *skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090055static int irlan_client_state_data (struct irlan_cb *self, IRLAN_EVENT event,
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 struct sk_buff *skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090057static int irlan_client_state_close(struct irlan_cb *self, IRLAN_EVENT event,
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 struct sk_buff *skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090059static int irlan_client_state_sync (struct irlan_cb *self, IRLAN_EVENT event,
Linus Torvalds1da177e2005-04-16 15:20:36 -070060 struct sk_buff *skb);
61
62static int (*state[])(struct irlan_cb *, IRLAN_EVENT event, struct sk_buff *) =
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090063{
Linus Torvalds1da177e2005-04-16 15:20:36 -070064 irlan_client_state_idle,
65 irlan_client_state_query,
66 irlan_client_state_conn,
67 irlan_client_state_info,
68 irlan_client_state_media,
69 irlan_client_state_open,
70 irlan_client_state_wait,
71 irlan_client_state_arb,
72 irlan_client_state_data,
73 irlan_client_state_close,
74 irlan_client_state_sync
75};
76
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090077void irlan_do_client_event(struct irlan_cb *self, IRLAN_EVENT event,
78 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070079{
80 IRDA_ASSERT(self != NULL, return;);
81 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
82
83 (*state[ self->client.state]) (self, event, skb);
84}
85
86/*
87 * Function irlan_client_state_idle (event, skb, info)
88 *
89 * IDLE, We are waiting for an indication that there is a provider
90 * available.
91 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090092static int irlan_client_state_idle(struct irlan_cb *self, IRLAN_EVENT event,
93 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070094{
Harvey Harrison0dc47872008-03-05 20:47:47 -080095 IRDA_DEBUG(4, "%s()\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
97 IRDA_ASSERT(self != NULL, return -1;);
98 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090099
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100 switch (event) {
101 case IRLAN_DISCOVERY_INDICATION:
102 if (self->client.iriap) {
103 IRDA_WARNING("%s(), busy with a previous query\n",
Harvey Harrison0dc47872008-03-05 20:47:47 -0800104 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 return -EBUSY;
106 }
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900107
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 self->client.iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
109 irlan_client_get_value_confirm);
110 /* Get some values from peer IAS */
111 irlan_next_client_state(self, IRLAN_QUERY);
112 iriap_getvaluebyclass_request(self->client.iriap,
113 self->saddr, self->daddr,
114 "IrLAN", "IrDA:TinyTP:LsapSel");
115 break;
116 case IRLAN_WATCHDOG_TIMEOUT:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800117 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 break;
119 default:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800120 IRDA_DEBUG(4, "%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121 break;
122 }
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900123 if (skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 dev_kfree_skb(skb);
125
126 return 0;
127}
128
129/*
130 * Function irlan_client_state_query (event, skb, info)
131 *
132 * QUERY, We have queryed the remote IAS and is ready to connect
133 * to provider, just waiting for the confirm.
134 *
135 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900136static int irlan_client_state_query(struct irlan_cb *self, IRLAN_EVENT event,
137 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138{
Harvey Harrison0dc47872008-03-05 20:47:47 -0800139 IRDA_DEBUG(4, "%s()\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140
141 IRDA_ASSERT(self != NULL, return -1;);
142 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900143
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 switch(event) {
145 case IRLAN_IAS_PROVIDER_AVAIL:
146 IRDA_ASSERT(self->dtsap_sel_ctrl != 0, return -1;);
147
148 self->client.open_retries = 0;
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900149
150 irttp_connect_request(self->client.tsap_ctrl,
151 self->dtsap_sel_ctrl,
152 self->saddr, self->daddr, NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153 IRLAN_MTU, NULL);
154 irlan_next_client_state(self, IRLAN_CONN);
155 break;
156 case IRLAN_IAS_PROVIDER_NOT_AVAIL:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800157 IRDA_DEBUG(2, "%s(), IAS_PROVIDER_NOT_AVAIL\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 irlan_next_client_state(self, IRLAN_IDLE);
159
160 /* Give the client a kick! */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900161 if ((self->provider.access_type == ACCESS_PEER) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162 (self->provider.state != IRLAN_IDLE))
163 irlan_client_wakeup(self, self->saddr, self->daddr);
164 break;
165 case IRLAN_LMP_DISCONNECT:
166 case IRLAN_LAP_DISCONNECT:
167 irlan_next_client_state(self, IRLAN_IDLE);
168 break;
169 case IRLAN_WATCHDOG_TIMEOUT:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800170 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 break;
172 default:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800173 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 break;
175 }
176 if (skb)
177 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900178
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 return 0;
180}
181
182/*
183 * Function irlan_client_state_conn (event, skb, info)
184 *
185 * CONN, We have connected to a provider but has not issued any
186 * commands yet.
187 *
188 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900189static int irlan_client_state_conn(struct irlan_cb *self, IRLAN_EVENT event,
190 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191{
Harvey Harrison0dc47872008-03-05 20:47:47 -0800192 IRDA_DEBUG(4, "%s()\n", __func__ );
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900193
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 IRDA_ASSERT(self != NULL, return -1;);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900195
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196 switch (event) {
197 case IRLAN_CONNECT_COMPLETE:
198 /* Send getinfo cmd */
199 irlan_get_provider_info(self);
200 irlan_next_client_state(self, IRLAN_INFO);
201 break;
202 case IRLAN_LMP_DISCONNECT:
203 case IRLAN_LAP_DISCONNECT:
204 irlan_next_client_state(self, IRLAN_IDLE);
205 break;
206 case IRLAN_WATCHDOG_TIMEOUT:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800207 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 break;
209 default:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800210 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211 break;
212 }
213 if (skb)
214 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900215
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 return 0;
217}
218
219/*
220 * Function irlan_client_state_info (self, event, skb, info)
221 *
222 * INFO, We have issued a GetInfo command and is awaiting a reply.
223 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900224static int irlan_client_state_info(struct irlan_cb *self, IRLAN_EVENT event,
225 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226{
Harvey Harrison0dc47872008-03-05 20:47:47 -0800227 IRDA_DEBUG(4, "%s()\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
229 IRDA_ASSERT(self != NULL, return -1;);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900230
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 switch (event) {
232 case IRLAN_DATA_INDICATION:
233 IRDA_ASSERT(skb != NULL, return -1;);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900234
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 irlan_client_parse_response(self, skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900236
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 irlan_next_client_state(self, IRLAN_MEDIA);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900238
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239 irlan_get_media_char(self);
240 break;
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900241
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242 case IRLAN_LMP_DISCONNECT:
243 case IRLAN_LAP_DISCONNECT:
244 irlan_next_client_state(self, IRLAN_IDLE);
245 break;
246 case IRLAN_WATCHDOG_TIMEOUT:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800247 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 break;
249 default:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800250 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 break;
252 }
253 if (skb)
254 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900255
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 return 0;
257}
258
259/*
260 * Function irlan_client_state_media (self, event, skb, info)
261 *
262 * MEDIA, The irlan_client has issued a GetMedia command and is awaiting a
263 * reply.
264 *
265 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900266static int irlan_client_state_media(struct irlan_cb *self, IRLAN_EVENT event,
267 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268{
Harvey Harrison0dc47872008-03-05 20:47:47 -0800269 IRDA_DEBUG(4, "%s()\n", __func__ );
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900270
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 IRDA_ASSERT(self != NULL, return -1;);
272
273 switch(event) {
274 case IRLAN_DATA_INDICATION:
275 irlan_client_parse_response(self, skb);
276 irlan_open_data_channel(self);
277 irlan_next_client_state(self, IRLAN_OPEN);
278 break;
279 case IRLAN_LMP_DISCONNECT:
280 case IRLAN_LAP_DISCONNECT:
281 irlan_next_client_state(self, IRLAN_IDLE);
282 break;
283 case IRLAN_WATCHDOG_TIMEOUT:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800284 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 break;
286 default:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800287 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 break;
289 }
290 if (skb)
291 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900292
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 return 0;
294}
295
296/*
297 * Function irlan_client_state_open (self, event, skb, info)
298 *
299 * OPEN, The irlan_client has issued a OpenData command and is awaiting a
300 * reply
301 *
302 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900303static int irlan_client_state_open(struct irlan_cb *self, IRLAN_EVENT event,
304 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305{
306 struct qos_info qos;
307
Harvey Harrison0dc47872008-03-05 20:47:47 -0800308 IRDA_DEBUG(4, "%s()\n", __func__ );
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900309
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310 IRDA_ASSERT(self != NULL, return -1;);
311
312 switch(event) {
313 case IRLAN_DATA_INDICATION:
314 irlan_client_parse_response(self, skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900315
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 /*
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900317 * Check if we have got the remote TSAP for data
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 * communications
319 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900320 IRDA_ASSERT(self->dtsap_sel_data != 0, return -1;);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321
322 /* Check which access type we are dealing with */
323 switch (self->client.access_type) {
324 case ACCESS_PEER:
325 if (self->provider.state == IRLAN_OPEN) {
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900326
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327 irlan_next_client_state(self, IRLAN_ARB);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900328 irlan_do_client_event(self, IRLAN_CHECK_CON_ARB,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 NULL);
330 } else {
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900331
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 irlan_next_client_state(self, IRLAN_WAIT);
333 }
334 break;
335 case ACCESS_DIRECT:
336 case ACCESS_HOSTED:
337 qos.link_disc_time.bits = 0x01; /* 3 secs */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900338
339 irttp_connect_request(self->tsap_data,
340 self->dtsap_sel_data,
341 self->saddr, self->daddr, &qos,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 IRLAN_MTU, NULL);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900343
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 irlan_next_client_state(self, IRLAN_DATA);
345 break;
346 default:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800347 IRDA_DEBUG(2, "%s(), unknown access type!\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 break;
349 }
350 break;
351 case IRLAN_LMP_DISCONNECT:
352 case IRLAN_LAP_DISCONNECT:
353 irlan_next_client_state(self, IRLAN_IDLE);
354 break;
355 case IRLAN_WATCHDOG_TIMEOUT:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800356 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 break;
358 default:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800359 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360 break;
361 }
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900362
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 if (skb)
364 dev_kfree_skb(skb);
365
366 return 0;
367}
368
369/*
370 * Function irlan_client_state_wait (self, event, skb, info)
371 *
372 * WAIT, The irlan_client is waiting for the local provider to enter the
373 * provider OPEN state.
374 *
375 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900376static int irlan_client_state_wait(struct irlan_cb *self, IRLAN_EVENT event,
377 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378{
Harvey Harrison0dc47872008-03-05 20:47:47 -0800379 IRDA_DEBUG(4, "%s()\n", __func__ );
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900380
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 IRDA_ASSERT(self != NULL, return -1;);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900382
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 switch(event) {
384 case IRLAN_PROVIDER_SIGNAL:
385 irlan_next_client_state(self, IRLAN_ARB);
386 irlan_do_client_event(self, IRLAN_CHECK_CON_ARB, NULL);
387 break;
388 case IRLAN_LMP_DISCONNECT:
389 case IRLAN_LAP_DISCONNECT:
390 irlan_next_client_state(self, IRLAN_IDLE);
391 break;
392 case IRLAN_WATCHDOG_TIMEOUT:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800393 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 break;
395 default:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800396 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 break;
398 }
399 if (skb)
400 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900401
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 return 0;
403}
404
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900405static int irlan_client_state_arb(struct irlan_cb *self, IRLAN_EVENT event,
406 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407{
408 struct qos_info qos;
409
Harvey Harrison0dc47872008-03-05 20:47:47 -0800410 IRDA_DEBUG(2, "%s()\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
412 IRDA_ASSERT(self != NULL, return -1;);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900413
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 switch(event) {
415 case IRLAN_CHECK_CON_ARB:
416 if (self->client.recv_arb_val == self->provider.send_arb_val) {
417 irlan_next_client_state(self, IRLAN_CLOSE);
418 irlan_close_data_channel(self);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900419 } else if (self->client.recv_arb_val <
420 self->provider.send_arb_val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 {
422 qos.link_disc_time.bits = 0x01; /* 3 secs */
423
424 irlan_next_client_state(self, IRLAN_DATA);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900425 irttp_connect_request(self->tsap_data,
426 self->dtsap_sel_data,
427 self->saddr, self->daddr, &qos,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 IRLAN_MTU, NULL);
429 } else if (self->client.recv_arb_val >
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900430 self->provider.send_arb_val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431 {
Harvey Harrison0dc47872008-03-05 20:47:47 -0800432 IRDA_DEBUG(2, "%s(), lost the battle :-(\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 }
434 break;
435 case IRLAN_DATA_CONNECT_INDICATION:
436 irlan_next_client_state(self, IRLAN_DATA);
437 break;
438 case IRLAN_LMP_DISCONNECT:
439 case IRLAN_LAP_DISCONNECT:
440 irlan_next_client_state(self, IRLAN_IDLE);
441 break;
442 case IRLAN_WATCHDOG_TIMEOUT:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800443 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 break;
445 default:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800446 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 break;
448 }
449 if (skb)
450 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900451
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 return 0;
453}
454
455/*
456 * Function irlan_client_state_data (self, event, skb, info)
457 *
458 * DATA, The data channel is connected, allowing data transfers between
459 * the local and remote machines.
460 *
461 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900462static int irlan_client_state_data(struct irlan_cb *self, IRLAN_EVENT event,
463 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464{
Harvey Harrison0dc47872008-03-05 20:47:47 -0800465 IRDA_DEBUG(4, "%s()\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466
467 IRDA_ASSERT(self != NULL, return -1;);
468 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
469
470 switch(event) {
471 case IRLAN_DATA_INDICATION:
472 irlan_client_parse_response(self, skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900473 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
475 case IRLAN_LAP_DISCONNECT:
476 irlan_next_client_state(self, IRLAN_IDLE);
477 break;
478 default:
Harvey Harrison0dc47872008-03-05 20:47:47 -0800479 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 break;
481 }
482 if (skb)
483 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900484
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 return 0;
486}
487
488/*
489 * Function irlan_client_state_close (self, event, skb, info)
490 *
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900491 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 *
493 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900494static int irlan_client_state_close(struct irlan_cb *self, IRLAN_EVENT event,
495 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496{
Harvey Harrison0dc47872008-03-05 20:47:47 -0800497 IRDA_DEBUG(2, "%s()\n", __func__ );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498
499 if (skb)
500 dev_kfree_skb(skb);
501
502 return 0;
503}
504
505/*
506 * Function irlan_client_state_sync (self, event, skb, info)
507 *
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900508 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 *
510 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900511static int irlan_client_state_sync(struct irlan_cb *self, IRLAN_EVENT event,
512 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513{
Harvey Harrison0dc47872008-03-05 20:47:47 -0800514 IRDA_DEBUG(2, "%s()\n", __func__ );
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900515
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 if (skb)
517 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900518
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 return 0;
520}
521
522
523
524
525
526
527
528
529
530
531
532
533