* better
[mascara-docs.git] / i386 / linux-2.3.21 / net / irda / irlan / irlan_common.c
blob8940343536d6cc9e100b643dcb044f0758215160
1 /*********************************************************************
2 *
3 * Filename: irlan_common.c
4 * Version: 0.9
5 * Description: IrDA LAN Access Protocol Implementation
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Aug 31 20:14:37 1997
9 * Modified at: Thu Sep 9 11:39:43 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
12 * Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
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.
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.
24 ********************************************************************/
26 #include <linux/config.h>
27 #include <linux/module.h>
29 #include <linux/kernel.h>
30 #include <linux/string.h>
31 #include <linux/init.h>
32 #include <linux/errno.h>
33 #include <linux/proc_fs.h>
34 #include <linux/netdevice.h>
35 #include <linux/etherdevice.h>
37 #include <asm/system.h>
38 #include <asm/bitops.h>
39 #include <asm/byteorder.h>
41 #include <net/irda/irda.h>
42 #include <net/irda/irttp.h>
43 #include <net/irda/irlmp.h>
44 #include <net/irda/iriap.h>
45 #include <net/irda/timer.h>
47 #include <net/irda/irlan_common.h>
48 #include <net/irda/irlan_client.h>
49 #include <net/irda/irlan_provider.h>
50 #include <net/irda/irlan_eth.h>
51 #include <net/irda/irlan_filter.h>
53 /* extern char sysctl_devname[]; */
56 * Master structure
58 hashbin_t *irlan = NULL;
59 static __u32 ckey, skey;
61 /* Module parameters */
62 static int eth = 0; /* Use "eth" or "irlan" name for devices */
63 static int access = ACCESS_PEER; /* PEER, DIRECT or HOSTED */
64 static int timeout = IRLAN_TIMEOUT;
66 static char *irlan_state[] = {
67 "IRLAN_IDLE",
68 "IRLAN_QUERY",
69 "IRLAN_CONN",
70 "IRLAN_INFO",
71 "IRLAN_MEDIA",
72 "IRLAN_OPEN",
73 "IRLAN_WAIT",
74 "IRLAN_ARB",
75 "IRLAN_DATA",
76 "IRLAN_CLOSE",
77 "IRLAN_SYNC"
80 static char *irlan_access[] = {
81 "UNKNOWN",
82 "DIRECT",
83 "PEER",
84 "HOSTED"
87 static char *irlan_media[] = {
88 "UNKNOWN",
89 "802.3",
90 "802.5"
93 static void __irlan_close(struct irlan_cb *self);
94 static int __irlan_insert_param(struct sk_buff *skb, char *param, int type,
95 __u8 value_byte, __u16 value_short,
96 __u8 *value_array, __u16 value_len);
97 void irlan_close_tsaps(struct irlan_cb *self);
99 #ifdef CONFIG_PROC_FS
100 static int irlan_proc_read(char *buf, char **start, off_t offset, int len,
101 int unused);
103 extern struct proc_dir_entry *proc_irda;
104 #endif /* CONFIG_PROC_FS */
107 * Function irlan_watchdog_timer_expired (data)
109 * Something has gone wrong during the connection establishment
112 void irlan_watchdog_timer_expired(void *data)
114 struct irmanager_event mgr_event;
115 struct irlan_cb *self;
117 DEBUG(0, __FUNCTION__ "()\n");
119 self = (struct irlan_cb *) data;
121 ASSERT(self != NULL, return;);
122 ASSERT(self->magic == IRLAN_MAGIC, return;);
124 /* Check if device still configured */
125 if (self->dev.start) {
126 DEBUG(0, __FUNCTION__
127 "(), notifying irmanager to stop irlan!\n");
128 mgr_event.event = EVENT_IRLAN_STOP;
129 sprintf(mgr_event.devname, "%s", self->ifname);
130 irmanager_notify(&mgr_event);
133 * We set this to false, so that irlan_dev_close known that
134 * notify_irmanager should actually be set to TRUE again
135 * instead of FALSE, since this close has not been initiated
136 * by the user.
138 self->notify_irmanager = FALSE;
139 } else {
140 DEBUG(0, __FUNCTION__ "(), closing instance!\n");
141 /*irlan_close(self);*/
146 * Function irlan_start_watchdog_timer (self, timeout)
151 void irlan_start_watchdog_timer(struct irlan_cb *self, int timeout)
153 DEBUG(4, __FUNCTION__ "()\n");
155 irda_start_timer(&self->watchdog_timer, timeout, (void *) self,
156 irlan_watchdog_timer_expired);
160 * Function irlan_init (void)
162 * Initialize IrLAN layer
165 int __init irlan_init(void)
167 struct irlan_cb *new;
168 __u16 hints;
170 DEBUG(4, __FUNCTION__"()\n");
172 /* Allocate master structure */
173 irlan = hashbin_new(HB_LOCAL);
174 if (irlan == NULL) {
175 printk(KERN_WARNING "IrLAN: Can't allocate hashbin!\n");
176 return -ENOMEM;
178 #ifdef CONFIG_PROC_FS
179 create_proc_entry("irlan", 0, proc_irda)->get_info = irlan_proc_read;
180 #endif /* CONFIG_PROC_FS */
182 DEBUG(4, __FUNCTION__ "()\n");
184 hints = irlmp_service_to_hint(S_LAN);
186 /* Register with IrLMP as a client */
187 ckey = irlmp_register_client(hints, irlan_client_discovery_indication,
188 NULL);
190 /* Register with IrLMP as a service */
191 skey = irlmp_register_service(hints);
193 /* Start the master IrLAN instance */
194 new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY, FALSE);
196 /* The master will only open its (listen) control TSAP */
197 irlan_provider_open_ctrl_tsap(new);
198 new->master = TRUE;
200 /* Do some fast discovery! */
201 irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS);
203 return 0;
206 void irlan_cleanup(void)
208 DEBUG(4, __FUNCTION__ "()\n");
210 irlmp_unregister_client(ckey);
212 irlmp_unregister_service(skey);
214 #ifdef CONFIG_PROC_FS
215 remove_proc_entry("irlan", proc_irda);
216 #endif /* CONFIG_PROC_FS */
218 * Delete hashbin and close all irlan client instances in it
220 hashbin_delete(irlan, (FREE_FUNC) __irlan_close);
224 * Function irlan_register_netdev (self)
226 * Registers the network device to be used. We should don't register until
227 * we have been binded to a particular provider or client.
229 int irlan_register_netdev(struct irlan_cb *self)
231 int i=0;
233 DEBUG(0, __FUNCTION__ "()\n");
235 /* Check if we should call the device eth<x> or irlan<x> */
236 if (!eth) {
237 /* Get the first free irlan<x> name */
238 do {
239 sprintf(self->ifname, "%s%d", "irlan", i++);
240 } while (dev_get(self->ifname));
242 self->dev.name = self->ifname;
244 if (register_netdev(&self->dev) != 0) {
245 DEBUG(2, __FUNCTION__ "(), register_netdev() failed!\n");
246 return -1;
248 self->netdev_registered = TRUE;
250 return 0;
254 * Function irlan_open (void)
256 * Open new instance of a client/provider, we should only register the
257 * network device if this instance is ment for a particular client/provider
259 struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr, int netdev)
261 struct irlan_cb *self;
263 DEBUG(2, __FUNCTION__ "()\n");
266 * Initialize the irlan structure.
268 self = kmalloc(sizeof(struct irlan_cb), GFP_ATOMIC);
269 if (self == NULL)
270 return NULL;
272 memset(self, 0, sizeof(struct irlan_cb));
275 * Initialize local device structure
277 self->magic = IRLAN_MAGIC;
279 ASSERT(irlan != NULL, return NULL;);
281 sprintf(self->ifname, "%s", "unknown");
283 self->dev.priv = (void *) self;
284 self->dev.next = NULL;
285 self->dev.init = irlan_eth_init;
287 self->saddr = saddr;
288 self->daddr = daddr;
290 /* Provider access can only be PEER, DIRECT, or HOSTED */
291 self->provider.access_type = access;
292 self->media = MEDIA_802_3;
294 self->notify_irmanager = TRUE;
296 init_timer(&self->watchdog_timer);
297 init_timer(&self->client.kick_timer);
299 hashbin_insert(irlan, (QUEUE *) self, daddr, NULL);
301 skb_queue_head_init(&self->client.txq);
303 irlan_next_client_state(self, IRLAN_IDLE);
304 irlan_next_provider_state(self, IRLAN_IDLE);
306 /* Register network device now, or wait until some later time? */
307 if (netdev)
308 irlan_register_netdev(self);
310 return self;
313 * Function irlan_close (self)
315 * This function closes and deallocates the IrLAN client instances. Be
316 * aware that other functions which calles client_close() must call
317 * hashbin_remove() first!!!
320 static void __irlan_close(struct irlan_cb *self)
322 struct sk_buff *skb;
324 DEBUG(2, __FUNCTION__ "()\n");
326 ASSERT(self != NULL, return;);
327 ASSERT(self->magic == IRLAN_MAGIC, return;);
329 del_timer(&self->watchdog_timer);
330 del_timer(&self->client.kick_timer);
332 /* Close all open connections and remove TSAPs */
333 irlan_close_tsaps(self);
335 /* Remove frames queued on the control channel */
336 while ((skb = skb_dequeue(&self->client.txq))) {
337 dev_kfree_skb(skb);
340 if (self->netdev_registered) {
341 unregister_netdev(&self->dev);
342 self->netdev_registered = FALSE;
345 self->magic = 0;
346 kfree(self);
350 * Function irlan_close (self)
352 * Close instance
355 void irlan_close(struct irlan_cb *self)
357 struct irlan_cb *entry;
359 DEBUG(0, __FUNCTION__ "()\n");
361 ASSERT(self != NULL, return;);
362 ASSERT(self->magic == IRLAN_MAGIC, return;);
364 /* Check if device is still configured */
365 if (self->dev.start) {
366 DEBUG(0, __FUNCTION__
367 "(), Device still configured, closing later!\n");
369 /* Give it a chance to reconnect */
370 irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
371 return;
373 DEBUG(2, __FUNCTION__ "(), daddr=%08x\n", self->daddr);
374 entry = hashbin_remove(irlan, self->daddr, NULL);
376 ASSERT(entry == self, return;);
378 __irlan_close(self);
382 * Function irlan_connect_indication (instance, sap, qos, max_sdu_size, skb)
384 * Here we receive the connect indication for the data channel
387 void irlan_connect_indication(void *instance, void *sap, struct qos_info *qos,
388 __u32 max_sdu_size, __u8 max_header_size,
389 struct sk_buff *skb)
391 struct irlan_cb *self;
392 struct tsap_cb *tsap;
394 DEBUG(2, __FUNCTION__ "()\n");
396 self = (struct irlan_cb *) instance;
397 tsap = (struct tsap_cb *) sap;
399 ASSERT(self != NULL, return;);
400 ASSERT(self->magic == IRLAN_MAGIC, return;);
401 ASSERT(tsap == self->tsap_data,return;);
403 self->max_sdu_size = max_sdu_size;
404 self->max_header_size = max_header_size;
406 DEBUG(0, "IrLAN, We are now connected!\n");
408 del_timer(&self->watchdog_timer);
410 irlan_do_provider_event(self, IRLAN_DATA_CONNECT_INDICATION, skb);
411 irlan_do_client_event(self, IRLAN_DATA_CONNECT_INDICATION, skb);
413 if (self->provider.access_type == ACCESS_PEER) {
415 * Data channel is open, so we are now allowed to
416 * configure the remote filter
418 irlan_get_unicast_addr(self);
419 irlan_open_unicast_addr(self);
421 /* Ready to transfer Ethernet frames (at last) */
422 self->dev.tbusy = 0;
425 void irlan_connect_confirm(void *instance, void *sap, struct qos_info *qos,
426 __u32 max_sdu_size, __u8 max_header_size,
427 struct sk_buff *skb)
429 struct irlan_cb *self;
431 self = (struct irlan_cb *) instance;
433 ASSERT(self != NULL, return;);
434 ASSERT(self->magic == IRLAN_MAGIC, return;);
436 self->max_sdu_size = max_sdu_size;
437 self->max_header_size = max_header_size;
439 /* TODO: we could set the MTU depending on the max_sdu_size */
441 DEBUG(2, "IrLAN, We are now connected!\n");
442 del_timer(&self->watchdog_timer);
445 * Data channel is open, so we are now allowed to configure the remote
446 * filter
448 irlan_get_unicast_addr(self);
449 irlan_open_unicast_addr(self);
451 /* Open broadcast and multicast filter by default */
452 irlan_set_broadcast_filter(self, TRUE);
453 irlan_set_multicast_filter(self, TRUE);
455 /* Ready to transfer Ethernet frames */
456 self->dev.tbusy = 0;
458 irlan_eth_send_gratuitous_arp(&self->dev);
462 * Function irlan_client_disconnect_indication (handle)
464 * Callback function for the IrTTP layer. Indicates a disconnection of
465 * the specified connection (handle)
467 void irlan_disconnect_indication(void *instance, void *sap, LM_REASON reason,
468 struct sk_buff *userdata)
470 struct irlan_cb *self;
471 struct tsap_cb *tsap;
473 DEBUG(0, __FUNCTION__ "(), reason=%d\n", reason);
475 self = (struct irlan_cb *) instance;
476 tsap = (struct tsap_cb *) sap;
478 ASSERT(self != NULL, return;);
479 ASSERT(self->magic == IRLAN_MAGIC, return;);
480 ASSERT(tsap != NULL, return;);
481 ASSERT(tsap->magic == TTP_TSAP_MAGIC, return;);
483 ASSERT(tsap == self->tsap_data, return;);
485 DEBUG(2, "IrLAN, data channel disconnected by peer!\n");
487 switch(reason) {
488 case LM_USER_REQUEST: /* User request */
489 irlan_close(self);
490 break;
491 case LM_LAP_DISCONNECT: /* Unexpected IrLAP disconnect */
492 irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
493 break;
494 case LM_CONNECT_FAILURE: /* Failed to establish IrLAP connection */
495 DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n");
496 break;
497 case LM_LAP_RESET: /* IrLAP reset */
498 DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n");
499 break;
500 case LM_INIT_DISCONNECT:
501 DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n");
502 break;
503 default:
504 break;
507 irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
508 irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);
511 void irlan_open_data_tsap(struct irlan_cb *self)
513 struct tsap_cb *tsap;
514 notify_t notify;
516 DEBUG(2, __FUNCTION__ "()\n");
518 ASSERT(self != NULL, return;);
519 ASSERT(self->magic == IRLAN_MAGIC, return;);
521 /* Check if already open */
522 if (self->tsap_data)
523 return;
525 irda_notify_init(&notify);
527 notify.data_indication = irlan_eth_receive;
528 notify.udata_indication = irlan_eth_receive;
529 notify.connect_indication = irlan_connect_indication;
530 notify.connect_confirm = irlan_connect_confirm;
531 /*notify.flow_indication = irlan_eth_flow_indication;*/
532 notify.disconnect_indication = irlan_disconnect_indication;
533 notify.instance = self;
534 strncpy(notify.name, "IrLAN data", NOTIFY_MAX_NAME);
536 tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, &notify);
537 if (!tsap) {
538 DEBUG(2, __FUNCTION__ "(), Got no tsap!\n");
539 return;
541 self->tsap_data = tsap;
544 * This is the data TSAP selector which we will pass to the client
545 * when the client ask for it.
547 self->stsap_sel_data = self->tsap_data->stsap_sel;
550 void irlan_close_tsaps(struct irlan_cb *self)
552 DEBUG(4, __FUNCTION__ "()\n");
554 ASSERT(self != NULL, return;);
555 ASSERT(self->magic == IRLAN_MAGIC, return;);
558 * Disconnect and close all open TSAP connections
560 if (self->tsap_data) {
561 irttp_disconnect_request(self->tsap_data, NULL, P_NORMAL);
562 irttp_close_tsap(self->tsap_data);
563 self->tsap_data = NULL;
565 if (self->client.tsap_ctrl) {
566 irttp_disconnect_request(self->client.tsap_ctrl, NULL,
567 P_NORMAL);
568 irttp_close_tsap(self->client.tsap_ctrl);
569 self->client.tsap_ctrl = NULL;
571 if (self->provider.tsap_ctrl) {
572 irttp_disconnect_request(self->provider.tsap_ctrl, NULL,
573 P_NORMAL);
574 irttp_close_tsap(self->provider.tsap_ctrl);
575 self->provider.tsap_ctrl = NULL;
580 * Function irlan_ias_register (self, tsap_sel)
582 * Register with LM-IAS
585 void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel)
587 struct ias_object *obj;
588 struct ias_value *new_value;
590 ASSERT(self != NULL, return;);
591 ASSERT(self->magic == IRLAN_MAGIC, return;);
594 * Check if object has already been registred by a previous provider.
595 * If that is the case, we just change the value of the attribute
597 if (!irias_find_object("IrLAN")) {
598 obj = irias_new_object("IrLAN", IAS_IRLAN_ID);
599 irias_add_integer_attrib(obj, "IrDA:TinyTP:LsapSel", tsap_sel);
600 irias_insert_object(obj);
601 } else {
602 new_value = irias_new_integer_value(tsap_sel);
603 irias_object_change_attribute("IrLAN", "IrDA:TinyTP:LsapSel",
604 new_value);
607 /* Register PnP object only if not registred before */
608 if (!irias_find_object("PnP")) {
609 obj = irias_new_object("PnP", IAS_PNP_ID);
610 #if 0
611 irias_add_string_attrib(obj, "Name", sysctl_devname);
612 #else
613 irias_add_string_attrib(obj, "Name", "Linux");
614 #endif
615 irias_add_string_attrib(obj, "DeviceID", "HWP19F0");
616 irias_add_integer_attrib(obj, "CompCnt", 1);
617 if (self->provider.access_type == ACCESS_PEER)
618 irias_add_string_attrib(obj, "Comp#01", "PNP8389");
619 else
620 irias_add_string_attrib(obj, "Comp#01", "PNP8294");
622 irias_add_string_attrib(obj, "Manufacturer", "Linux-IrDA Project");
623 irias_insert_object(obj);
628 * Function irlan_run_ctrl_tx_queue (self)
630 * Try to send the next command in the control transmit queue
633 int irlan_run_ctrl_tx_queue(struct irlan_cb *self)
635 struct sk_buff *skb;
637 DEBUG(3, __FUNCTION__ "()\n");
639 if (irda_lock(&self->client.tx_busy) == FALSE)
640 return -EBUSY;
642 skb = skb_dequeue(&self->client.txq);
643 if (!skb) {
644 self->client.tx_busy = FALSE;
645 return 0;
648 /* Check that it's really possible to send commands */
649 if ((self->client.tsap_ctrl == NULL) ||
650 (self->client.state == IRLAN_IDLE))
652 self->client.tx_busy = FALSE;
653 dev_kfree_skb(skb);
654 return -1;
656 DEBUG(3, __FUNCTION__ "(), sending ...\n");
658 return irttp_data_request(self->client.tsap_ctrl, skb);
662 * Function irlan_ctrl_data_request (self, skb)
664 * This function makes sure that commands on the control channel is being
665 * sent in a command/response fashion
667 void irlan_ctrl_data_request(struct irlan_cb *self, struct sk_buff *skb)
669 DEBUG(2, __FUNCTION__ "()\n");
671 /* Queue command */
672 skb_queue_tail(&self->client.txq, skb);
674 /* Try to send command */
675 irlan_run_ctrl_tx_queue(self);
679 * Function irlan_get_provider_info (self)
681 * Send Get Provider Information command to peer IrLAN layer
684 void irlan_get_provider_info(struct irlan_cb *self)
686 struct sk_buff *skb;
687 __u8 *frame;
689 DEBUG(4, __FUNCTION__ "()\n");
691 ASSERT(self != NULL, return;);
692 ASSERT(self->magic == IRLAN_MAGIC, return;);
694 skb = dev_alloc_skb(64);
695 if (!skb)
696 return;
698 /* Reserve space for TTP, LMP, and LAP header */
699 skb_reserve(skb, self->client.max_header_size);
700 skb_put(skb, 2);
702 frame = skb->data;
704 frame[0] = CMD_GET_PROVIDER_INFO;
705 frame[1] = 0x00; /* Zero parameters */
707 /* irttp_data_request(self->client.tsap_ctrl, skb); */
708 irlan_ctrl_data_request(self, skb);
712 * Function irlan_open_data_channel (self)
714 * Send an Open Data Command to provider
717 void irlan_open_data_channel(struct irlan_cb *self)
719 struct sk_buff *skb;
720 __u8 *frame;
722 DEBUG(4, __FUNCTION__ "()\n");
724 ASSERT(self != NULL, return;);
725 ASSERT(self->magic == IRLAN_MAGIC, return;);
727 skb = dev_alloc_skb(64);
728 if (!skb)
729 return;
731 skb_reserve(skb, self->client.max_header_size);
732 skb_put(skb, 2);
734 frame = skb->data;
736 /* Build frame */
737 frame[0] = CMD_OPEN_DATA_CHANNEL;
738 frame[1] = 0x02; /* Two parameters */
740 irlan_insert_string_param(skb, "MEDIA", "802.3");
741 irlan_insert_string_param(skb, "ACCESS_TYPE", "DIRECT");
742 /* irlan_insert_string_param(skb, "MODE", "UNRELIABLE"); */
744 /* self->use_udata = TRUE; */
746 /* irttp_data_request(self->client.tsap_ctrl, skb); */
747 irlan_ctrl_data_request(self, skb);
750 void irlan_close_data_channel(struct irlan_cb *self)
752 struct sk_buff *skb;
753 __u8 *frame;
755 DEBUG(4, __FUNCTION__ "()\n");
757 ASSERT(self != NULL, return;);
758 ASSERT(self->magic == IRLAN_MAGIC, return;);
760 /* Check if the TSAP is still there */
761 if (self->client.tsap_ctrl == NULL)
762 return;
764 skb = dev_alloc_skb(64);
765 if (!skb)
766 return;
768 skb_reserve(skb, self->client.max_header_size);
769 skb_put(skb, 2);
771 frame = skb->data;
773 /* Build frame */
774 frame[0] = CMD_CLOSE_DATA_CHAN;
775 frame[1] = 0x01; /* Two parameters */
777 irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
779 irlan_ctrl_data_request(self, skb);
783 * Function irlan_open_unicast_addr (self)
785 * Make IrLAN provider accept ethernet frames addressed to the unicast
786 * address.
789 void irlan_open_unicast_addr(struct irlan_cb *self)
791 struct sk_buff *skb;
792 __u8 *frame;
794 DEBUG(4, __FUNCTION__ "()\n");
796 ASSERT(self != NULL, return;);
797 ASSERT(self->magic == IRLAN_MAGIC, return;);
799 skb = dev_alloc_skb(128);
800 if (!skb)
801 return;
803 /* Reserve space for TTP, LMP, and LAP header */
804 skb_reserve(skb, self->max_header_size);
805 skb_put(skb, 2);
807 frame = skb->data;
809 frame[0] = CMD_FILTER_OPERATION;
810 frame[1] = 0x03; /* Three parameters */
811 irlan_insert_byte_param(skb, "DATA_CHAN" , self->dtsap_sel_data);
812 irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
813 irlan_insert_string_param(skb, "FILTER_MODE", "FILTER");
815 /* irttp_data_request(self->client.tsap_ctrl, skb); */
816 irlan_ctrl_data_request(self, skb);
820 * Function irlan_set_broadcast_filter (self, status)
822 * Make IrLAN provider accept ethernet frames addressed to the broadcast
823 * address. Be careful with the use of this one, since there may be a lot
824 * of broadcast traffic out there. We can still function without this
825 * one but then _we_ have to initiate all communication with other
826 * hosts, since ARP request for this host will not be answered.
828 void irlan_set_broadcast_filter(struct irlan_cb *self, int status)
830 struct sk_buff *skb;
831 __u8 *frame;
833 DEBUG(2, __FUNCTION__ "()\n");
835 ASSERT(self != NULL, return;);
836 ASSERT(self->magic == IRLAN_MAGIC, return;);
838 skb = dev_alloc_skb(128);
839 if (!skb)
840 return;
842 /* Reserve space for TTP, LMP, and LAP header */
843 skb_reserve(skb, self->client.max_header_size);
844 skb_put(skb, 2);
846 frame = skb->data;
848 frame[0] = CMD_FILTER_OPERATION;
849 frame[1] = 0x03; /* Three parameters */
850 irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
851 irlan_insert_string_param(skb, "FILTER_TYPE", "BROADCAST");
852 if (status)
853 irlan_insert_string_param(skb, "FILTER_MODE", "FILTER");
854 else
855 irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
857 /* irttp_data_request(self->client.tsap_ctrl, skb); */
858 irlan_ctrl_data_request(self, skb);
862 * Function irlan_set_multicast_filter (self, status)
864 * Make IrLAN provider accept ethernet frames addressed to the multicast
865 * address.
868 void irlan_set_multicast_filter(struct irlan_cb *self, int status)
870 struct sk_buff *skb;
871 __u8 *frame;
873 DEBUG(2, __FUNCTION__ "()\n");
875 ASSERT(self != NULL, return;);
876 ASSERT(self->magic == IRLAN_MAGIC, return;);
878 skb = dev_alloc_skb(128);
879 if (!skb)
880 return;
882 /* Reserve space for TTP, LMP, and LAP header */
883 skb_reserve(skb, self->client.max_header_size);
884 skb_put(skb, 2);
886 frame = skb->data;
888 frame[0] = CMD_FILTER_OPERATION;
889 frame[1] = 0x03; /* Three parameters */
890 irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
891 irlan_insert_string_param(skb, "FILTER_TYPE", "MULTICAST");
892 if (status)
893 irlan_insert_string_param(skb, "FILTER_MODE", "ALL");
894 else
895 irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
897 /* irttp_data_request(self->client.tsap_ctrl, skb); */
898 irlan_ctrl_data_request(self, skb);
902 * Function irlan_get_unicast_addr (self)
904 * Retrives the unicast address from the IrLAN provider. This address
905 * will be inserted into the devices structure, so the ethernet layer
906 * can construct its packets.
909 void irlan_get_unicast_addr(struct irlan_cb *self)
911 struct sk_buff *skb;
912 __u8 *frame;
914 DEBUG(2, __FUNCTION__ "()\n");
916 ASSERT(self != NULL, return;);
917 ASSERT(self->magic == IRLAN_MAGIC, return;);
919 skb = dev_alloc_skb(128);
920 if (!skb)
921 return;
923 /* Reserve space for TTP, LMP, and LAP header */
924 skb_reserve(skb, self->client.max_header_size);
925 skb_put(skb, 2);
927 frame = skb->data;
929 frame[0] = CMD_FILTER_OPERATION;
930 frame[1] = 0x03; /* Three parameters */
931 irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
932 irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
933 irlan_insert_string_param(skb, "FILTER_OPERATION", "DYNAMIC");
935 /* irttp_data_request(self->client.tsap_ctrl, skb); */
936 irlan_ctrl_data_request(self, skb);
940 * Function irlan_get_media_char (self)
945 void irlan_get_media_char(struct irlan_cb *self)
947 struct sk_buff *skb;
948 __u8 *frame;
950 DEBUG(4, __FUNCTION__ "()\n");
952 ASSERT(self != NULL, return;);
953 ASSERT(self->magic == IRLAN_MAGIC, return;);
955 skb = dev_alloc_skb(64);
956 if (!skb)
957 return;
959 /* Reserve space for TTP, LMP, and LAP header */
960 skb_reserve(skb, self->client.max_header_size);
961 skb_put(skb, 2);
963 frame = skb->data;
965 /* Build frame */
966 frame[0] = CMD_GET_MEDIA_CHAR;
967 frame[1] = 0x01; /* One parameter */
969 irlan_insert_string_param(skb, "MEDIA", "802.3");
971 /* irttp_data_request(self->client.tsap_ctrl, skb); */
972 irlan_ctrl_data_request(self, skb);
976 * Function insert_byte_param (skb, param, value)
978 * Insert byte parameter into frame
981 int irlan_insert_byte_param(struct sk_buff *skb, char *param, __u8 value)
983 return __irlan_insert_param(skb, param, IRLAN_BYTE, value, 0, NULL, 0);
986 int irlan_insert_short_param(struct sk_buff *skb, char *param, __u16 value)
988 return __irlan_insert_param(skb, param, IRLAN_SHORT, 0, value, NULL, 0);
992 * Function insert_string (skb, param, value)
994 * Insert string parameter into frame
997 int irlan_insert_string_param(struct sk_buff *skb, char *param, char *string)
999 int string_len = strlen(string);
1001 return __irlan_insert_param(skb, param, IRLAN_ARRAY, 0, 0, string,
1002 string_len);
1006 * Function insert_array_param(skb, param, value, len_value)
1008 * Insert array parameter into frame
1011 int irlan_insert_array_param(struct sk_buff *skb, char *name, __u8 *array,
1012 __u16 array_len)
1014 return __irlan_insert_param(skb, name, IRLAN_ARRAY, 0, 0, array,
1015 array_len);
1019 * Function insert_param (skb, param, value, byte)
1021 * Insert parameter at end of buffer, structure of a parameter is:
1023 * -----------------------------------------------------------------------
1024 * | Name Length[1] | Param Name[1..255] | Val Length[2] | Value[0..1016]|
1025 * -----------------------------------------------------------------------
1027 static int __irlan_insert_param(struct sk_buff *skb, char *param, int type,
1028 __u8 value_byte, __u16 value_short,
1029 __u8 *value_array, __u16 value_len)
1031 __u8 *frame;
1032 __u8 param_len;
1033 __u16 tmp_le; /* Temporary value in little endian format */
1034 int n=0;
1036 if (skb == NULL) {
1037 DEBUG(2, __FUNCTION__ "(), Got NULL skb\n");
1038 return 0;
1041 param_len = strlen(param);
1042 switch (type) {
1043 case IRLAN_BYTE:
1044 value_len = 1;
1045 break;
1046 case IRLAN_SHORT:
1047 value_len = 2;
1048 break;
1049 case IRLAN_ARRAY:
1050 ASSERT(value_array != NULL, return 0;);
1051 ASSERT(value_len > 0, return 0;);
1052 break;
1053 default:
1054 DEBUG(2, __FUNCTION__ "(), Unknown parameter type!\n");
1055 return 0;
1056 break;
1059 /* Insert at end of sk-buffer */
1060 frame = skb->tail;
1062 /* Make space for data */
1063 if (skb_tailroom(skb) < (param_len+value_len+3)) {
1064 DEBUG(2, __FUNCTION__ "(), No more space at end of skb\n");
1065 return 0;
1067 skb_put(skb, param_len+value_len+3);
1069 /* Insert parameter length */
1070 frame[n++] = param_len;
1072 /* Insert parameter */
1073 memcpy(frame+n, param, param_len); n += param_len;
1075 /* Insert value length (2 byte little endian format, LSB first) */
1076 tmp_le = cpu_to_le16(value_len);
1077 memcpy(frame+n, &tmp_le, 2); n += 2; /* To avoid alignment problems */
1079 /* Insert value */
1080 switch (type) {
1081 case IRLAN_BYTE:
1082 frame[n++] = value_byte;
1083 break;
1084 case IRLAN_SHORT:
1085 tmp_le = cpu_to_le16(value_short);
1086 memcpy(frame+n, &tmp_le, 2); n += 2;
1087 break;
1088 case IRLAN_ARRAY:
1089 memcpy(frame+n, value_array, value_len); n+=value_len;
1090 break;
1091 default:
1092 break;
1094 ASSERT(n == (param_len+value_len+3), return 0;);
1096 return param_len+value_len+3;
1100 * Function irlan_extract_param (buf, name, value, len)
1102 * Extracts a single parameter name/value pair from buffer and updates
1103 * the buffer pointer to point to the next name/value pair.
1105 int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len)
1107 __u8 name_len;
1108 __u16 val_len;
1109 int n=0;
1111 DEBUG(4, __FUNCTION__ "()\n");
1113 /* get length of parameter name (1 byte) */
1114 name_len = buf[n++];
1116 if (name_len > 254) {
1117 DEBUG(2, __FUNCTION__ "(), name_len > 254\n");
1118 return -RSP_INVALID_COMMAND_FORMAT;
1121 /* get parameter name */
1122 memcpy(name, buf+n, name_len);
1123 name[name_len] = '\0';
1124 n+=name_len;
1127 * Get length of parameter value (2 bytes in little endian
1128 * format)
1130 memcpy(&val_len, buf+n, 2); /* To avoid alignment problems */
1131 le16_to_cpus(&val_len); n+=2;
1133 if (val_len > 1016) {
1134 DEBUG(2, __FUNCTION__ "(), parameter length to long\n");
1135 return -RSP_INVALID_COMMAND_FORMAT;
1137 *len = val_len;
1139 /* get parameter value */
1140 memcpy(value, buf+n, val_len);
1141 value[val_len] = '\0';
1142 n+=val_len;
1144 DEBUG(4, "Parameter: %s ", name);
1145 DEBUG(4, "Value: %s\n", value);
1147 return n;
1150 #ifdef CONFIG_PROC_FS
1152 * Function irlan_client_proc_read (buf, start, offset, len, unused)
1154 * Give some info to the /proc file system
1156 static int irlan_proc_read(char *buf, char **start, off_t offset, int len,
1157 int unused)
1159 struct irlan_cb *self;
1160 unsigned long flags;
1162 save_flags(flags);
1163 cli();
1165 ASSERT(irlan != NULL, return 0;);
1167 len = 0;
1169 len += sprintf(buf+len, "IrLAN instances:\n");
1171 self = (struct irlan_cb *) hashbin_get_first(irlan);
1172 while (self != NULL) {
1173 ASSERT(self->magic == IRLAN_MAGIC, return len;);
1175 /* Don't display the master server */
1176 if (self->master == 0) {
1177 len += sprintf(buf+len, "ifname: %s,\n",
1178 self->ifname);
1179 len += sprintf(buf+len, "client state: %s, ",
1180 irlan_state[ self->client.state]);
1181 len += sprintf(buf+len, "provider state: %s,\n",
1182 irlan_state[ self->provider.state]);
1183 len += sprintf(buf+len, "saddr: %#08x, ",
1184 self->saddr);
1185 len += sprintf(buf+len, "daddr: %#08x\n",
1186 self->daddr);
1187 len += sprintf(buf+len, "version: %d.%d,\n",
1188 self->version[1], self->version[0]);
1189 len += sprintf(buf+len, "access type: %s\n",
1190 irlan_access[self->client.access_type]);
1191 len += sprintf(buf+len, "media: %s\n",
1192 irlan_media[self->media]);
1194 len += sprintf(buf+len, "local filter:\n");
1195 len += sprintf(buf+len, "remote filter: ");
1196 len += irlan_print_filter(self->client.filter_type,
1197 buf+len);
1199 len += sprintf(buf+len, "tx busy: %s\n",
1200 self->dev.tbusy ? "TRUE" : "FALSE");
1202 len += sprintf(buf+len, "\n");
1205 self = (struct irlan_cb *) hashbin_get_next(irlan);
1207 restore_flags(flags);
1209 return len;
1211 #endif
1214 * Function print_ret_code (code)
1216 * Print return code of request to peer IrLAN layer.
1219 void print_ret_code(__u8 code)
1221 switch(code) {
1222 case 0:
1223 printk(KERN_INFO "Success\n");
1224 break;
1225 case 1:
1226 WARNING("IrLAN: Insufficient resources\n");
1227 break;
1228 case 2:
1229 WARNING("IrLAN: Invalid command format\n");
1230 break;
1231 case 3:
1232 WARNING("IrLAN: Command not supported\n");
1233 break;
1234 case 4:
1235 WARNING("IrLAN: Parameter not supported\n");
1236 break;
1237 case 5:
1238 WARNING("IrLAN: Value not supported\n");
1239 break;
1240 case 6:
1241 WARNING("IrLAN: Not open\n");
1242 break;
1243 case 7:
1244 WARNING("IrLAN: Authentication required\n");
1245 break;
1246 case 8:
1247 WARNING("IrLAN: Invalid password\n");
1248 break;
1249 case 9:
1250 WARNING("IrLAN: Protocol error\n");
1251 break;
1252 case 255:
1253 WARNING("IrLAN: Asynchronous status\n");
1254 break;
1258 void irlan_mod_inc_use_count(void)
1260 #ifdef MODULE
1261 MOD_INC_USE_COUNT;
1262 #endif
1265 void irlan_mod_dec_use_count(void)
1267 #ifdef MODULE
1268 MOD_DEC_USE_COUNT;
1269 #endif
1272 #ifdef MODULE
1274 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
1275 MODULE_DESCRIPTION("The Linux IrDA LAN protocol");
1277 MODULE_PARM(eth, "i");
1278 MODULE_PARM(access, "i");
1279 MODULE_PARM(timeout, "i");
1282 * Function init_module (void)
1284 * Initialize the IrLAN module, this function is called by the
1285 * modprobe(1) program.
1287 int init_module(void)
1289 return irlan_init();
1293 * Function cleanup_module (void)
1295 * Remove the IrLAN module, this function is called by the rmmod(1)
1296 * program
1298 void cleanup_module(void)
1300 /* Free some memory */
1301 irlan_cleanup();
1304 #endif /* MODULE */