Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
irlan_client.c
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Filename: irlan_client.c
4  * Version: 0.9
5  * Description: IrDA LAN Access Protocol (IrLAN) Client
6  * Status: Experimental.
7  * Author: Dag Brattli <[email protected]>
8  * Created at: Sun Aug 31 20:14:37 1997
9  * Modified at: Tue Dec 14 15:47:02 1999
10  * Modified by: Dag Brattli <[email protected]>
11  * Sources: skeleton.c by Donald Becker <[email protected]>
12  * slip.c by Laurence Culhane, <[email protected]>
13  * Fred N. van Kempen, <[email protected]>
14  *
15  * Copyright (c) 1998-1999 Dag Brattli <[email protected]>,
16  * All Rights Reserved.
17  *
18  * This program is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU General Public License as
20  * published by the Free Software Foundation; either version 2 of
21  * the License, or (at your option) any later version.
22  *
23  * Neither Dag Brattli nor University of Tromsø admit liability nor
24  * provide warranty for any of this software. This material is
25  * provided "AS-IS" and at no charge.
26  *
27  ********************************************************************/
28 
29 #include <linux/kernel.h>
30 #include <linux/string.h>
31 #include <linux/slab.h>
32 #include <linux/errno.h>
33 #include <linux/init.h>
34 #include <linux/netdevice.h>
35 #include <linux/etherdevice.h>
36 #include <linux/if_arp.h>
37 #include <linux/bitops.h>
38 #include <net/arp.h>
39 
40 #include <asm/byteorder.h>
41 
42 #include <net/irda/irda.h>
43 #include <net/irda/irttp.h>
44 #include <net/irda/irlmp.h>
45 #include <net/irda/irias_object.h>
46 #include <net/irda/iriap.h>
47 #include <net/irda/timer.h>
48 
49 #include <net/irda/irlan_common.h>
50 #include <net/irda/irlan_event.h>
51 #include <net/irda/irlan_eth.h>
53 #include <net/irda/irlan_client.h>
54 
55 #undef CONFIG_IRLAN_GRATUITOUS_ARP
56 
57 static void irlan_client_ctrl_disconnect_indication(void *instance, void *sap,
59  struct sk_buff *);
60 static int irlan_client_ctrl_data_indication(void *instance, void *sap,
61  struct sk_buff *skb);
62 static void irlan_client_ctrl_connect_confirm(void *instance, void *sap,
63  struct qos_info *qos,
64  __u32 max_sdu_size,
65  __u8 max_header_size,
66  struct sk_buff *);
67 static void irlan_check_response_param(struct irlan_cb *self, char *param,
68  char *value, int val_len);
69 static void irlan_client_open_ctrl_tsap(struct irlan_cb *self);
70 
71 static void irlan_client_kick_timer_expired(void *data)
72 {
73  struct irlan_cb *self = (struct irlan_cb *) data;
74 
75  IRDA_DEBUG(2, "%s()\n", __func__ );
76 
77  IRDA_ASSERT(self != NULL, return;);
78  IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
79 
80  /*
81  * If we are in peer mode, the client may not have got the discovery
82  * indication it needs to make progress. If the client is still in
83  * IDLE state, we must kick it to, but only if the provider is not IDLE
84  */
85  if ((self->provider.access_type == ACCESS_PEER) &&
86  (self->client.state == IRLAN_IDLE) &&
87  (self->provider.state != IRLAN_IDLE)) {
88  irlan_client_wakeup(self, self->saddr, self->daddr);
89  }
90 }
91 
92 static void irlan_client_start_kick_timer(struct irlan_cb *self, int timeout)
93 {
94  IRDA_DEBUG(4, "%s()\n", __func__ );
95 
96  irda_start_timer(&self->client.kick_timer, timeout, (void *) self,
97  irlan_client_kick_timer_expired);
98 }
99 
100 /*
101  * Function irlan_client_wakeup (self, saddr, daddr)
102  *
103  * Wake up client
104  *
105  */
107 {
108  IRDA_DEBUG(1, "%s()\n", __func__ );
109 
110  IRDA_ASSERT(self != NULL, return;);
111  IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
112 
113  /*
114  * Check if we are already awake, or if we are a provider in direct
115  * mode (in that case we must leave the client idle
116  */
117  if ((self->client.state != IRLAN_IDLE) ||
118  (self->provider.access_type == ACCESS_DIRECT))
119  {
120  IRDA_DEBUG(0, "%s(), already awake!\n", __func__ );
121  return;
122  }
123 
124  /* Addresses may have changed! */
125  self->saddr = saddr;
126  self->daddr = daddr;
127 
128  if (self->disconnect_reason == LM_USER_REQUEST) {
129  IRDA_DEBUG(0, "%s(), still stopped by user\n", __func__ );
130  return;
131  }
132 
133  /* Open TSAPs */
134  irlan_client_open_ctrl_tsap(self);
135  irlan_open_data_tsap(self);
136 
138 
139  /* Start kick timer */
140  irlan_client_start_kick_timer(self, 2*HZ);
141 }
142 
143 /*
144  * Function irlan_discovery_indication (daddr)
145  *
146  * Remote device with IrLAN server support discovered
147  *
148  */
151  void *priv)
152 {
153  struct irlan_cb *self;
154  __u32 saddr, daddr;
155 
156  IRDA_DEBUG(1, "%s()\n", __func__ );
157 
158  IRDA_ASSERT(discovery != NULL, return;);
159 
160  /*
161  * I didn't check it, but I bet that IrLAN suffer from the same
162  * deficiency as IrComm and doesn't handle two instances
163  * simultaneously connecting to each other.
164  * Same workaround, drop passive discoveries.
165  * Jean II */
166  if(mode == DISCOVERY_PASSIVE)
167  return;
168 
169  saddr = discovery->saddr;
170  daddr = discovery->daddr;
171 
172  /* Find instance */
173  rcu_read_lock();
174  self = irlan_get_any();
175  if (self) {
176  IRDA_ASSERT(self->magic == IRLAN_MAGIC, goto out;);
177 
178  IRDA_DEBUG(1, "%s(), Found instance (%08x)!\n", __func__ ,
179  daddr);
180 
181  irlan_client_wakeup(self, saddr, daddr);
182  }
184  rcu_read_unlock();
185 }
186 
187 /*
188  * Function irlan_client_data_indication (handle, skb)
189  *
190  * This function gets the data that is received on the control channel
191  *
192  */
193 static int irlan_client_ctrl_data_indication(void *instance, void *sap,
194  struct sk_buff *skb)
195 {
196  struct irlan_cb *self;
197 
198  IRDA_DEBUG(2, "%s()\n", __func__ );
199 
200  self = instance;
201 
202  IRDA_ASSERT(self != NULL, return -1;);
203  IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
204  IRDA_ASSERT(skb != NULL, return -1;);
205 
207 
208  /* Ready for a new command */
209  IRDA_DEBUG(2, "%s(), clearing tx_busy\n", __func__ );
210  self->client.tx_busy = FALSE;
211 
212  /* Check if we have some queued commands waiting to be sent */
214 
215  return 0;
216 }
217 
218 static void irlan_client_ctrl_disconnect_indication(void *instance, void *sap,
220  struct sk_buff *userdata)
221 {
222  struct irlan_cb *self;
223  struct tsap_cb *tsap;
224  struct sk_buff *skb;
225 
226  IRDA_DEBUG(4, "%s(), reason=%d\n", __func__ , reason);
227 
228  self = instance;
229  tsap = sap;
230 
231  IRDA_ASSERT(self != NULL, return;);
232  IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
233  IRDA_ASSERT(tsap != NULL, return;);
234  IRDA_ASSERT(tsap->magic == TTP_TSAP_MAGIC, return;);
235 
236  IRDA_ASSERT(tsap == self->client.tsap_ctrl, return;);
237 
238  /* Remove frames queued on the control channel */
239  while ((skb = skb_dequeue(&self->client.txq)) != NULL) {
240  dev_kfree_skb(skb);
241  }
242  self->client.tx_busy = FALSE;
243 
245 }
246 
247 /*
248  * Function irlan_client_open_tsaps (self)
249  *
250  * Initialize callbacks and open IrTTP TSAPs
251  *
252  */
253 static void irlan_client_open_ctrl_tsap(struct irlan_cb *self)
254 {
255  struct tsap_cb *tsap;
257 
258  IRDA_DEBUG(4, "%s()\n", __func__ );
259 
260  IRDA_ASSERT(self != NULL, return;);
261  IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
262 
263  /* Check if already open */
264  if (self->client.tsap_ctrl)
265  return;
266 
267  irda_notify_init(&notify);
268 
269  /* Set up callbacks */
270  notify.data_indication = irlan_client_ctrl_data_indication;
271  notify.connect_confirm = irlan_client_ctrl_connect_confirm;
272  notify.disconnect_indication = irlan_client_ctrl_disconnect_indication;
273  notify.instance = self;
274  strlcpy(notify.name, "IrLAN ctrl (c)", sizeof(notify.name));
275 
277  if (!tsap) {
278  IRDA_DEBUG(2, "%s(), Got no tsap!\n", __func__ );
279  return;
280  }
281  self->client.tsap_ctrl = tsap;
282 }
283 
284 /*
285  * Function irlan_client_connect_confirm (handle, skb)
286  *
287  * Connection to peer IrLAN laye confirmed
288  *
289  */
290 static void irlan_client_ctrl_connect_confirm(void *instance, void *sap,
291  struct qos_info *qos,
292  __u32 max_sdu_size,
294  struct sk_buff *skb)
295 {
296  struct irlan_cb *self;
297 
298  IRDA_DEBUG(4, "%s()\n", __func__ );
299 
300  self = instance;
301 
302  IRDA_ASSERT(self != NULL, return;);
303  IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
304 
305  self->client.max_sdu_size = max_sdu_size;
306  self->client.max_header_size = max_header_size;
307 
308  /* TODO: we could set the MTU depending on the max_sdu_size */
309 
311 }
312 
313 /*
314  * Function print_ret_code (code)
315  *
316  * Print return code of request to peer IrLAN layer.
317  *
318  */
319 static void print_ret_code(__u8 code)
320 {
321  switch(code) {
322  case 0:
323  printk(KERN_INFO "Success\n");
324  break;
325  case 1:
326  IRDA_WARNING("IrLAN: Insufficient resources\n");
327  break;
328  case 2:
329  IRDA_WARNING("IrLAN: Invalid command format\n");
330  break;
331  case 3:
332  IRDA_WARNING("IrLAN: Command not supported\n");
333  break;
334  case 4:
335  IRDA_WARNING("IrLAN: Parameter not supported\n");
336  break;
337  case 5:
338  IRDA_WARNING("IrLAN: Value not supported\n");
339  break;
340  case 6:
341  IRDA_WARNING("IrLAN: Not open\n");
342  break;
343  case 7:
344  IRDA_WARNING("IrLAN: Authentication required\n");
345  break;
346  case 8:
347  IRDA_WARNING("IrLAN: Invalid password\n");
348  break;
349  case 9:
350  IRDA_WARNING("IrLAN: Protocol error\n");
351  break;
352  case 255:
353  IRDA_WARNING("IrLAN: Asynchronous status\n");
354  break;
355  }
356 }
357 
358 /*
359  * Function irlan_client_parse_response (self, skb)
360  *
361  * Extract all parameters from received buffer, then feed them to
362  * check_params for parsing
363  */
364 void irlan_client_parse_response(struct irlan_cb *self, struct sk_buff *skb)
365 {
366  __u8 *frame;
367  __u8 *ptr;
368  int count;
369  int ret;
370  __u16 val_len;
371  int i;
372  char *name;
373  char *value;
374 
375  IRDA_ASSERT(skb != NULL, return;);
376 
377  IRDA_DEBUG(4, "%s() skb->len=%d\n", __func__ , (int) skb->len);
378 
379  IRDA_ASSERT(self != NULL, return;);
380  IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
381 
382  if (!skb) {
383  IRDA_ERROR("%s(), Got NULL skb!\n", __func__);
384  return;
385  }
386  frame = skb->data;
387 
388  /*
389  * Check return code and print it if not success
390  */
391  if (frame[0]) {
392  print_ret_code(frame[0]);
393  return;
394  }
395 
396  name = kmalloc(255, GFP_ATOMIC);
397  if (!name)
398  return;
399  value = kmalloc(1016, GFP_ATOMIC);
400  if (!value) {
401  kfree(name);
402  return;
403  }
404 
405  /* How many parameters? */
406  count = frame[1];
407 
408  IRDA_DEBUG(4, "%s(), got %d parameters\n", __func__ , count);
409 
410  ptr = frame+2;
411 
412  /* For all parameters */
413  for (i=0; i<count;i++) {
414  ret = irlan_extract_param(ptr, name, value, &val_len);
415  if (ret < 0) {
416  IRDA_DEBUG(2, "%s(), IrLAN, Error!\n", __func__ );
417  break;
418  }
419  ptr += ret;
420  irlan_check_response_param(self, name, value, val_len);
421  }
422  /* Cleanup */
423  kfree(name);
424  kfree(value);
425 }
426 
427 /*
428  * Function irlan_check_response_param (self, param, value, val_len)
429  *
430  * Check which parameter is received and update local variables
431  *
432  */
433 static void irlan_check_response_param(struct irlan_cb *self, char *param,
434  char *value, int val_len)
435 {
436  __u16 tmp_cpu; /* Temporary value in host order */
437  __u8 *bytes;
438  int i;
439 
440  IRDA_DEBUG(4, "%s(), parm=%s\n", __func__ , param);
441 
442  IRDA_ASSERT(self != NULL, return;);
443  IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
444 
445  /* Media type */
446  if (strcmp(param, "MEDIA") == 0) {
447  if (strcmp(value, "802.3") == 0)
448  self->media = MEDIA_802_3;
449  else
450  self->media = MEDIA_802_5;
451  return;
452  }
453  if (strcmp(param, "FILTER_TYPE") == 0) {
454  if (strcmp(value, "DIRECTED") == 0)
455  self->client.filter_type |= IRLAN_DIRECTED;
456  else if (strcmp(value, "FUNCTIONAL") == 0)
457  self->client.filter_type |= IRLAN_FUNCTIONAL;
458  else if (strcmp(value, "GROUP") == 0)
459  self->client.filter_type |= IRLAN_GROUP;
460  else if (strcmp(value, "MAC_FRAME") == 0)
461  self->client.filter_type |= IRLAN_MAC_FRAME;
462  else if (strcmp(value, "MULTICAST") == 0)
463  self->client.filter_type |= IRLAN_MULTICAST;
464  else if (strcmp(value, "BROADCAST") == 0)
465  self->client.filter_type |= IRLAN_BROADCAST;
466  else if (strcmp(value, "IPX_SOCKET") == 0)
467  self->client.filter_type |= IRLAN_IPX_SOCKET;
468 
469  }
470  if (strcmp(param, "ACCESS_TYPE") == 0) {
471  if (strcmp(value, "DIRECT") == 0)
472  self->client.access_type = ACCESS_DIRECT;
473  else if (strcmp(value, "PEER") == 0)
474  self->client.access_type = ACCESS_PEER;
475  else if (strcmp(value, "HOSTED") == 0)
476  self->client.access_type = ACCESS_HOSTED;
477  else {
478  IRDA_DEBUG(2, "%s(), unknown access type!\n", __func__ );
479  }
480  }
481  /* IRLAN version */
482  if (strcmp(param, "IRLAN_VER") == 0) {
483  IRDA_DEBUG(4, "IrLAN version %d.%d\n", (__u8) value[0],
484  (__u8) value[1]);
485 
486  self->version[0] = value[0];
487  self->version[1] = value[1];
488  return;
489  }
490  /* Which remote TSAP to use for data channel */
491  if (strcmp(param, "DATA_CHAN") == 0) {
492  self->dtsap_sel_data = value[0];
493  IRDA_DEBUG(4, "Data TSAP = %02x\n", self->dtsap_sel_data);
494  return;
495  }
496  if (strcmp(param, "CON_ARB") == 0) {
497  memcpy(&tmp_cpu, value, 2); /* Align value */
498  le16_to_cpus(&tmp_cpu); /* Convert to host order */
499  self->client.recv_arb_val = tmp_cpu;
500  IRDA_DEBUG(2, "%s(), receive arb val=%d\n", __func__ ,
501  self->client.recv_arb_val);
502  }
503  if (strcmp(param, "MAX_FRAME") == 0) {
504  memcpy(&tmp_cpu, value, 2); /* Align value */
505  le16_to_cpus(&tmp_cpu); /* Convert to host order */
506  self->client.max_frame = tmp_cpu;
507  IRDA_DEBUG(4, "%s(), max frame=%d\n", __func__ ,
508  self->client.max_frame);
509  }
510 
511  /* RECONNECT_KEY, in case the link goes down! */
512  if (strcmp(param, "RECONNECT_KEY") == 0) {
513  IRDA_DEBUG(4, "Got reconnect key: ");
514  /* for (i = 0; i < val_len; i++) */
515 /* printk("%02x", value[i]); */
516  memcpy(self->client.reconnect_key, value, val_len);
517  self->client.key_len = val_len;
518  IRDA_DEBUG(4, "\n");
519  }
520  /* FILTER_ENTRY, have we got an ethernet address? */
521  if (strcmp(param, "FILTER_ENTRY") == 0) {
522  bytes = value;
523  IRDA_DEBUG(4, "Ethernet address = %pM\n", bytes);
524  for (i = 0; i < 6; i++)
525  self->dev->dev_addr[i] = bytes[i];
526  }
527 }
528 
529 /*
530  * Function irlan_client_get_value_confirm (obj_id, value)
531  *
532  * Got results from remote LM-IAS
533  *
534  */
536  struct ias_value *value, void *priv)
537 {
538  struct irlan_cb *self;
539 
540  IRDA_DEBUG(4, "%s()\n", __func__ );
541 
542  IRDA_ASSERT(priv != NULL, return;);
543 
544  self = priv;
545  IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
546 
547  /* We probably don't need to make any more queries */
548  iriap_close(self->client.iriap);
549  self->client.iriap = NULL;
550 
551  /* Check if request succeeded */
552  if (result != IAS_SUCCESS) {
553  IRDA_DEBUG(2, "%s(), got NULL value!\n", __func__ );
555  NULL);
556  return;
557  }
558 
559  switch (value->type) {
560  case IAS_INTEGER:
561  self->dtsap_sel_ctrl = value->t.integer;
562 
563  if (value->t.integer != -1) {
565  NULL);
566  return;
567  }
568  irias_delete_value(value);
569  break;
570  default:
571  IRDA_DEBUG(2, "%s(), unknown type!\n", __func__ );
572  break;
573  }
575 }