1 /*********************************************************************
5 * Description: Kernel side of the IrOBEX layer
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Thu Jun 25 21:21:07 1998
9 * Modified at: Sat Jan 16 22:18:03 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
12 * Copyright (c) 1998 Dag Brattli, All Rights Reserved.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
19 * Neither Dag Brattli nor University of Tromsø admit liability nor
20 * provide warranty for any of this software. This material is
21 * provided "AS-IS" and at no charge.
23 ********************************************************************/
25 #include <linux/config.h>
26 #include <linux/module.h>
27 #include <linux/miscdevice.h>
29 #include <linux/proc_fs.h>
30 #include <linux/ioctl.h>
31 #include <linux/init.h>
33 #include <asm/byteorder.h>
34 #include <asm/segment.h>
35 #include <asm/uaccess.h>
36 #include <linux/poll.h>
38 #include <net/irda/irttp.h>
39 #include <net/irda/irias_object.h>
40 #include <net/irda/iriap.h>
42 #include <net/irda/irobex.h>
45 * Master structure, only one instance for now!!
47 struct irobex_cb
*irobex
;
49 char *irobex_state
[] = {
57 static int irobex_dev_open( struct inode
* inode
, struct file
*file
);
58 static int irobex_ioctl( struct inode
*inode
, struct file
*filp
,
59 unsigned int cmd
, unsigned long arg
);
61 static int irobex_dev_close( struct inode
*inode
, struct file
*file
);
62 static ssize_t
irobex_read( struct file
*file
, char *buffer
, size_t count
,
64 static ssize_t
irobex_write( struct file
*file
, const char *buffer
,
65 size_t count
, loff_t
*noidea
);
66 static loff_t
irobex_seek( struct file
*, loff_t
, int);
67 static u_int
irobex_poll( struct file
*file
, poll_table
*wait
);
68 static int irobex_fasync( int, struct file
*, int);
70 static struct file_operations irobex_fops
= {
71 irobex_seek
, /* seek */
75 irobex_poll
, /* poll */
76 irobex_ioctl
, /* ioctl */
86 static int irobex_proc_read( char *buf
, char **start
, off_t offset
,
89 extern struct proc_dir_entry proc_irda
;
91 struct proc_dir_entry proc_irobex
= {
93 S_IFREG
| S_IRUGO
, 1, 0, 0,
100 * Function irobex_init (dev)
102 * Initializes the irobex control structure, and registers as a misc
106 __initfunc(int irobex_init(void))
108 struct irobex_cb
*self
;
110 self
= kmalloc(sizeof(struct irobex_cb
), GFP_ATOMIC
);
114 memset( self
, 0, sizeof(struct irobex_cb
));
115 sprintf( self
->devname
, "irobex%d", 0); /* Just one instance for now */
117 self
->magic
= IROBEX_MAGIC
;
118 self
->rx_flow
= self
->tx_flow
= FLOW_START
;
120 self
->dev
.minor
= MISC_DYNAMIC_MINOR
;
121 self
->dev
.name
= "irobex";
122 self
->dev
.fops
= &irobex_fops
;
124 skb_queue_head_init( &self
->rx_queue
);
125 init_timer( &self
->watchdog_timer
);
129 misc_register( &self
->dev
);
131 #ifdef CONFIG_PROC_FS
132 proc_register( &proc_irda
, &proc_irobex
);
133 #endif /* CONFIG_PROC_FS */
135 irlmp_register_layer( S_OBEX
, CLIENT
| SERVER
, TRUE
,
136 irobex_discovery_indication
);
142 * Function irobex_cleanup (void)
144 * Removes the IrOBEX layer
148 void irobex_cleanup(void)
151 struct irobex_cb
*self
;
153 DEBUG( 4, __FUNCTION__
"()\n");
157 ASSERT( self
!= NULL
, return;);
158 ASSERT( self
->magic
== IROBEX_MAGIC
, return;);
161 * Deregister client and server
163 irlmp_unregister_layer( S_OBEX
, CLIENT
| SERVER
);
166 irttp_close_tsap( self
->tsap
);
171 del_timer( &self
->watchdog_timer
);
176 while (( skb
= skb_dequeue( &self
->rx_queue
)) != NULL
)
179 #ifdef CONFIG_PROC_FS
180 proc_unregister( &proc_irda
, proc_irobex
.low_ino
);
183 misc_deregister( &self
->dev
);
190 * Function irobex_read (inode, file, buffer, count)
192 * User process wants to read some data
195 static ssize_t
irobex_read( struct file
*file
, char *buffer
, size_t count
,
199 struct irobex_cb
*self
;
200 struct sk_buff
*skb
= NULL
;
205 ASSERT( self
!= NULL
, return -EIO
;);
206 ASSERT( self
->magic
== IROBEX_MAGIC
, return -EIO
;);
208 DEBUG( 4, __FUNCTION__
": count=%d, skb_len=%d, state=%s, eof=%d\n",
209 count
, skb_queue_len( &self
->rx_queue
),
210 irobex_state
[self
->state
],
213 if ( self
->state
!= OBEX_DATA
) {
214 DEBUG( 0, __FUNCTION__
"(), link not connected yet!\n");
219 * If there is data to return, then we return it. If not, then we
220 * must check if we are still connected
222 if ( skb_queue_len( &self
->rx_queue
) == 0) {
224 /* Still connected? */
225 if ( self
->state
!= OBEX_DATA
) {
226 switch ( self
->eof
) {
227 case LM_USER_REQUEST
:
229 DEBUG(3, "read_irobex: returning 0\n");
232 case LM_LAP_DISCONNECT
:
248 /* Return if user does not want to block */
249 if ( file
->f_flags
& O_NONBLOCK
)
252 /* Go to sleep and wait for data! */
253 interruptible_sleep_on( &self
->read_wait
);
256 * Ensure proper reaction to signals, and screen out
257 * blocked signals (page 112. linux device drivers)
259 if ( signal_pending( current
))
263 while ( count
&& skb_queue_len( &self
->rx_queue
)) {
265 skb
= skb_dequeue( &self
->rx_queue
);
268 * Check if we have previously stopped IrTTP and we know
269 * have more free space in our rx_queue. If so tell IrTTP
270 * to start delivering frames again before our rx_queue gets
273 if ( self
->rx_flow
== FLOW_STOP
) {
274 if ( skb_queue_len( &self
->rx_queue
) < LOW_THRESHOLD
) {
275 DEBUG( 4, __FUNCTION__
"(), Starting IrTTP\n");
276 self
->rx_flow
= FLOW_START
;
277 irttp_flow_request( self
->tsap
, FLOW_START
);
282 * Is the request from the user less that the amount in the
285 if ( count
< skb
->len
) {
286 copy_to_user( buffer
+len
, skb
->data
, count
);
290 * Remove copied data from skb and queue
293 skb_pull( skb
, count
);
294 skb_queue_head( &self
->rx_queue
, skb
);
298 copy_to_user( buffer
+len
, skb
->data
, skb
->len
);
309 * Function irobex_write (inode, file, buffer, count)
311 * User process wants to write to device
314 static ssize_t
irobex_write( struct file
*file
, const char *buffer
,
315 size_t count
, loff_t
*noidea
)
317 struct irobex_cb
*self
;
324 ASSERT( self
!= NULL
, return -EIO
;);
325 ASSERT( self
->magic
== IROBEX_MAGIC
, return -EIO
;);
327 DEBUG( 4, __FUNCTION__
": count = %d\n", count
);
330 * If we are not connected then we just give up!
332 if ( self
->state
!= OBEX_DATA
) {
333 DEBUG( 0, __FUNCTION__
"(): Not connected!\n");
338 /* Check if IrTTP is wants us to slow down */
339 if ( self
->tx_flow
== FLOW_STOP
) {
340 DEBUG( 4, __FUNCTION__
341 "(), IrTTP wants us to slow down, going to sleep\n");
342 interruptible_sleep_on( &self
->write_wait
);
345 /* Send data to TTP layer possibly as muliple packets */
349 * Check if request is larger than what fits inside a TTP
350 * frame. In that case we must fragment the frame into
351 * multiple TTP frames. IrOBEX should not care about message
354 if ( count
< (self
->irlap_data_size
- IROBEX_MAX_HEADER
))
357 data_len
= self
->irlap_data_size
- IROBEX_MAX_HEADER
;
359 DEBUG( 4, __FUNCTION__
"(), data_len=%d, header_len = %d\n",
360 data_len
, IROBEX_MAX_HEADER
);
362 skb
= dev_alloc_skb( data_len
+ IROBEX_MAX_HEADER
);
364 DEBUG( 0, "irobex - couldn't allocate skbuff!\n");
368 skb_reserve( skb
, IROBEX_MAX_HEADER
);
369 skb_put( skb
, data_len
);
371 copy_from_user( skb
->data
, buffer
+len
, data_len
);
375 DEBUG( 4, __FUNCTION__
"(), skb->len=%d\n", (int) skb
->len
);
376 ASSERT( skb
->len
<= (self
->irlap_data_size
-IROBEX_MAX_HEADER
),
379 irttp_data_request( self
->tsap
, skb
);
385 * Function irobex_poll (file, wait)
390 static u_int
irobex_poll(struct file
*file
, poll_table
*wait
)
392 DEBUG( 0, __FUNCTION__
"(), Sorry not implemented yet!\n");
394 /* check out /usr/src/pcmcia/modules/ds.c for an example */
399 * Function irobex_fasync (inode, filp, mode)
401 * Implementation for SIGIO
404 static int irobex_fasync( int fd
, struct file
*filp
, int on
)
406 struct irobex_cb
*self
;
408 DEBUG( 4, __FUNCTION__
"()\n");
412 ASSERT( self
!= NULL
, return -1;);
413 ASSERT( self
->magic
== IROBEX_MAGIC
, return -1;);
415 return fasync_helper( fd
, filp
, on
, &self
->async
);
419 * Function irobex_seek (inode, file, buffer, count)
421 * Not implemented yet!
424 static loff_t
irobex_seek( struct file
*file
, loff_t off
, int whence
)
426 DEBUG( 0, __FUNCTION__
"(), Not implemented yet!\n");
432 * Function irobex_ioctl (inode, filp, cmd, arg)
434 * Drivers IOCTL handler, used for connecting and disconnecting
438 static int irobex_ioctl( struct inode
*inode
, struct file
*filp
,
439 unsigned int cmd
, unsigned long arg
)
441 struct irobex_cb
*self
;
443 int size
= _IOC_SIZE(cmd
);
445 DEBUG( 4, __FUNCTION__
"()\n");
449 ASSERT( self
!= NULL
, return -ENOTTY
;);
450 ASSERT( self
->magic
= IROBEX_MAGIC
, return -ENOTTY
;);
452 if ( _IOC_TYPE(cmd
) != IROBEX_IOC_MAGIC
)
454 if ( _IOC_NR(cmd
) > IROBEX_IOC_MAXNR
)
457 if ( _IOC_DIR(cmd
) & _IOC_READ
)
458 err
= verify_area( VERIFY_WRITE
, (void *) arg
, size
);
459 else if ( _IOC_DIR(cmd
) & _IOC_WRITE
)
460 err
= verify_area( VERIFY_READ
, (void *) arg
, size
);
465 case IROBEX_IOCSCONNECT
:
466 DEBUG( 4, __FUNCTION__
"(): IROBEX_IOCSCONNECT!\n");
468 /* Already connected? */
469 if ( self
->state
== OBEX_DATA
) {
470 DEBUG( 0, __FUNCTION__
"(), already connected!\n");
474 /* Timeout after 15 secs. */
475 irobex_start_watchdog_timer( self
, 1000);
478 * If we have discovered a remote device we
479 * check if the discovery is still fresh. If not, we don't
482 if ( self
->daddr
&& ((jiffies
- self
->time_discovered
) > 500))
486 * Try to discover remote remote device if it has not been
490 self
->state
= OBEX_DISCOVER
;
492 irlmp_discovery_request( 8);
494 /* Wait for discovery to complete */
495 interruptible_sleep_on( &self
->write_wait
);
496 del_timer( &self
->watchdog_timer
);
499 /* Give up if we are unable to discover any remote devices */
501 DEBUG( 0, __FUNCTION__
502 "(), Unable to discover any devices!\n");
506 /* Need to find remote destination TSAP selector? */
507 if ( !self
->dtsap_sel
) {
508 DEBUG( 0, __FUNCTION__
"() : Quering remote IAS!\n");
510 self
->state
= OBEX_QUERY
;
512 /* Timeout after 5 secs. */
513 irobex_start_watchdog_timer( self
, 500);
514 iriap_getvaluebyclass_request(
517 "IrDA:TinyTP:LsapSel",
518 irobex_get_value_confirm
,
521 interruptible_sleep_on( &self
->write_wait
);
522 del_timer( &self
->watchdog_timer
);
525 if ( !self
->dtsap_sel
) {
526 DEBUG( 0, __FUNCTION__
527 "(), Unable to query remote LM-IAS!\n");
531 self
->state
= OBEX_CONN
;
533 /* Timeout after 5 secs. */
534 irobex_start_watchdog_timer( self
, 500);
536 irttp_connect_request( self
->tsap
, self
->dtsap_sel
,
537 self
->daddr
, NULL
, SAR_DISABLE
,
540 /* Go to sleep and wait for connection! */
541 interruptible_sleep_on( &self
->write_wait
);
542 del_timer( &self
->watchdog_timer
);
544 if ( self
->state
!= OBEX_DATA
) {
545 DEBUG( 0, __FUNCTION__
546 "(), Unable to connect to remote device!\n");
551 case IROBEX_IOCSDISCONNECT
:
552 DEBUG( 4, __FUNCTION__
"(): IROBEX_IOCSDISCONNECT!\n");
554 if ( self
->state
!= OBEX_DATA
)
557 irttp_disconnect_request( self
->tsap
, NULL
, P_NORMAL
);
559 /* Reset values for this instance */
560 self
->state
= OBEX_IDLE
;
561 self
->eof
= LM_USER_REQUEST
;
564 self
->rx_flow
= FLOW_START
;
565 self
->tx_flow
= FLOW_START
;
567 wake_up_interruptible( &self
->read_wait
);
576 * Function irobex_dev_open (inode, file)
578 * Device opened by user process
581 static int irobex_dev_open( struct inode
* inode
, struct file
*file
)
583 struct irobex_cb
*self
;
585 DEBUG( 4, __FUNCTION__
"()\n");
589 ASSERT( self
!= NULL
, return -1;);
590 ASSERT( self
->magic
== IROBEX_MAGIC
, return -1;);
592 if ( self
->count
++) {
593 DEBUG( 3, "open_irobex: count not zero; actual = %d\n",
599 irobex_register_server( self
);
601 /* Reset values for this instance */
602 self
->state
= OBEX_IDLE
;
606 self
->rx_flow
= FLOW_START
;
607 self
->tx_flow
= FLOW_START
;
614 static int irobex_dev_close( struct inode
*inode
, struct file
*file
)
616 struct irobex_cb
*self
;
619 DEBUG( 4, __FUNCTION__
"()\n");
623 ASSERT( self
!= NULL
, return -ENODEV
;);
624 ASSERT( self
->magic
== IROBEX_MAGIC
, return -EBADR
;);
626 /* Deallocate buffers */
627 while (( skb
= skb_dequeue( &self
->rx_queue
)) != NULL
) {
628 DEBUG( 3, "irobex_close: freeing SKB\n");
632 /* Close TSAP is its still there */
634 irttp_close_tsap( self
->tsap
);
637 self
->state
= OBEX_IDLE
;
641 self
->rx_flow
= FLOW_START
;
642 self
->tx_flow
= FLOW_START
;
644 /* Remove this filp from the asynchronously notified filp's */
645 irobex_fasync( -1, file
, 0);
655 * Function irobex_discovery_inication (daddr)
657 * Remote device discovered, try query the remote IAS to see which
658 * device it is, and which services it has.
661 void irobex_discovery_indication( DISCOVERY
*discovery
)
663 struct irobex_cb
*self
;
665 DEBUG( 4, __FUNCTION__
"()\n");
669 ASSERT( self
!= NULL
, return;);
670 ASSERT( self
->magic
== IROBEX_MAGIC
, return;);
672 /* Remember address and time if was discovered */
673 self
->daddr
= discovery
->daddr
;
674 self
->time_discovered
= jiffies
;
676 /* Wake up process if its waiting for device to be discovered */
677 if ( self
->state
== OBEX_DISCOVER
)
678 wake_up_interruptible( &self
->write_wait
);
682 * Function irobex_disconnect_indication (handle, reason, priv)
684 * Link has been disconnected
687 void irobex_disconnect_indication( void *instance
, void *sap
,
688 LM_REASON reason
, struct sk_buff
*userdata
)
690 struct irobex_cb
*self
;
692 DEBUG( 4, __FUNCTION__
"(), reason=%d\n", reason
);
694 self
= ( struct irobex_cb
*) instance
;
696 ASSERT( self
!= NULL
, return;);
697 ASSERT( self
->magic
== IROBEX_MAGIC
, return;);
699 self
->state
= OBEX_IDLE
;
703 self
->rx_flow
= self
->tx_flow
= FLOW_START
;
705 wake_up_interruptible( &self
->read_wait
);
706 wake_up_interruptible( &self
->write_wait
);
708 DEBUG( 4, __FUNCTION__
"(), skb_queue_len=%d\n",
709 skb_queue_len( &irobex
->rx_queue
));
712 dev_kfree_skb( userdata
);
716 * Function irobex_connect_confirm (instance, sap, qos, userdata)
718 * Connection to peer IrOBEX layer established
721 void irobex_connect_confirm( void *instance
, void *sap
, struct qos_info
*qos
,
722 int max_sdu_size
, struct sk_buff
*userdata
)
724 struct irobex_cb
*self
;
726 DEBUG( 4, __FUNCTION__
"()\n");
728 self
= ( struct irobex_cb
*) instance
;
730 ASSERT( self
!= NULL
, return;);
731 ASSERT( self
->magic
== IROBEX_MAGIC
, return;);
732 ASSERT( qos
!= NULL
, return;);
734 DEBUG( 4, __FUNCTION__
"(), IrLAP data size=%d\n",
735 qos
->data_size
.value
);
737 self
->irlap_data_size
= qos
->data_size
.value
;
740 * Wake up any blocked process wanting to write. Finally this process
741 * can start writing since the connection is now open :-)
743 if (self
->state
== OBEX_CONN
) {
744 self
->state
= OBEX_DATA
;
745 wake_up_interruptible( &self
->write_wait
);
749 dev_kfree_skb( userdata
);
755 * Function irobex_connect_response (handle)
757 * Accept incomming connection
760 void irobex_connect_response( struct irobex_cb
*self
)
765 DEBUG( 4, __FUNCTION__
"()\n");
767 ASSERT( self
!= NULL
, return;);
768 ASSERT( self
->magic
== IROBEX_MAGIC
, return;);
770 self
->state
= OBEX_DATA
;
772 skb
= dev_alloc_skb( 64);
774 DEBUG( 0, __FUNCTION__
"() Could not allocate sk_buff!\n");
778 /* Reserve space for MUX_CONTROL and LAP header */
779 skb_reserve( skb
, TTP_HEADER
+LMP_CONTROL_HEADER
+LAP_HEADER
);
781 irttp_connect_response( self
->tsap
, SAR_DISABLE
, skb
);
785 * Function irobex_connect_indication (handle, skb, priv)
787 * Connection request from a remote device
790 void irobex_connect_indication( void *instance
, void *sap
,
791 struct qos_info
*qos
, int max_sdu_size
,
792 struct sk_buff
*userdata
)
794 struct irmanager_event mgr_event
;
795 struct irobex_cb
*self
;
797 DEBUG( 4, __FUNCTION__
"()\n");
799 self
= ( struct irobex_cb
*) instance
;
801 ASSERT( self
!= NULL
, return;);
802 ASSERT( self
->magic
== IROBEX_MAGIC
, return;);
803 ASSERT( userdata
!= NULL
, return;);
807 DEBUG( 4, __FUNCTION__
"(), skb_len = %d\n",
808 (int) userdata
->len
);
810 DEBUG( 4, __FUNCTION__
"(), IrLAP data size=%d\n",
811 qos
->data_size
.value
);
813 ASSERT( qos
->data_size
.value
>= 64, return;);
815 self
->irlap_data_size
= qos
->data_size
.value
;
817 /* We just accept the connection */
818 irobex_connect_response( self
);
820 mgr_event
.event
= EVENT_IROBEX_START
;
821 sprintf( mgr_event
.devname
, "%s", self
->devname
);
822 irmanager_notify( &mgr_event
);
824 wake_up_interruptible( &self
->read_wait
);
827 dev_kfree_skb( userdata
);
832 * Function irobex_data_indication (instance, sap, skb)
834 * This function gets the data that is received on the data channel
837 void irobex_data_indication( void *instance
, void *sap
, struct sk_buff
*skb
)
840 struct irobex_cb
*self
;
842 self
= ( struct irobex_cb
*) instance
;
844 ASSERT( self
!= NULL
, return;);
845 ASSERT( self
->magic
== IROBEX_MAGIC
, return;);
846 ASSERT( skb
!= NULL
, return;);
848 DEBUG( 4, __FUNCTION__
"(), len=%d\n", (int) skb
->len
);
850 skb_queue_tail( &self
->rx_queue
, skb
);
853 * Check if queues are beginning to get filled, and inform
854 * IrTTP to slow down if that is the case
856 if ( skb_queue_len( &self
->rx_queue
) > HIGH_THRESHOLD
) {
857 DEBUG( 0, __FUNCTION__
858 "(), rx_queue is full, telling IrTTP to slow down\n");
859 self
->rx_flow
= FLOW_STOP
;
860 irttp_flow_request( self
->tsap
, FLOW_STOP
);
864 * Wake up process blocked on read or select
866 wake_up_interruptible( &self
->read_wait
);
868 /* Send signal to asynchronous readers */
870 kill_fasync( self
->async
, SIGIO
);
874 * Function irobex_flow_indication (instance, sap, cmd)
879 void irobex_flow_indication( void *instance
, void *sap
, LOCAL_FLOW flow
)
881 struct irobex_cb
*self
;
883 DEBUG( 4, __FUNCTION__
"()\n");
885 self
= ( struct irobex_cb
*) instance
;
887 ASSERT( self
!= NULL
, return;);
888 ASSERT( self
->magic
== IROBEX_MAGIC
, return;);
892 DEBUG( 0, __FUNCTION__
"(), IrTTP wants us to slow down\n");
893 self
->tx_flow
= flow
;
896 self
->tx_flow
= flow
;
897 DEBUG( 0, __FUNCTION__
"(), IrTTP wants us to start again\n");
898 wake_up_interruptible( &self
->write_wait
);
901 DEBUG( 0, __FUNCTION__
"(), Unknown flow command!\n");
906 * Function irobex_get_value_confirm (obj_id, value)
908 * Got results from previous GetValueByClass request
911 void irobex_get_value_confirm( __u16 obj_id
, struct ias_value
*value
,
914 struct irobex_cb
*self
;
916 DEBUG( 4, __FUNCTION__
"()\n");
918 ASSERT( priv
!= NULL
, return;);
919 self
= ( struct irobex_cb
*) priv
;
921 if ( !self
|| self
->magic
!= IROBEX_MAGIC
) {
922 DEBUG( 0, "irobex_get_value_confirm: bad magic!\n");
926 switch ( value
->type
) {
928 DEBUG( 4, __FUNCTION__
"() int=%d\n", value
->t
.integer
);
930 if ( value
->t
.integer
!= -1) {
931 self
->dtsap_sel
= value
->t
.integer
;
934 * Got the remote TSAP, so wake up any processes
935 * blocking on write. We don't do the connect
936 * ourselves since we must make sure there is a
937 * process that wants to make a connection, so we
938 * just let that process do the connect itself
940 if ( self
->state
== OBEX_QUERY
)
941 wake_up_interruptible( &self
->write_wait
);
946 DEBUG( 0, __FUNCTION__
"(), got string %s\n", value
->t
.string
);
949 DEBUG( 0, __FUNCTION__
"(), OCT_SEQ not implemented\n");
952 DEBUG( 0, __FUNCTION__
"(), MISSING not implemented\n");
955 DEBUG( 0, __FUNCTION__
"(), unknown type!\n");
961 * Function irobex_provider_confirm (dlsap)
963 * IrOBEX provider is discovered. We can now establish connections
964 * TODO: This function is currently not used!
966 void irobex_provider_confirm( struct irobex_cb
*self
, __u8 dlsap
)
968 /* struct irobex_cb *self = irobex; */
969 struct notify_t notify
;
971 DEBUG( 4, __FUNCTION__
"()\n");
973 ASSERT( self
!= NULL
, return;);
974 ASSERT( self
->magic
== IROBEX_MAGIC
, return;);
976 notify
.data_indication
= irobex_data_indication
;
977 notify
.connect_confirm
= irobex_connect_confirm
;
978 notify
.connect_indication
= irobex_connect_indication
;
979 notify
.flow_indication
= irobex_flow_indication
;
980 notify
.disconnect_indication
= irobex_disconnect_indication
;
981 notify
.instance
= self
;
984 self
->tsap
= irttp_open_tsap( LSAP_ANY
, DEFAULT_INITIAL_CREDIT
,
987 /* DEBUG( 0, "OBEX allocated TSAP%d for data\n", self->handle); */
989 /* irlan_do_event( IAS_PROVIDER_AVAIL, NULL, &frame); */
993 * Function irobex_register_server(void)
995 * Register server support so we can accept incomming connections. We
996 * must register both a TSAP for control and data
999 void irobex_register_server( struct irobex_cb
*self
)
1001 struct notify_t notify
;
1002 struct ias_object
*obj
;
1004 DEBUG( 4, __FUNCTION__
"()\n");
1006 ASSERT( self
!= NULL
, return;);
1007 ASSERT( self
->magic
== IROBEX_MAGIC
, return;);
1009 irda_notify_init( ¬ify
);
1011 notify
.connect_confirm
= irobex_connect_confirm
;
1012 notify
.connect_indication
= irobex_connect_indication
;
1013 notify
.disconnect_indication
= irobex_disconnect_indication
;
1014 notify
.data_indication
= irobex_data_indication
;
1015 notify
.flow_indication
= irobex_flow_indication
;
1016 notify
.instance
= self
;
1017 strcpy( notify
.name
, "IrOBEX");
1019 self
->tsap
= irttp_open_tsap( TSAP_IROBEX
, DEFAULT_INITIAL_CREDIT
,
1021 if ( self
->tsap
== NULL
) {
1022 DEBUG( 0, __FUNCTION__
"(), Unable to allocate TSAP!\n");
1027 * Register with LM-IAS
1029 obj
= irias_new_object( "OBEX", 0x42343);
1030 irias_add_integer_attrib( obj
, "IrDA:TinyTP:LsapSel", TSAP_IROBEX
);
1031 irias_insert_object( obj
);
1034 void irobex_watchdog_timer_expired( unsigned long data
)
1036 struct irobex_cb
*self
= ( struct irobex_cb
*) data
;
1038 DEBUG( 4, __FUNCTION__
"()\n");
1040 ASSERT( self
!= NULL
, return;);
1041 ASSERT( self
->magic
== IROBEX_MAGIC
, return;);
1043 switch (self
->state
) {
1044 case OBEX_CONN
: /* FALLTROUGH */
1045 case OBEX_DISCOVER
: /* FALLTROUGH */
1046 case OBEX_QUERY
: /* FALLTROUGH */
1047 wake_up_interruptible( &self
->write_wait
);
1054 #ifdef CONFIG_PROC_FS
1056 * Function irobex_proc_read (buf, start, offset, len, unused)
1058 * Give some info to the /proc file system
1060 static int irobex_proc_read( char *buf
, char **start
, off_t offset
,
1061 int len
, int unused
)
1063 struct irobex_cb
*self
;
1067 ASSERT( self
!= NULL
, return -1;);
1068 ASSERT( self
->magic
== IROBEX_MAGIC
, return -1;);
1072 len
+= sprintf( buf
+len
, "ifname: %s ",self
->devname
);
1073 len
+= sprintf( buf
+len
, "state: %s ", irobex_state
[ self
->state
]);
1074 len
+= sprintf( buf
+len
, "EOF: %s\n", self
->eof
? "TRUE": "FALSE");
1079 #endif /* CONFIG_PROC_FS */
1083 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
1084 MODULE_DESCRIPTION("The Linux IrOBEX module");
1087 * Function init_module (void)
1089 * Initialize the IrOBEX module, this function is called by the
1090 * modprobe(1) program.
1092 int init_module(void)
1100 * Function cleanup_module (void)
1102 * Remove the IrOBEX module, this function is called by the rmmod(1)
1105 void cleanup_module(void)
1108 * No need to check MOD_IN_USE, as sys_delete_module() checks.
1111 /* Free some memory */