Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
irlan_client_event.c
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Filename: irlan_client_event.c
4  * Version: 0.9
5  * Description: IrLAN client state machine
6  * Status: Experimental.
7  * Author: Dag Brattli <[email protected]>
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 <[email protected]>
11  *
12  * Copyright (c) 1998-1999 Dag Brattli <[email protected]>,
13  * All Rights Reserved.
14  *
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
18  * the License, or (at your option) any later version.
19  *
20  * Neither Dag Brattli nor University of Tromsø admit liability nor
21  * provide warranty for any of this software. This material is
22  * 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 
39 static int irlan_client_state_idle (struct irlan_cb *self, IRLAN_EVENT event,
40  struct sk_buff *skb);
41 static int irlan_client_state_query(struct irlan_cb *self, IRLAN_EVENT event,
42  struct sk_buff *skb);
43 static int irlan_client_state_conn (struct irlan_cb *self, IRLAN_EVENT event,
44  struct sk_buff *skb);
45 static int irlan_client_state_info (struct irlan_cb *self, IRLAN_EVENT event,
46  struct sk_buff *skb);
47 static int irlan_client_state_media(struct irlan_cb *self, IRLAN_EVENT event,
48  struct sk_buff *skb);
49 static int irlan_client_state_open (struct irlan_cb *self, IRLAN_EVENT event,
50  struct sk_buff *skb);
51 static int irlan_client_state_wait (struct irlan_cb *self, IRLAN_EVENT event,
52  struct sk_buff *skb);
53 static int irlan_client_state_arb (struct irlan_cb *self, IRLAN_EVENT event,
54  struct sk_buff *skb);
55 static int irlan_client_state_data (struct irlan_cb *self, IRLAN_EVENT event,
56  struct sk_buff *skb);
57 static int irlan_client_state_close(struct irlan_cb *self, IRLAN_EVENT event,
58  struct sk_buff *skb);
59 static int irlan_client_state_sync (struct irlan_cb *self, IRLAN_EVENT event,
60  struct sk_buff *skb);
61 
62 static int (*state[])(struct irlan_cb *, IRLAN_EVENT event, struct sk_buff *) =
63 {
64  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 
78  struct sk_buff *skb)
79 {
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  */
92 static int irlan_client_state_idle(struct irlan_cb *self, IRLAN_EVENT event,
93  struct sk_buff *skb)
94 {
95  IRDA_DEBUG(4, "%s()\n", __func__ );
96 
97  IRDA_ASSERT(self != NULL, return -1;);
98  IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
99 
100  switch (event) {
102  if (self->client.iriap) {
103  IRDA_WARNING("%s(), busy with a previous query\n",
104  __func__);
105  return -EBUSY;
106  }
107 
108  self->client.iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
110  /* Get some values from peer IAS */
112  iriap_getvaluebyclass_request(self->client.iriap,
113  self->saddr, self->daddr,
114  "IrLAN", "IrDA:TinyTP:LsapSel");
115  break;
117  IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
118  break;
119  default:
120  IRDA_DEBUG(4, "%s(), Unknown event %d\n", __func__ , event);
121  break;
122  }
123  if (skb)
124  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  */
136 static int irlan_client_state_query(struct irlan_cb *self, IRLAN_EVENT event,
137  struct sk_buff *skb)
138 {
139  IRDA_DEBUG(4, "%s()\n", __func__ );
140 
141  IRDA_ASSERT(self != NULL, return -1;);
142  IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
143 
144  switch(event) {
146  IRDA_ASSERT(self->dtsap_sel_ctrl != 0, return -1;);
147 
148  self->client.open_retries = 0;
149 
150  irttp_connect_request(self->client.tsap_ctrl,
151  self->dtsap_sel_ctrl,
152  self->saddr, self->daddr, NULL,
153  IRLAN_MTU, NULL);
155  break;
157  IRDA_DEBUG(2, "%s(), IAS_PROVIDER_NOT_AVAIL\n", __func__ );
159 
160  /* Give the client a kick! */
161  if ((self->provider.access_type == ACCESS_PEER) &&
162  (self->provider.state != IRLAN_IDLE))
163  irlan_client_wakeup(self, self->saddr, self->daddr);
164  break;
168  break;
170  IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
171  break;
172  default:
173  IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
174  break;
175  }
176  if (skb)
177  dev_kfree_skb(skb);
178 
179  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  */
189 static int irlan_client_state_conn(struct irlan_cb *self, IRLAN_EVENT event,
190  struct sk_buff *skb)
191 {
192  IRDA_DEBUG(4, "%s()\n", __func__ );
193 
194  IRDA_ASSERT(self != NULL, return -1;);
195 
196  switch (event) {
198  /* Send getinfo cmd */
201  break;
205  break;
207  IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
208  break;
209  default:
210  IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
211  break;
212  }
213  if (skb)
214  dev_kfree_skb(skb);
215 
216  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  */
224 static int irlan_client_state_info(struct irlan_cb *self, IRLAN_EVENT event,
225  struct sk_buff *skb)
226 {
227  IRDA_DEBUG(4, "%s()\n", __func__ );
228 
229  IRDA_ASSERT(self != NULL, return -1;);
230 
231  switch (event) {
233  IRDA_ASSERT(skb != NULL, return -1;);
234 
235  irlan_client_parse_response(self, skb);
236 
238 
239  irlan_get_media_char(self);
240  break;
241 
245  break;
247  IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
248  break;
249  default:
250  IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
251  break;
252  }
253  if (skb)
254  dev_kfree_skb(skb);
255 
256  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  */
266 static int irlan_client_state_media(struct irlan_cb *self, IRLAN_EVENT event,
267  struct sk_buff *skb)
268 {
269  IRDA_DEBUG(4, "%s()\n", __func__ );
270 
271  IRDA_ASSERT(self != NULL, return -1;);
272 
273  switch(event) {
275  irlan_client_parse_response(self, skb);
278  break;
282  break;
284  IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
285  break;
286  default:
287  IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
288  break;
289  }
290  if (skb)
291  dev_kfree_skb(skb);
292 
293  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  */
303 static int irlan_client_state_open(struct irlan_cb *self, IRLAN_EVENT event,
304  struct sk_buff *skb)
305 {
306  struct qos_info qos;
307 
308  IRDA_DEBUG(4, "%s()\n", __func__ );
309 
310  IRDA_ASSERT(self != NULL, return -1;);
311 
312  switch(event) {
314  irlan_client_parse_response(self, skb);
315 
316  /*
317  * Check if we have got the remote TSAP for data
318  * communications
319  */
320  IRDA_ASSERT(self->dtsap_sel_data != 0, return -1;);
321 
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) {
326 
329  NULL);
330  } else {
331 
333  }
334  break;
335  case ACCESS_DIRECT:
336  case ACCESS_HOSTED:
337  qos.link_disc_time.bits = 0x01; /* 3 secs */
338 
339  irttp_connect_request(self->tsap_data,
340  self->dtsap_sel_data,
341  self->saddr, self->daddr, &qos,
342  IRLAN_MTU, NULL);
343 
345  break;
346  default:
347  IRDA_DEBUG(2, "%s(), unknown access type!\n", __func__ );
348  break;
349  }
350  break;
354  break;
356  IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
357  break;
358  default:
359  IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
360  break;
361  }
362 
363  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  */
376 static int irlan_client_state_wait(struct irlan_cb *self, IRLAN_EVENT event,
377  struct sk_buff *skb)
378 {
379  IRDA_DEBUG(4, "%s()\n", __func__ );
380 
381  IRDA_ASSERT(self != NULL, return -1;);
382 
383  switch(event) {
387  break;
391  break;
393  IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
394  break;
395  default:
396  IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
397  break;
398  }
399  if (skb)
400  dev_kfree_skb(skb);
401 
402  return 0;
403 }
404 
405 static int irlan_client_state_arb(struct irlan_cb *self, IRLAN_EVENT event,
406  struct sk_buff *skb)
407 {
408  struct qos_info qos;
409 
410  IRDA_DEBUG(2, "%s()\n", __func__ );
411 
412  IRDA_ASSERT(self != NULL, return -1;);
413 
414  switch(event) {
415  case IRLAN_CHECK_CON_ARB:
416  if (self->client.recv_arb_val == self->provider.send_arb_val) {
419  } else if (self->client.recv_arb_val <
420  self->provider.send_arb_val)
421  {
422  qos.link_disc_time.bits = 0x01; /* 3 secs */
423 
425  irttp_connect_request(self->tsap_data,
426  self->dtsap_sel_data,
427  self->saddr, self->daddr, &qos,
428  IRLAN_MTU, NULL);
429  } else if (self->client.recv_arb_val >
430  self->provider.send_arb_val)
431  {
432  IRDA_DEBUG(2, "%s(), lost the battle :-(\n", __func__ );
433  }
434  break;
437  break;
441  break;
443  IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __func__ );
444  break;
445  default:
446  IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
447  break;
448  }
449  if (skb)
450  dev_kfree_skb(skb);
451 
452  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  */
462 static int irlan_client_state_data(struct irlan_cb *self, IRLAN_EVENT event,
463  struct sk_buff *skb)
464 {
465  IRDA_DEBUG(4, "%s()\n", __func__ );
466 
467  IRDA_ASSERT(self != NULL, return -1;);
468  IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
469 
470  switch(event) {
472  irlan_client_parse_response(self, skb);
473  break;
474  case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
477  break;
478  default:
479  IRDA_DEBUG(2, "%s(), Unknown event %d\n", __func__ , event);
480  break;
481  }
482  if (skb)
483  dev_kfree_skb(skb);
484 
485  return 0;
486 }
487 
488 /*
489  * Function irlan_client_state_close (self, event, skb, info)
490  *
491  *
492  *
493  */
494 static int irlan_client_state_close(struct irlan_cb *self, IRLAN_EVENT event,
495  struct sk_buff *skb)
496 {
497  IRDA_DEBUG(2, "%s()\n", __func__ );
498 
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  *
508  *
509  *
510  */
511 static int irlan_client_state_sync(struct irlan_cb *self, IRLAN_EVENT event,
512  struct sk_buff *skb)
513 {
514  IRDA_DEBUG(2, "%s()\n", __func__ );
515 
516  if (skb)
517  dev_kfree_skb(skb);
518 
519  return 0;
520 }
521 
522 
523 
524 
525 
526 
527 
528 
529 
530 
531 
532 
533