Blame view

net/irda/irlan/irlan_client.c 14.8 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*********************************************************************
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
2
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
4
5
6
7
8
9
10
11
12
13
   * Filename:      irlan_client.c
   * Version:       0.9
   * Description:   IrDA LAN Access Protocol (IrLAN) Client
   * Status:        Experimental.
   * Author:        Dag Brattli <dagb@cs.uit.no>
   * Created at:    Sun Aug 31 20:14:37 1997
   * Modified at:   Tue Dec 14 15:47:02 1999
   * Modified by:   Dag Brattli <dagb@cs.uit.no>
   * Sources:       skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
   *                slip.c by Laurence Culhane, <loz@holmes.demon.co.uk>
   *                          Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
14
15
   *
   *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
   *     All Rights Reserved.
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
17
18
19
20
   *
   *     This program is free software; you can redistribute it and/or
   *     modify it under the terms of the GNU General Public License as
   *     published by the Free Software Foundation; either version 2 of
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
   *     the License, or (at your option) any later version.
   *
96de0e252   Jan Engelhardt   Convert files to ...
23
   *     Neither Dag Brattli nor University of Tromsø admit liability nor
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
24
   *     provide warranty for any of this software. This material is
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
27
28
29
30
   *     provided "AS-IS" and at no charge.
   *
   ********************************************************************/
  
  #include <linux/kernel.h>
  #include <linux/string.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
31
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  #include <linux/errno.h>
  #include <linux/init.h>
  #include <linux/netdevice.h>
  #include <linux/etherdevice.h>
  #include <linux/if_arp.h>
  #include <linux/bitops.h>
  #include <net/arp.h>
  
  #include <asm/system.h>
  #include <asm/byteorder.h>
  
  #include <net/irda/irda.h>
  #include <net/irda/irttp.h>
  #include <net/irda/irlmp.h>
  #include <net/irda/irias_object.h>
  #include <net/irda/iriap.h>
  #include <net/irda/timer.h>
  
  #include <net/irda/irlan_common.h>
  #include <net/irda/irlan_event.h>
  #include <net/irda/irlan_eth.h>
  #include <net/irda/irlan_provider.h>
  #include <net/irda/irlan_client.h>
  
  #undef CONFIG_IRLAN_GRATUITOUS_ARP
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
57
58
  static void irlan_client_ctrl_disconnect_indication(void *instance, void *sap,
  						    LM_REASON reason,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
  						    struct sk_buff *);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
60
  static int irlan_client_ctrl_data_indication(void *instance, void *sap,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  					     struct sk_buff *skb);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
62
63
  static void irlan_client_ctrl_connect_confirm(void *instance, void *sap,
  					      struct qos_info *qos,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
65
66
  					      __u32 max_sdu_size,
  					      __u8 max_header_size,
  					      struct sk_buff *);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
67
  static void irlan_check_response_param(struct irlan_cb *self, char *param,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
69
70
71
72
73
  				       char *value, int val_len);
  static void irlan_client_open_ctrl_tsap(struct irlan_cb *self);
  
  static void irlan_client_kick_timer_expired(void *data)
  {
  	struct irlan_cb *self = (struct irlan_cb *) data;
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
74

0dc47877a   Harvey Harrison   net: replace rema...
75
76
  	IRDA_DEBUG(2, "%s()
  ", __func__ );
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
79
  
  	IRDA_ASSERT(self != NULL, return;);
  	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
80
81
  
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
  	 * If we are in peer mode, the client may not have got the discovery
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
83
  	 * indication it needs to make progress. If the client is still in
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
  	 * IDLE state, we must kick it to, but only if the provider is not IDLE
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
85
86
  	 */
  	if ((self->provider.access_type == ACCESS_PEER) &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
88
89
90
91
92
93
94
  	    (self->client.state == IRLAN_IDLE) &&
  	    (self->provider.state != IRLAN_IDLE)) {
  		irlan_client_wakeup(self, self->saddr, self->daddr);
  	}
  }
  
  static void irlan_client_start_kick_timer(struct irlan_cb *self, int timeout)
  {
0dc47877a   Harvey Harrison   net: replace rema...
95
96
  	IRDA_DEBUG(4, "%s()
  ", __func__ );
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
97
98
  
  	irda_start_timer(&self->client.kick_timer, timeout, (void *) self,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
100
101
102
103
104
105
106
107
108
109
  			 irlan_client_kick_timer_expired);
  }
  
  /*
   * Function irlan_client_wakeup (self, saddr, daddr)
   *
   *    Wake up client
   *
   */
  void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr)
  {
0dc47877a   Harvey Harrison   net: replace rema...
110
111
  	IRDA_DEBUG(1, "%s()
  ", __func__ );
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
113
114
  
  	IRDA_ASSERT(self != NULL, return;);
  	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
115
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
117
118
  	 * Check if we are already awake, or if we are a provider in direct
  	 * mode (in that case we must leave the client idle
  	 */
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
119
  	if ((self->client.state != IRLAN_IDLE) ||
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
  	    (self->provider.access_type == ACCESS_DIRECT))
  	{
0dc47877a   Harvey Harrison   net: replace rema...
122
123
  			IRDA_DEBUG(0, "%s(), already awake!
  ", __func__ );
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
125
126
127
128
129
130
131
  			return;
  	}
  
  	/* Addresses may have changed! */
  	self->saddr = saddr;
  	self->daddr = daddr;
  
  	if (self->disconnect_reason == LM_USER_REQUEST) {
0dc47877a   Harvey Harrison   net: replace rema...
132
133
  			IRDA_DEBUG(0, "%s(), still stopped by user
  ", __func__ );
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
136
137
138
139
140
141
  			return;
  	}
  
  	/* Open TSAPs */
  	irlan_client_open_ctrl_tsap(self);
  	irlan_open_data_tsap(self);
  
  	irlan_do_client_event(self, IRLAN_DISCOVERY_INDICATION, NULL);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
142

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
144
145
146
147
148
149
150
151
152
153
154
  	/* Start kick timer */
  	irlan_client_start_kick_timer(self, 2*HZ);
  }
  
  /*
   * Function irlan_discovery_indication (daddr)
   *
   *    Remote device with IrLAN server support discovered
   *
   */
  void irlan_client_discovery_indication(discinfo_t *discovery,
  				       DISCOVERY_MODE mode,
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
155
  				       void *priv)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
158
  {
  	struct irlan_cb *self;
  	__u32 saddr, daddr;
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
159

0dc47877a   Harvey Harrison   net: replace rema...
160
161
  	IRDA_DEBUG(1, "%s()
  ", __func__ );
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
  
  	IRDA_ASSERT(discovery != NULL, return;);
  
  	/*
  	 * I didn't check it, but I bet that IrLAN suffer from the same
  	 * deficiency as IrComm and doesn't handle two instances
  	 * simultaneously connecting to each other.
  	 * Same workaround, drop passive discoveries.
  	 * Jean II */
  	if(mode == DISCOVERY_PASSIVE)
  		return;
  
  	saddr = discovery->saddr;
  	daddr = discovery->daddr;
  
  	/* Find instance */
  	rcu_read_lock();
  	self = irlan_get_any();
  	if (self) {
1bc173113   Josh Triplett   [IrDA]: Fix RCU l...
181
  		IRDA_ASSERT(self->magic == IRLAN_MAGIC, goto out;);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182

0dc47877a   Harvey Harrison   net: replace rema...
183
184
  		IRDA_DEBUG(1, "%s(), Found instance (%08x)!
  ", __func__ ,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
185
  		      daddr);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
186

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187
188
  		irlan_client_wakeup(self, saddr, daddr);
  	}
1bc173113   Josh Triplett   [IrDA]: Fix RCU l...
189
  IRDA_ASSERT_LABEL(out:)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
191
  	rcu_read_unlock();
  }
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
192

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193
194
195
196
197
198
  /*
   * Function irlan_client_data_indication (handle, skb)
   *
   *    This function gets the data that is received on the control channel
   *
   */
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
199
  static int irlan_client_ctrl_data_indication(void *instance, void *sap,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
201
202
  					     struct sk_buff *skb)
  {
  	struct irlan_cb *self;
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
203

0dc47877a   Harvey Harrison   net: replace rema...
204
205
  	IRDA_DEBUG(2, "%s()
  ", __func__ );
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
206

ea1107338   Joe Perches   net: Remove casts...
207
  	self = instance;
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
208

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
209
210
211
  	IRDA_ASSERT(self != NULL, return -1;);
  	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
  	IRDA_ASSERT(skb != NULL, return -1;);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212

6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
213
214
215
  	irlan_do_client_event(self, IRLAN_DATA_INDICATION, skb);
  
  	/* Ready for a new command */
0dc47877a   Harvey Harrison   net: replace rema...
216
217
  	IRDA_DEBUG(2, "%s(), clearing tx_busy
  ", __func__ );
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
219
220
221
222
223
224
  	self->client.tx_busy = FALSE;
  
  	/* Check if we have some queued commands waiting to be sent */
  	irlan_run_ctrl_tx_queue(self);
  
  	return 0;
  }
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
225
226
227
  static void irlan_client_ctrl_disconnect_indication(void *instance, void *sap,
  						    LM_REASON reason,
  						    struct sk_buff *userdata)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
229
230
231
  {
  	struct irlan_cb *self;
  	struct tsap_cb *tsap;
  	struct sk_buff *skb;
0dc47877a   Harvey Harrison   net: replace rema...
232
233
  	IRDA_DEBUG(4, "%s(), reason=%d
  ", __func__ , reason);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
234

ea1107338   Joe Perches   net: Remove casts...
235
236
  	self = instance;
  	tsap = sap;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237
238
  
  	IRDA_ASSERT(self != NULL, return;);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
239
  	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240
241
  	IRDA_ASSERT(tsap != NULL, return;);
  	IRDA_ASSERT(tsap->magic == TTP_TSAP_MAGIC, return;);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
242

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
  	IRDA_ASSERT(tsap == self->client.tsap_ctrl, return;);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
244
  	/* Remove frames queued on the control channel */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
  	while ((skb = skb_dequeue(&self->client.txq)) != NULL) {
  		dev_kfree_skb(skb);
  	}
  	self->client.tx_busy = FALSE;
  
  	irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
  }
  
  /*
   * Function irlan_client_open_tsaps (self)
   *
   *    Initialize callbacks and open IrTTP TSAPs
   *
   */
  static void irlan_client_open_ctrl_tsap(struct irlan_cb *self)
  {
  	struct tsap_cb *tsap;
  	notify_t notify;
0dc47877a   Harvey Harrison   net: replace rema...
263
264
  	IRDA_DEBUG(4, "%s()
  ", __func__ );
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  
  	IRDA_ASSERT(self != NULL, return;);
  	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  
  	/* Check if already open */
  	if (self->client.tsap_ctrl)
  		return;
  
  	irda_notify_init(&notify);
  
  	/* Set up callbacks */
  	notify.data_indication       = irlan_client_ctrl_data_indication;
  	notify.connect_confirm       = irlan_client_ctrl_connect_confirm;
  	notify.disconnect_indication = irlan_client_ctrl_disconnect_indication;
  	notify.instance = self;
  	strlcpy(notify.name, "IrLAN ctrl (c)", sizeof(notify.name));
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
281

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
283
  	tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, &notify);
  	if (!tsap) {
0dc47877a   Harvey Harrison   net: replace rema...
284
285
  		IRDA_DEBUG(2, "%s(), Got no tsap!
  ", __func__ );
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
286
287
288
289
290
291
292
293
294
295
296
  		return;
  	}
  	self->client.tsap_ctrl = tsap;
  }
  
  /*
   * Function irlan_client_connect_confirm (handle, skb)
   *
   *    Connection to peer IrLAN laye confirmed
   *
   */
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
297
298
  static void irlan_client_ctrl_connect_confirm(void *instance, void *sap,
  					      struct qos_info *qos,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
300
  					      __u32 max_sdu_size,
  					      __u8 max_header_size,
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
301
  					      struct sk_buff *skb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
303
  {
  	struct irlan_cb *self;
0dc47877a   Harvey Harrison   net: replace rema...
304
305
  	IRDA_DEBUG(4, "%s()
  ", __func__ );
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306

ea1107338   Joe Perches   net: Remove casts...
307
  	self = instance;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
  
  	IRDA_ASSERT(self != NULL, return;);
  	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  
  	self->client.max_sdu_size = max_sdu_size;
  	self->client.max_header_size = max_header_size;
  
  	/* TODO: we could set the MTU depending on the max_sdu_size */
  
  	irlan_do_client_event(self, IRLAN_CONNECT_COMPLETE, NULL);
  }
  
  /*
   * Function print_ret_code (code)
   *
   *    Print return code of request to peer IrLAN layer.
   *
   */
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
326
  static void print_ret_code(__u8 code)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
  {
  	switch(code) {
  	case 0:
  		printk(KERN_INFO "Success
  ");
  		break;
  	case 1:
  		IRDA_WARNING("IrLAN: Insufficient resources
  ");
  		break;
  	case 2:
  		IRDA_WARNING("IrLAN: Invalid command format
  ");
  		break;
  	case 3:
  		IRDA_WARNING("IrLAN: Command not supported
  ");
  		break;
  	case 4:
  		IRDA_WARNING("IrLAN: Parameter not supported
  ");
  		break;
  	case 5:
  		IRDA_WARNING("IrLAN: Value not supported
  ");
  		break;
  	case 6:
  		IRDA_WARNING("IrLAN: Not open
  ");
  		break;
  	case 7:
  		IRDA_WARNING("IrLAN: Authentication required
  ");
  		break;
  	case 8:
  		IRDA_WARNING("IrLAN: Invalid password
  ");
  		break;
  	case 9:
  		IRDA_WARNING("IrLAN: Protocol error
  ");
  		break;
  	case 255:
  		IRDA_WARNING("IrLAN: Asynchronous status
  ");
  		break;
  	}
  }
  
  /*
   * Function irlan_client_parse_response (self, skb)
   *
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
379
   *    Extract all parameters from received buffer, then feed them to
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
380
381
382
383
384
385
386
387
388
389
   *    check_params for parsing
   */
  void irlan_client_parse_response(struct irlan_cb *self, struct sk_buff *skb)
  {
  	__u8 *frame;
  	__u8 *ptr;
  	int count;
  	int ret;
  	__u16 val_len;
  	int i;
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
390
391
392
393
  	char *name;
  	char *value;
  
  	IRDA_ASSERT(skb != NULL, return;);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
394

0dc47877a   Harvey Harrison   net: replace rema...
395
396
  	IRDA_DEBUG(4, "%s() skb->len=%d
  ", __func__ , (int) skb->len);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
397

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
399
  	IRDA_ASSERT(self != NULL, return;);
  	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
400

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
  	if (!skb) {
0dc47877a   Harvey Harrison   net: replace rema...
402
403
  		IRDA_ERROR("%s(), Got NULL skb!
  ", __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
404
405
406
  		return;
  	}
  	frame = skb->data;
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
407
408
409
  
  	/*
  	 *  Check return code and print it if not success
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
411
412
413
414
  	 */
  	if (frame[0]) {
  		print_ret_code(frame[0]);
  		return;
  	}
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
415

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
417
418
419
420
421
422
423
424
425
426
  	name = kmalloc(255, GFP_ATOMIC);
  	if (!name)
  		return;
  	value = kmalloc(1016, GFP_ATOMIC);
  	if (!value) {
  		kfree(name);
  		return;
  	}
  
  	/* How many parameters? */
  	count = frame[1];
0dc47877a   Harvey Harrison   net: replace rema...
427
428
  	IRDA_DEBUG(4, "%s(), got %d parameters
  ", __func__ , count);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
429

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
430
431
432
  	ptr = frame+2;
  
  	/* For all parameters */
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
433
  	for (i=0; i<count;i++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
435
  		ret = irlan_extract_param(ptr, name, value, &val_len);
  		if (ret < 0) {
0dc47877a   Harvey Harrison   net: replace rema...
436
437
  			IRDA_DEBUG(2, "%s(), IrLAN, Error!
  ", __func__ );
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
439
440
441
  			break;
  		}
  		ptr += ret;
  		irlan_check_response_param(self, name, value, val_len);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
442
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
443
444
445
446
447
448
449
450
451
452
453
  	/* Cleanup */
  	kfree(name);
  	kfree(value);
  }
  
  /*
   * Function irlan_check_response_param (self, param, value, val_len)
   *
   *     Check which parameter is received and update local variables
   *
   */
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
454
455
  static void irlan_check_response_param(struct irlan_cb *self, char *param,
  				       char *value, int val_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
457
458
459
  {
  	__u16 tmp_cpu; /* Temporary value in host order */
  	__u8 *bytes;
  	int i;
0dc47877a   Harvey Harrison   net: replace rema...
460
461
  	IRDA_DEBUG(4, "%s(), parm=%s
  ", __func__ , param);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
  
  	IRDA_ASSERT(self != NULL, return;);
  	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  
  	/* Media type */
  	if (strcmp(param, "MEDIA") == 0) {
  		if (strcmp(value, "802.3") == 0)
  			self->media = MEDIA_802_3;
  		else
  			self->media = MEDIA_802_5;
  		return;
  	}
  	if (strcmp(param, "FILTER_TYPE") == 0) {
  		if (strcmp(value, "DIRECTED") == 0)
  			self->client.filter_type |= IRLAN_DIRECTED;
  		else if (strcmp(value, "FUNCTIONAL") == 0)
  			self->client.filter_type |= IRLAN_FUNCTIONAL;
  		else if (strcmp(value, "GROUP") == 0)
  			self->client.filter_type |= IRLAN_GROUP;
  		else if (strcmp(value, "MAC_FRAME") == 0)
  			self->client.filter_type |= IRLAN_MAC_FRAME;
  		else if (strcmp(value, "MULTICAST") == 0)
  			self->client.filter_type |= IRLAN_MULTICAST;
  		else if (strcmp(value, "BROADCAST") == 0)
  			self->client.filter_type |= IRLAN_BROADCAST;
  		else if (strcmp(value, "IPX_SOCKET") == 0)
  			self->client.filter_type |= IRLAN_IPX_SOCKET;
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
489

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
490
491
492
493
494
495
496
497
498
  	}
  	if (strcmp(param, "ACCESS_TYPE") == 0) {
  		if (strcmp(value, "DIRECT") == 0)
  			self->client.access_type = ACCESS_DIRECT;
  		else if (strcmp(value, "PEER") == 0)
  			self->client.access_type = ACCESS_PEER;
  		else if (strcmp(value, "HOSTED") == 0)
  			self->client.access_type = ACCESS_HOSTED;
  		else {
0dc47877a   Harvey Harrison   net: replace rema...
499
500
  			IRDA_DEBUG(2, "%s(), unknown access type!
  ", __func__ );
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
502
503
504
  		}
  	}
  	/* IRLAN version */
  	if (strcmp(param, "IRLAN_VER") == 0) {
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
505
506
  		IRDA_DEBUG(4, "IrLAN version %d.%d
  ", (__u8) value[0],
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
  		      (__u8) value[1]);
  
  		self->version[0] = value[0];
  		self->version[1] = value[1];
  		return;
  	}
  	/* Which remote TSAP to use for data channel */
  	if (strcmp(param, "DATA_CHAN") == 0) {
  		self->dtsap_sel_data = value[0];
  		IRDA_DEBUG(4, "Data TSAP = %02x
  ", self->dtsap_sel_data);
  		return;
  	}
  	if (strcmp(param, "CON_ARB") == 0) {
  		memcpy(&tmp_cpu, value, 2); /* Align value */
  		le16_to_cpus(&tmp_cpu);     /* Convert to host order */
  		self->client.recv_arb_val = tmp_cpu;
0dc47877a   Harvey Harrison   net: replace rema...
524
525
  		IRDA_DEBUG(2, "%s(), receive arb val=%d
  ", __func__ ,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
527
528
529
530
531
  			   self->client.recv_arb_val);
  	}
  	if (strcmp(param, "MAX_FRAME") == 0) {
  		memcpy(&tmp_cpu, value, 2); /* Align value */
  		le16_to_cpus(&tmp_cpu);     /* Convert to host order */
  		self->client.max_frame = tmp_cpu;
0dc47877a   Harvey Harrison   net: replace rema...
532
533
  		IRDA_DEBUG(4, "%s(), max frame=%d
  ", __func__ ,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
534
535
  			   self->client.max_frame);
  	}
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
536

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
537
538
539
540
541
542
543
544
545
546
547
548
549
  	/* RECONNECT_KEY, in case the link goes down! */
  	if (strcmp(param, "RECONNECT_KEY") == 0) {
  		IRDA_DEBUG(4, "Got reconnect key: ");
  		/* for (i = 0; i < val_len; i++) */
  /* 			printk("%02x", value[i]); */
  		memcpy(self->client.reconnect_key, value, val_len);
  		self->client.key_len = val_len;
  		IRDA_DEBUG(4, "
  ");
  	}
  	/* FILTER_ENTRY, have we got an ethernet address? */
  	if (strcmp(param, "FILTER_ENTRY") == 0) {
  		bytes = value;
e174961ca   Johannes Berg   net: convert prin...
550
551
  		IRDA_DEBUG(4, "Ethernet address = %pM
  ", bytes);
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
552
  		for (i = 0; i < 6; i++)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
553
554
555
556
557
558
559
560
561
562
  			self->dev->dev_addr[i] = bytes[i];
  	}
  }
  
  /*
   * Function irlan_client_get_value_confirm (obj_id, value)
   *
   *    Got results from remote LM-IAS
   *
   */
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
563
564
  void irlan_client_get_value_confirm(int result, __u16 obj_id,
  				    struct ias_value *value, void *priv)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
565
566
  {
  	struct irlan_cb *self;
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
567

0dc47877a   Harvey Harrison   net: replace rema...
568
569
  	IRDA_DEBUG(4, "%s()
  ", __func__ );
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
570
571
  
  	IRDA_ASSERT(priv != NULL, return;);
ea1107338   Joe Perches   net: Remove casts...
572
  	self = priv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
573
574
575
576
577
578
579
580
  	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  
  	/* We probably don't need to make any more queries */
  	iriap_close(self->client.iriap);
  	self->client.iriap = NULL;
  
  	/* Check if request succeeded */
  	if (result != IAS_SUCCESS) {
0dc47877a   Harvey Harrison   net: replace rema...
581
582
  		IRDA_DEBUG(2, "%s(), got NULL value!
  ", __func__ );
6819bc2e1   YOSHIFUJI Hideaki   [NET] IRDA: Fix w...
583
  		irlan_do_client_event(self, IRLAN_IAS_PROVIDER_NOT_AVAIL,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
  				      NULL);
  		return;
  	}
  
  	switch (value->type) {
  	case IAS_INTEGER:
  		self->dtsap_sel_ctrl = value->t.integer;
  
  		if (value->t.integer != -1) {
  			irlan_do_client_event(self, IRLAN_IAS_PROVIDER_AVAIL,
  					      NULL);
  			return;
  		}
  		irias_delete_value(value);
  		break;
  	default:
0dc47877a   Harvey Harrison   net: replace rema...
600
601
  		IRDA_DEBUG(2, "%s(), unknown type!
  ", __func__ );
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
602
603
604
605
  		break;
  	}
  	irlan_do_client_event(self, IRLAN_IAS_PROVIDER_NOT_AVAIL, NULL);
  }