blob: cc93fabbbb199ede3758021ef13261958d3cc641 [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 Garskidb9551702007-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{
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 IRDA_ASSERT(self != NULL, return -1;);
96 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +090097
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 switch (event) {
99 case IRLAN_DISCOVERY_INDICATION:
100 if (self->client.iriap) {
Joe Perches6c910232014-11-11 13:37:30 -0800101 net_warn_ratelimited("%s(), busy with a previous query\n",
102 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 return -EBUSY;
104 }
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900105
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 self->client.iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
107 irlan_client_get_value_confirm);
108 /* Get some values from peer IAS */
109 irlan_next_client_state(self, IRLAN_QUERY);
110 iriap_getvaluebyclass_request(self->client.iriap,
111 self->saddr, self->daddr,
112 "IrLAN", "IrDA:TinyTP:LsapSel");
113 break;
114 case IRLAN_WATCHDOG_TIMEOUT:
Joe Perches955a9d202014-11-11 14:44:57 -0800115 pr_debug("%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 break;
117 default:
Joe Perches955a9d202014-11-11 14:44:57 -0800118 pr_debug("%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 break;
120 }
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900121 if (skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 dev_kfree_skb(skb);
123
124 return 0;
125}
126
127/*
128 * Function irlan_client_state_query (event, skb, info)
129 *
130 * QUERY, We have queryed the remote IAS and is ready to connect
131 * to provider, just waiting for the confirm.
132 *
133 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900134static int irlan_client_state_query(struct irlan_cb *self, IRLAN_EVENT event,
135 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 IRDA_ASSERT(self != NULL, return -1;);
138 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900139
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 switch(event) {
141 case IRLAN_IAS_PROVIDER_AVAIL:
142 IRDA_ASSERT(self->dtsap_sel_ctrl != 0, return -1;);
143
144 self->client.open_retries = 0;
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900145
146 irttp_connect_request(self->client.tsap_ctrl,
147 self->dtsap_sel_ctrl,
148 self->saddr, self->daddr, NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 IRLAN_MTU, NULL);
150 irlan_next_client_state(self, IRLAN_CONN);
151 break;
152 case IRLAN_IAS_PROVIDER_NOT_AVAIL:
Joe Perches955a9d202014-11-11 14:44:57 -0800153 pr_debug("%s(), IAS_PROVIDER_NOT_AVAIL\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154 irlan_next_client_state(self, IRLAN_IDLE);
155
156 /* Give the client a kick! */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900157 if ((self->provider.access_type == ACCESS_PEER) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 (self->provider.state != IRLAN_IDLE))
159 irlan_client_wakeup(self, self->saddr, self->daddr);
160 break;
161 case IRLAN_LMP_DISCONNECT:
162 case IRLAN_LAP_DISCONNECT:
163 irlan_next_client_state(self, IRLAN_IDLE);
164 break;
165 case IRLAN_WATCHDOG_TIMEOUT:
Joe Perches955a9d202014-11-11 14:44:57 -0800166 pr_debug("%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 break;
168 default:
Joe Perches955a9d202014-11-11 14:44:57 -0800169 pr_debug("%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 break;
171 }
172 if (skb)
173 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900174
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 return 0;
176}
177
178/*
179 * Function irlan_client_state_conn (event, skb, info)
180 *
181 * CONN, We have connected to a provider but has not issued any
182 * commands yet.
183 *
184 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900185static int irlan_client_state_conn(struct irlan_cb *self, IRLAN_EVENT event,
186 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 IRDA_ASSERT(self != NULL, return -1;);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900189
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 switch (event) {
191 case IRLAN_CONNECT_COMPLETE:
192 /* Send getinfo cmd */
193 irlan_get_provider_info(self);
194 irlan_next_client_state(self, IRLAN_INFO);
195 break;
196 case IRLAN_LMP_DISCONNECT:
197 case IRLAN_LAP_DISCONNECT:
198 irlan_next_client_state(self, IRLAN_IDLE);
199 break;
200 case IRLAN_WATCHDOG_TIMEOUT:
Joe Perches955a9d202014-11-11 14:44:57 -0800201 pr_debug("%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 break;
203 default:
Joe Perches955a9d202014-11-11 14:44:57 -0800204 pr_debug("%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 break;
206 }
207 if (skb)
208 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900209
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 return 0;
211}
212
213/*
214 * Function irlan_client_state_info (self, event, skb, info)
215 *
216 * INFO, We have issued a GetInfo command and is awaiting a reply.
217 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900218static int irlan_client_state_info(struct irlan_cb *self, IRLAN_EVENT event,
219 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 IRDA_ASSERT(self != NULL, return -1;);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900222
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 switch (event) {
224 case IRLAN_DATA_INDICATION:
225 IRDA_ASSERT(skb != NULL, return -1;);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900226
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 irlan_client_parse_response(self, skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900228
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 irlan_next_client_state(self, IRLAN_MEDIA);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900230
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 irlan_get_media_char(self);
232 break;
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900233
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 case IRLAN_LMP_DISCONNECT:
235 case IRLAN_LAP_DISCONNECT:
236 irlan_next_client_state(self, IRLAN_IDLE);
237 break;
238 case IRLAN_WATCHDOG_TIMEOUT:
Joe Perches955a9d202014-11-11 14:44:57 -0800239 pr_debug("%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 break;
241 default:
Joe Perches955a9d202014-11-11 14:44:57 -0800242 pr_debug("%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243 break;
244 }
245 if (skb)
246 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900247
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 return 0;
249}
250
251/*
252 * Function irlan_client_state_media (self, event, skb, info)
253 *
254 * MEDIA, The irlan_client has issued a GetMedia command and is awaiting a
255 * reply.
256 *
257 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900258static int irlan_client_state_media(struct irlan_cb *self, IRLAN_EVENT event,
259 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 IRDA_ASSERT(self != NULL, return -1;);
262
263 switch(event) {
264 case IRLAN_DATA_INDICATION:
265 irlan_client_parse_response(self, skb);
266 irlan_open_data_channel(self);
267 irlan_next_client_state(self, IRLAN_OPEN);
268 break;
269 case IRLAN_LMP_DISCONNECT:
270 case IRLAN_LAP_DISCONNECT:
271 irlan_next_client_state(self, IRLAN_IDLE);
272 break;
273 case IRLAN_WATCHDOG_TIMEOUT:
Joe Perches955a9d202014-11-11 14:44:57 -0800274 pr_debug("%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 break;
276 default:
Joe Perches955a9d202014-11-11 14:44:57 -0800277 pr_debug("%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278 break;
279 }
280 if (skb)
281 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900282
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 return 0;
284}
285
286/*
287 * Function irlan_client_state_open (self, event, skb, info)
288 *
289 * OPEN, The irlan_client has issued a OpenData command and is awaiting a
290 * reply
291 *
292 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900293static int irlan_client_state_open(struct irlan_cb *self, IRLAN_EVENT event,
294 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295{
296 struct qos_info qos;
297
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 IRDA_ASSERT(self != NULL, return -1;);
299
300 switch(event) {
301 case IRLAN_DATA_INDICATION:
302 irlan_client_parse_response(self, skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900303
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 /*
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900305 * Check if we have got the remote TSAP for data
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 * communications
307 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900308 IRDA_ASSERT(self->dtsap_sel_data != 0, return -1;);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309
310 /* Check which access type we are dealing with */
311 switch (self->client.access_type) {
312 case ACCESS_PEER:
313 if (self->provider.state == IRLAN_OPEN) {
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900314
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 irlan_next_client_state(self, IRLAN_ARB);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900316 irlan_do_client_event(self, IRLAN_CHECK_CON_ARB,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317 NULL);
318 } else {
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900319
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320 irlan_next_client_state(self, IRLAN_WAIT);
321 }
322 break;
323 case ACCESS_DIRECT:
324 case ACCESS_HOSTED:
325 qos.link_disc_time.bits = 0x01; /* 3 secs */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900326
327 irttp_connect_request(self->tsap_data,
328 self->dtsap_sel_data,
329 self->saddr, self->daddr, &qos,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330 IRLAN_MTU, NULL);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900331
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 irlan_next_client_state(self, IRLAN_DATA);
333 break;
334 default:
Joe Perches955a9d202014-11-11 14:44:57 -0800335 pr_debug("%s(), unknown access type!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 break;
337 }
338 break;
339 case IRLAN_LMP_DISCONNECT:
340 case IRLAN_LAP_DISCONNECT:
341 irlan_next_client_state(self, IRLAN_IDLE);
342 break;
343 case IRLAN_WATCHDOG_TIMEOUT:
Joe Perches955a9d202014-11-11 14:44:57 -0800344 pr_debug("%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 break;
346 default:
Joe Perches955a9d202014-11-11 14:44:57 -0800347 pr_debug("%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 break;
349 }
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900350
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 if (skb)
352 dev_kfree_skb(skb);
353
354 return 0;
355}
356
357/*
358 * Function irlan_client_state_wait (self, event, skb, info)
359 *
360 * WAIT, The irlan_client is waiting for the local provider to enter the
361 * provider OPEN state.
362 *
363 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900364static int irlan_client_state_wait(struct irlan_cb *self, IRLAN_EVENT event,
365 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 IRDA_ASSERT(self != NULL, return -1;);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900368
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 switch(event) {
370 case IRLAN_PROVIDER_SIGNAL:
371 irlan_next_client_state(self, IRLAN_ARB);
372 irlan_do_client_event(self, IRLAN_CHECK_CON_ARB, NULL);
373 break;
374 case IRLAN_LMP_DISCONNECT:
375 case IRLAN_LAP_DISCONNECT:
376 irlan_next_client_state(self, IRLAN_IDLE);
377 break;
378 case IRLAN_WATCHDOG_TIMEOUT:
Joe Perches955a9d202014-11-11 14:44:57 -0800379 pr_debug("%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 break;
381 default:
Joe Perches955a9d202014-11-11 14:44:57 -0800382 pr_debug("%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 break;
384 }
385 if (skb)
386 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900387
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 return 0;
389}
390
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900391static int irlan_client_state_arb(struct irlan_cb *self, IRLAN_EVENT event,
392 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393{
394 struct qos_info qos;
395
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 IRDA_ASSERT(self != NULL, return -1;);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900397
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 switch(event) {
399 case IRLAN_CHECK_CON_ARB:
400 if (self->client.recv_arb_val == self->provider.send_arb_val) {
401 irlan_next_client_state(self, IRLAN_CLOSE);
402 irlan_close_data_channel(self);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900403 } else if (self->client.recv_arb_val <
404 self->provider.send_arb_val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 {
406 qos.link_disc_time.bits = 0x01; /* 3 secs */
407
408 irlan_next_client_state(self, IRLAN_DATA);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900409 irttp_connect_request(self->tsap_data,
410 self->dtsap_sel_data,
411 self->saddr, self->daddr, &qos,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 IRLAN_MTU, NULL);
413 } else if (self->client.recv_arb_val >
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900414 self->provider.send_arb_val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 {
Joe Perches955a9d202014-11-11 14:44:57 -0800416 pr_debug("%s(), lost the battle :-(\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 }
418 break;
419 case IRLAN_DATA_CONNECT_INDICATION:
420 irlan_next_client_state(self, IRLAN_DATA);
421 break;
422 case IRLAN_LMP_DISCONNECT:
423 case IRLAN_LAP_DISCONNECT:
424 irlan_next_client_state(self, IRLAN_IDLE);
425 break;
426 case IRLAN_WATCHDOG_TIMEOUT:
Joe Perches955a9d202014-11-11 14:44:57 -0800427 pr_debug("%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 break;
429 default:
Joe Perches955a9d202014-11-11 14:44:57 -0800430 pr_debug("%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431 break;
432 }
433 if (skb)
434 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900435
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436 return 0;
437}
438
439/*
440 * Function irlan_client_state_data (self, event, skb, info)
441 *
442 * DATA, The data channel is connected, allowing data transfers between
443 * the local and remote machines.
444 *
445 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900446static int irlan_client_state_data(struct irlan_cb *self, IRLAN_EVENT event,
447 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 IRDA_ASSERT(self != NULL, return -1;);
450 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
451
452 switch(event) {
453 case IRLAN_DATA_INDICATION:
454 irlan_client_parse_response(self, skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900455 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456 case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
457 case IRLAN_LAP_DISCONNECT:
458 irlan_next_client_state(self, IRLAN_IDLE);
459 break;
460 default:
Joe Perches955a9d202014-11-11 14:44:57 -0800461 pr_debug("%s(), Unknown event %d\n", __func__ , event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462 break;
463 }
464 if (skb)
465 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900466
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 return 0;
468}
469
470/*
471 * Function irlan_client_state_close (self, event, skb, info)
472 *
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900473 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 *
475 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900476static int irlan_client_state_close(struct irlan_cb *self, IRLAN_EVENT event,
477 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 if (skb)
480 dev_kfree_skb(skb);
481
482 return 0;
483}
484
485/*
486 * Function irlan_client_state_sync (self, event, skb, info)
487 *
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900488 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 *
490 */
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900491static int irlan_client_state_sync(struct irlan_cb *self, IRLAN_EVENT event,
492 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 if (skb)
495 dev_kfree_skb(skb);
YOSHIFUJI Hideaki6819bc22007-02-09 23:24:53 +0900496
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 return 0;
498}
499
500
501
502
503
504
505
506
507
508
509
510
511