diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /net/irda/irlan/irlan_client.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'net/irda/irlan/irlan_client.c')
-rw-r--r-- | net/irda/irlan/irlan_client.c | 576 |
1 files changed, 576 insertions, 0 deletions
diff --git a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c new file mode 100644 index 000000000000..f8e6cb0db04b --- /dev/null +++ b/net/irda/irlan/irlan_client.c | |||
@@ -0,0 +1,576 @@ | |||
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 <dagb@cs.uit.no> | ||
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 <dagb@cs.uit.no> | ||
11 | * Sources: skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov> | ||
12 | * slip.c by Laurence Culhane, <loz@holmes.demon.co.uk> | ||
13 | * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> | ||
14 | * | ||
15 | * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, | ||
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/errno.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/netdevice.h> | ||
34 | #include <linux/etherdevice.h> | ||
35 | #include <linux/if_arp.h> | ||
36 | #include <linux/bitops.h> | ||
37 | #include <net/arp.h> | ||
38 | |||
39 | #include <asm/system.h> | ||
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> | ||
52 | #include <net/irda/irlan_provider.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, | ||
58 | LM_REASON reason, | ||
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", __FUNCTION__ ); | ||
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", __FUNCTION__ ); | ||
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 | */ | ||
106 | void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr) | ||
107 | { | ||
108 | IRDA_DEBUG(1, "%s()\n", __FUNCTION__ ); | ||
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", __FUNCTION__ ); | ||
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", __FUNCTION__ ); | ||
130 | return; | ||
131 | } | ||
132 | |||
133 | /* Open TSAPs */ | ||
134 | irlan_client_open_ctrl_tsap(self); | ||
135 | irlan_open_data_tsap(self); | ||
136 | |||
137 | irlan_do_client_event(self, IRLAN_DISCOVERY_INDICATION, NULL); | ||
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 | */ | ||
149 | void irlan_client_discovery_indication(discinfo_t *discovery, | ||
150 | DISCOVERY_MODE mode, | ||
151 | void *priv) | ||
152 | { | ||
153 | struct irlan_cb *self; | ||
154 | __u32 saddr, daddr; | ||
155 | |||
156 | IRDA_DEBUG(1, "%s()\n", __FUNCTION__ ); | ||
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, return;); | ||
177 | |||
178 | IRDA_DEBUG(1, "%s(), Found instance (%08x)!\n", __FUNCTION__ , | ||
179 | daddr); | ||
180 | |||
181 | irlan_client_wakeup(self, saddr, daddr); | ||
182 | } | ||
183 | rcu_read_unlock(); | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * Function irlan_client_data_indication (handle, skb) | ||
188 | * | ||
189 | * This function gets the data that is received on the control channel | ||
190 | * | ||
191 | */ | ||
192 | static int irlan_client_ctrl_data_indication(void *instance, void *sap, | ||
193 | struct sk_buff *skb) | ||
194 | { | ||
195 | struct irlan_cb *self; | ||
196 | |||
197 | IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); | ||
198 | |||
199 | self = (struct irlan_cb *) instance; | ||
200 | |||
201 | IRDA_ASSERT(self != NULL, return -1;); | ||
202 | IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;); | ||
203 | IRDA_ASSERT(skb != NULL, return -1;); | ||
204 | |||
205 | irlan_do_client_event(self, IRLAN_DATA_INDICATION, skb); | ||
206 | |||
207 | /* Ready for a new command */ | ||
208 | IRDA_DEBUG(2, "%s(), clearing tx_busy\n", __FUNCTION__ ); | ||
209 | self->client.tx_busy = FALSE; | ||
210 | |||
211 | /* Check if we have some queued commands waiting to be sent */ | ||
212 | irlan_run_ctrl_tx_queue(self); | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | static void irlan_client_ctrl_disconnect_indication(void *instance, void *sap, | ||
218 | LM_REASON reason, | ||
219 | struct sk_buff *userdata) | ||
220 | { | ||
221 | struct irlan_cb *self; | ||
222 | struct tsap_cb *tsap; | ||
223 | struct sk_buff *skb; | ||
224 | |||
225 | IRDA_DEBUG(4, "%s(), reason=%d\n", __FUNCTION__ , reason); | ||
226 | |||
227 | self = (struct irlan_cb *) instance; | ||
228 | tsap = (struct tsap_cb *) sap; | ||
229 | |||
230 | IRDA_ASSERT(self != NULL, return;); | ||
231 | IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); | ||
232 | IRDA_ASSERT(tsap != NULL, return;); | ||
233 | IRDA_ASSERT(tsap->magic == TTP_TSAP_MAGIC, return;); | ||
234 | |||
235 | IRDA_ASSERT(tsap == self->client.tsap_ctrl, return;); | ||
236 | |||
237 | /* Remove frames queued on the control channel */ | ||
238 | while ((skb = skb_dequeue(&self->client.txq)) != NULL) { | ||
239 | dev_kfree_skb(skb); | ||
240 | } | ||
241 | self->client.tx_busy = FALSE; | ||
242 | |||
243 | irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL); | ||
244 | } | ||
245 | |||
246 | /* | ||
247 | * Function irlan_client_open_tsaps (self) | ||
248 | * | ||
249 | * Initialize callbacks and open IrTTP TSAPs | ||
250 | * | ||
251 | */ | ||
252 | static void irlan_client_open_ctrl_tsap(struct irlan_cb *self) | ||
253 | { | ||
254 | struct tsap_cb *tsap; | ||
255 | notify_t notify; | ||
256 | |||
257 | IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); | ||
258 | |||
259 | IRDA_ASSERT(self != NULL, return;); | ||
260 | IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); | ||
261 | |||
262 | /* Check if already open */ | ||
263 | if (self->client.tsap_ctrl) | ||
264 | return; | ||
265 | |||
266 | irda_notify_init(¬ify); | ||
267 | |||
268 | /* Set up callbacks */ | ||
269 | notify.data_indication = irlan_client_ctrl_data_indication; | ||
270 | notify.connect_confirm = irlan_client_ctrl_connect_confirm; | ||
271 | notify.disconnect_indication = irlan_client_ctrl_disconnect_indication; | ||
272 | notify.instance = self; | ||
273 | strlcpy(notify.name, "IrLAN ctrl (c)", sizeof(notify.name)); | ||
274 | |||
275 | tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, ¬ify); | ||
276 | if (!tsap) { | ||
277 | IRDA_DEBUG(2, "%s(), Got no tsap!\n", __FUNCTION__ ); | ||
278 | return; | ||
279 | } | ||
280 | self->client.tsap_ctrl = tsap; | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * Function irlan_client_connect_confirm (handle, skb) | ||
285 | * | ||
286 | * Connection to peer IrLAN laye confirmed | ||
287 | * | ||
288 | */ | ||
289 | static void irlan_client_ctrl_connect_confirm(void *instance, void *sap, | ||
290 | struct qos_info *qos, | ||
291 | __u32 max_sdu_size, | ||
292 | __u8 max_header_size, | ||
293 | struct sk_buff *skb) | ||
294 | { | ||
295 | struct irlan_cb *self; | ||
296 | |||
297 | IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); | ||
298 | |||
299 | self = (struct irlan_cb *) instance; | ||
300 | |||
301 | IRDA_ASSERT(self != NULL, return;); | ||
302 | IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); | ||
303 | |||
304 | self->client.max_sdu_size = max_sdu_size; | ||
305 | self->client.max_header_size = max_header_size; | ||
306 | |||
307 | /* TODO: we could set the MTU depending on the max_sdu_size */ | ||
308 | |||
309 | irlan_do_client_event(self, IRLAN_CONNECT_COMPLETE, NULL); | ||
310 | } | ||
311 | |||
312 | /* | ||
313 | * Function print_ret_code (code) | ||
314 | * | ||
315 | * Print return code of request to peer IrLAN layer. | ||
316 | * | ||
317 | */ | ||
318 | static void print_ret_code(__u8 code) | ||
319 | { | ||
320 | switch(code) { | ||
321 | case 0: | ||
322 | printk(KERN_INFO "Success\n"); | ||
323 | break; | ||
324 | case 1: | ||
325 | IRDA_WARNING("IrLAN: Insufficient resources\n"); | ||
326 | break; | ||
327 | case 2: | ||
328 | IRDA_WARNING("IrLAN: Invalid command format\n"); | ||
329 | break; | ||
330 | case 3: | ||
331 | IRDA_WARNING("IrLAN: Command not supported\n"); | ||
332 | break; | ||
333 | case 4: | ||
334 | IRDA_WARNING("IrLAN: Parameter not supported\n"); | ||
335 | break; | ||
336 | case 5: | ||
337 | IRDA_WARNING("IrLAN: Value not supported\n"); | ||
338 | break; | ||
339 | case 6: | ||
340 | IRDA_WARNING("IrLAN: Not open\n"); | ||
341 | break; | ||
342 | case 7: | ||
343 | IRDA_WARNING("IrLAN: Authentication required\n"); | ||
344 | break; | ||
345 | case 8: | ||
346 | IRDA_WARNING("IrLAN: Invalid password\n"); | ||
347 | break; | ||
348 | case 9: | ||
349 | IRDA_WARNING("IrLAN: Protocol error\n"); | ||
350 | break; | ||
351 | case 255: | ||
352 | IRDA_WARNING("IrLAN: Asynchronous status\n"); | ||
353 | break; | ||
354 | } | ||
355 | } | ||
356 | |||
357 | /* | ||
358 | * Function irlan_client_parse_response (self, skb) | ||
359 | * | ||
360 | * Extract all parameters from received buffer, then feed them to | ||
361 | * check_params for parsing | ||
362 | */ | ||
363 | void irlan_client_parse_response(struct irlan_cb *self, struct sk_buff *skb) | ||
364 | { | ||
365 | __u8 *frame; | ||
366 | __u8 *ptr; | ||
367 | int count; | ||
368 | int ret; | ||
369 | __u16 val_len; | ||
370 | int i; | ||
371 | char *name; | ||
372 | char *value; | ||
373 | |||
374 | IRDA_ASSERT(skb != NULL, return;); | ||
375 | |||
376 | IRDA_DEBUG(4, "%s() skb->len=%d\n", __FUNCTION__ , (int) skb->len); | ||
377 | |||
378 | IRDA_ASSERT(self != NULL, return;); | ||
379 | IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); | ||
380 | |||
381 | if (!skb) { | ||
382 | IRDA_ERROR("%s(), Got NULL skb!\n", __FUNCTION__); | ||
383 | return; | ||
384 | } | ||
385 | frame = skb->data; | ||
386 | |||
387 | /* | ||
388 | * Check return code and print it if not success | ||
389 | */ | ||
390 | if (frame[0]) { | ||
391 | print_ret_code(frame[0]); | ||
392 | return; | ||
393 | } | ||
394 | |||
395 | name = kmalloc(255, GFP_ATOMIC); | ||
396 | if (!name) | ||
397 | return; | ||
398 | value = kmalloc(1016, GFP_ATOMIC); | ||
399 | if (!value) { | ||
400 | kfree(name); | ||
401 | return; | ||
402 | } | ||
403 | |||
404 | /* How many parameters? */ | ||
405 | count = frame[1]; | ||
406 | |||
407 | IRDA_DEBUG(4, "%s(), got %d parameters\n", __FUNCTION__ , count); | ||
408 | |||
409 | ptr = frame+2; | ||
410 | |||
411 | /* For all parameters */ | ||
412 | for (i=0; i<count;i++) { | ||
413 | ret = irlan_extract_param(ptr, name, value, &val_len); | ||
414 | if (ret < 0) { | ||
415 | IRDA_DEBUG(2, "%s(), IrLAN, Error!\n", __FUNCTION__ ); | ||
416 | break; | ||
417 | } | ||
418 | ptr += ret; | ||
419 | irlan_check_response_param(self, name, value, val_len); | ||
420 | } | ||
421 | /* Cleanup */ | ||
422 | kfree(name); | ||
423 | kfree(value); | ||
424 | } | ||
425 | |||
426 | /* | ||
427 | * Function irlan_check_response_param (self, param, value, val_len) | ||
428 | * | ||
429 | * Check which parameter is received and update local variables | ||
430 | * | ||
431 | */ | ||
432 | static void irlan_check_response_param(struct irlan_cb *self, char *param, | ||
433 | char *value, int val_len) | ||
434 | { | ||
435 | __u16 tmp_cpu; /* Temporary value in host order */ | ||
436 | __u8 *bytes; | ||
437 | int i; | ||
438 | |||
439 | IRDA_DEBUG(4, "%s(), parm=%s\n", __FUNCTION__ , param); | ||
440 | |||
441 | IRDA_ASSERT(self != NULL, return;); | ||
442 | IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); | ||
443 | |||
444 | /* Media type */ | ||
445 | if (strcmp(param, "MEDIA") == 0) { | ||
446 | if (strcmp(value, "802.3") == 0) | ||
447 | self->media = MEDIA_802_3; | ||
448 | else | ||
449 | self->media = MEDIA_802_5; | ||
450 | return; | ||
451 | } | ||
452 | if (strcmp(param, "FILTER_TYPE") == 0) { | ||
453 | if (strcmp(value, "DIRECTED") == 0) | ||
454 | self->client.filter_type |= IRLAN_DIRECTED; | ||
455 | else if (strcmp(value, "FUNCTIONAL") == 0) | ||
456 | self->client.filter_type |= IRLAN_FUNCTIONAL; | ||
457 | else if (strcmp(value, "GROUP") == 0) | ||
458 | self->client.filter_type |= IRLAN_GROUP; | ||
459 | else if (strcmp(value, "MAC_FRAME") == 0) | ||
460 | self->client.filter_type |= IRLAN_MAC_FRAME; | ||
461 | else if (strcmp(value, "MULTICAST") == 0) | ||
462 | self->client.filter_type |= IRLAN_MULTICAST; | ||
463 | else if (strcmp(value, "BROADCAST") == 0) | ||
464 | self->client.filter_type |= IRLAN_BROADCAST; | ||
465 | else if (strcmp(value, "IPX_SOCKET") == 0) | ||
466 | self->client.filter_type |= IRLAN_IPX_SOCKET; | ||
467 | |||
468 | } | ||
469 | if (strcmp(param, "ACCESS_TYPE") == 0) { | ||
470 | if (strcmp(value, "DIRECT") == 0) | ||
471 | self->client.access_type = ACCESS_DIRECT; | ||
472 | else if (strcmp(value, "PEER") == 0) | ||
473 | self->client.access_type = ACCESS_PEER; | ||
474 | else if (strcmp(value, "HOSTED") == 0) | ||
475 | self->client.access_type = ACCESS_HOSTED; | ||
476 | else { | ||
477 | IRDA_DEBUG(2, "%s(), unknown access type!\n", __FUNCTION__ ); | ||
478 | } | ||
479 | } | ||
480 | /* IRLAN version */ | ||
481 | if (strcmp(param, "IRLAN_VER") == 0) { | ||
482 | IRDA_DEBUG(4, "IrLAN version %d.%d\n", (__u8) value[0], | ||
483 | (__u8) value[1]); | ||
484 | |||
485 | self->version[0] = value[0]; | ||
486 | self->version[1] = value[1]; | ||
487 | return; | ||
488 | } | ||
489 | /* Which remote TSAP to use for data channel */ | ||
490 | if (strcmp(param, "DATA_CHAN") == 0) { | ||
491 | self->dtsap_sel_data = value[0]; | ||
492 | IRDA_DEBUG(4, "Data TSAP = %02x\n", self->dtsap_sel_data); | ||
493 | return; | ||
494 | } | ||
495 | if (strcmp(param, "CON_ARB") == 0) { | ||
496 | memcpy(&tmp_cpu, value, 2); /* Align value */ | ||
497 | le16_to_cpus(&tmp_cpu); /* Convert to host order */ | ||
498 | self->client.recv_arb_val = tmp_cpu; | ||
499 | IRDA_DEBUG(2, "%s(), receive arb val=%d\n", __FUNCTION__ , | ||
500 | self->client.recv_arb_val); | ||
501 | } | ||
502 | if (strcmp(param, "MAX_FRAME") == 0) { | ||
503 | memcpy(&tmp_cpu, value, 2); /* Align value */ | ||
504 | le16_to_cpus(&tmp_cpu); /* Convert to host order */ | ||
505 | self->client.max_frame = tmp_cpu; | ||
506 | IRDA_DEBUG(4, "%s(), max frame=%d\n", __FUNCTION__ , | ||
507 | self->client.max_frame); | ||
508 | } | ||
509 | |||
510 | /* RECONNECT_KEY, in case the link goes down! */ | ||
511 | if (strcmp(param, "RECONNECT_KEY") == 0) { | ||
512 | IRDA_DEBUG(4, "Got reconnect key: "); | ||
513 | /* for (i = 0; i < val_len; i++) */ | ||
514 | /* printk("%02x", value[i]); */ | ||
515 | memcpy(self->client.reconnect_key, value, val_len); | ||
516 | self->client.key_len = val_len; | ||
517 | IRDA_DEBUG(4, "\n"); | ||
518 | } | ||
519 | /* FILTER_ENTRY, have we got an ethernet address? */ | ||
520 | if (strcmp(param, "FILTER_ENTRY") == 0) { | ||
521 | bytes = value; | ||
522 | IRDA_DEBUG(4, "Ethernet address = %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
523 | bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], | ||
524 | bytes[5]); | ||
525 | for (i = 0; i < 6; i++) | ||
526 | self->dev->dev_addr[i] = bytes[i]; | ||
527 | } | ||
528 | } | ||
529 | |||
530 | /* | ||
531 | * Function irlan_client_get_value_confirm (obj_id, value) | ||
532 | * | ||
533 | * Got results from remote LM-IAS | ||
534 | * | ||
535 | */ | ||
536 | void irlan_client_get_value_confirm(int result, __u16 obj_id, | ||
537 | struct ias_value *value, void *priv) | ||
538 | { | ||
539 | struct irlan_cb *self; | ||
540 | |||
541 | IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); | ||
542 | |||
543 | IRDA_ASSERT(priv != NULL, return;); | ||
544 | |||
545 | self = (struct irlan_cb *) priv; | ||
546 | IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); | ||
547 | |||
548 | /* We probably don't need to make any more queries */ | ||
549 | iriap_close(self->client.iriap); | ||
550 | self->client.iriap = NULL; | ||
551 | |||
552 | /* Check if request succeeded */ | ||
553 | if (result != IAS_SUCCESS) { | ||
554 | IRDA_DEBUG(2, "%s(), got NULL value!\n", __FUNCTION__ ); | ||
555 | irlan_do_client_event(self, IRLAN_IAS_PROVIDER_NOT_AVAIL, | ||
556 | NULL); | ||
557 | return; | ||
558 | } | ||
559 | |||
560 | switch (value->type) { | ||
561 | case IAS_INTEGER: | ||
562 | self->dtsap_sel_ctrl = value->t.integer; | ||
563 | |||
564 | if (value->t.integer != -1) { | ||
565 | irlan_do_client_event(self, IRLAN_IAS_PROVIDER_AVAIL, | ||
566 | NULL); | ||
567 | return; | ||
568 | } | ||
569 | irias_delete_value(value); | ||
570 | break; | ||
571 | default: | ||
572 | IRDA_DEBUG(2, "%s(), unknown type!\n", __FUNCTION__ ); | ||
573 | break; | ||
574 | } | ||
575 | irlan_do_client_event(self, IRLAN_IAS_PROVIDER_NOT_AVAIL, NULL); | ||
576 | } | ||