1 /*********************************************************************
3 * Filename: irlan_common.c
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[]; */
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
[] = {
80 static char *irlan_access
[] = {
87 static char *irlan_media
[] = {
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
);
100 static int irlan_proc_read(char *buf
, char **start
, off_t offset
, int len
,
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
138 self
->notify_irmanager
= FALSE
;
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;
170 DEBUG(4, __FUNCTION__
"()\n");
172 /* Allocate master structure */
173 irlan
= hashbin_new(HB_LOCAL
);
175 printk(KERN_WARNING
"IrLAN: Can't allocate hashbin!\n");
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
,
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);
200 /* Do some fast discovery! */
201 irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS
);
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
)
233 DEBUG(0, __FUNCTION__
"()\n");
235 /* Check if we should call the device eth<x> or irlan<x> */
237 /* Get the first free irlan<x> name */
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");
248 self
->netdev_registered
= TRUE
;
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
);
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
;
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? */
308 irlan_register_netdev(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
)
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
))) {
340 if (self
->netdev_registered
) {
341 unregister_netdev(&self
->dev
);
342 self
->netdev_registered
= FALSE
;
350 * Function irlan_close (self)
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
);
373 DEBUG(2, __FUNCTION__
"(), daddr=%08x\n", self
->daddr
);
374 entry
= hashbin_remove(irlan
, self
->daddr
, NULL
);
376 ASSERT(entry
== self
, return;);
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
,
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) */
425 void irlan_connect_confirm(void *instance
, void *sap
, struct qos_info
*qos
,
426 __u32 max_sdu_size
, __u8 max_header_size
,
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
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 */
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");
488 case LM_USER_REQUEST
: /* User request */
491 case LM_LAP_DISCONNECT
: /* Unexpected IrLAP disconnect */
492 irlan_start_watchdog_timer(self
, IRLAN_TIMEOUT
);
494 case LM_CONNECT_FAILURE
: /* Failed to establish IrLAP connection */
495 DEBUG(2, __FUNCTION__
"(), LM_CONNECT_FAILURE not impl\n");
497 case LM_LAP_RESET
: /* IrLAP reset */
498 DEBUG(2, __FUNCTION__
"(), LM_CONNECT_FAILURE not impl\n");
500 case LM_INIT_DISCONNECT
:
501 DEBUG(2, __FUNCTION__
"(), LM_CONNECT_FAILURE not impl\n");
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
;
516 DEBUG(2, __FUNCTION__
"()\n");
518 ASSERT(self
!= NULL
, return;);
519 ASSERT(self
->magic
== IRLAN_MAGIC
, return;);
521 /* Check if already open */
525 irda_notify_init(¬ify
);
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
, ¬ify
);
538 DEBUG(2, __FUNCTION__
"(), Got no tsap!\n");
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
,
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
,
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
);
602 new_value
= irias_new_integer_value(tsap_sel
);
603 irias_object_change_attribute("IrLAN", "IrDA:TinyTP:LsapSel",
607 /* Register PnP object only if not registred before */
608 if (!irias_find_object("PnP")) {
609 obj
= irias_new_object("PnP", IAS_PNP_ID
);
611 irias_add_string_attrib(obj
, "Name", sysctl_devname
);
613 irias_add_string_attrib(obj
, "Name", "Linux");
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");
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
)
637 DEBUG(3, __FUNCTION__
"()\n");
639 if (irda_lock(&self
->client
.tx_busy
) == FALSE
)
642 skb
= skb_dequeue(&self
->client
.txq
);
644 self
->client
.tx_busy
= FALSE
;
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
;
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");
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
)
689 DEBUG(4, __FUNCTION__
"()\n");
691 ASSERT(self
!= NULL
, return;);
692 ASSERT(self
->magic
== IRLAN_MAGIC
, return;);
694 skb
= dev_alloc_skb(64);
698 /* Reserve space for TTP, LMP, and LAP header */
699 skb_reserve(skb
, self
->client
.max_header_size
);
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
)
722 DEBUG(4, __FUNCTION__
"()\n");
724 ASSERT(self
!= NULL
, return;);
725 ASSERT(self
->magic
== IRLAN_MAGIC
, return;);
727 skb
= dev_alloc_skb(64);
731 skb_reserve(skb
, self
->client
.max_header_size
);
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
)
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
)
764 skb
= dev_alloc_skb(64);
768 skb_reserve(skb
, self
->client
.max_header_size
);
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
789 void irlan_open_unicast_addr(struct irlan_cb
*self
)
794 DEBUG(4, __FUNCTION__
"()\n");
796 ASSERT(self
!= NULL
, return;);
797 ASSERT(self
->magic
== IRLAN_MAGIC
, return;);
799 skb
= dev_alloc_skb(128);
803 /* Reserve space for TTP, LMP, and LAP header */
804 skb_reserve(skb
, self
->max_header_size
);
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
)
833 DEBUG(2, __FUNCTION__
"()\n");
835 ASSERT(self
!= NULL
, return;);
836 ASSERT(self
->magic
== IRLAN_MAGIC
, return;);
838 skb
= dev_alloc_skb(128);
842 /* Reserve space for TTP, LMP, and LAP header */
843 skb_reserve(skb
, self
->client
.max_header_size
);
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");
853 irlan_insert_string_param(skb
, "FILTER_MODE", "FILTER");
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
868 void irlan_set_multicast_filter(struct irlan_cb
*self
, int status
)
873 DEBUG(2, __FUNCTION__
"()\n");
875 ASSERT(self
!= NULL
, return;);
876 ASSERT(self
->magic
== IRLAN_MAGIC
, return;);
878 skb
= dev_alloc_skb(128);
882 /* Reserve space for TTP, LMP, and LAP header */
883 skb_reserve(skb
, self
->client
.max_header_size
);
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");
893 irlan_insert_string_param(skb
, "FILTER_MODE", "ALL");
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
)
914 DEBUG(2, __FUNCTION__
"()\n");
916 ASSERT(self
!= NULL
, return;);
917 ASSERT(self
->magic
== IRLAN_MAGIC
, return;);
919 skb
= dev_alloc_skb(128);
923 /* Reserve space for TTP, LMP, and LAP header */
924 skb_reserve(skb
, self
->client
.max_header_size
);
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
)
950 DEBUG(4, __FUNCTION__
"()\n");
952 ASSERT(self
!= NULL
, return;);
953 ASSERT(self
->magic
== IRLAN_MAGIC
, return;);
955 skb
= dev_alloc_skb(64);
959 /* Reserve space for TTP, LMP, and LAP header */
960 skb_reserve(skb
, self
->client
.max_header_size
);
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
,
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
,
1014 return __irlan_insert_param(skb
, name
, IRLAN_ARRAY
, 0, 0, array
,
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
)
1033 __u16 tmp_le
; /* Temporary value in little endian format */
1037 DEBUG(2, __FUNCTION__
"(), Got NULL skb\n");
1041 param_len
= strlen(param
);
1050 ASSERT(value_array
!= NULL
, return 0;);
1051 ASSERT(value_len
> 0, return 0;);
1054 DEBUG(2, __FUNCTION__
"(), Unknown parameter type!\n");
1059 /* Insert at end of sk-buffer */
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");
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 */
1082 frame
[n
++] = value_byte
;
1085 tmp_le
= cpu_to_le16(value_short
);
1086 memcpy(frame
+n
, &tmp_le
, 2); n
+= 2;
1089 memcpy(frame
+n
, value_array
, value_len
); n
+=value_len
;
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
)
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';
1127 * Get length of parameter value (2 bytes in little endian
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
;
1139 /* get parameter value */
1140 memcpy(value
, buf
+n
, val_len
);
1141 value
[val_len
] = '\0';
1144 DEBUG(4, "Parameter: %s ", name
);
1145 DEBUG(4, "Value: %s\n", value
);
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
,
1159 struct irlan_cb
*self
;
1160 unsigned long flags
;
1165 ASSERT(irlan
!= NULL
, return 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",
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, ",
1185 len
+= sprintf(buf
+len
, "daddr: %#08x\n",
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
,
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
);
1214 * Function print_ret_code (code)
1216 * Print return code of request to peer IrLAN layer.
1219 void print_ret_code(__u8 code
)
1223 printk(KERN_INFO
"Success\n");
1226 WARNING("IrLAN: Insufficient resources\n");
1229 WARNING("IrLAN: Invalid command format\n");
1232 WARNING("IrLAN: Command not supported\n");
1235 WARNING("IrLAN: Parameter not supported\n");
1238 WARNING("IrLAN: Value not supported\n");
1241 WARNING("IrLAN: Not open\n");
1244 WARNING("IrLAN: Authentication required\n");
1247 WARNING("IrLAN: Invalid password\n");
1250 WARNING("IrLAN: Protocol error\n");
1253 WARNING("IrLAN: Asynchronous status\n");
1258 void irlan_mod_inc_use_count(void)
1265 void irlan_mod_dec_use_count(void)
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)
1298 void cleanup_module(void)
1300 /* Free some memory */