2.2.0-final
[davej-history.git] / net / irda / irobex / irobex.c
blob8b289182d2b51514dcb3d831dc821cd529c0d5a2
1 /*********************************************************************
2 *
3 * Filename: irobex.c
4 * Version: 0.3
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>
28 #include <linux/fs.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[] = {
50 "OBEX_IDLE",
51 "OBEX_DISCOVER",
52 "OBEX_QUERY",
53 "OBEX_CONN",
54 "OBEX_DATA",
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,
63 loff_t *noidea);
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 */
72 irobex_read,
73 irobex_write,
74 NULL, /* readdir */
75 irobex_poll, /* poll */
76 irobex_ioctl, /* ioctl */
77 NULL, /* mmap */
78 irobex_dev_open,
79 NULL,
80 irobex_dev_close,
81 NULL,
82 irobex_fasync,
85 #ifdef CONFIG_PROC_FS
86 static int irobex_proc_read( char *buf, char **start, off_t offset,
87 int len, int unused);
89 extern struct proc_dir_entry proc_irda;
91 struct proc_dir_entry proc_irobex = {
92 0, 6, "irobex",
93 S_IFREG | S_IRUGO, 1, 0, 0,
94 0, NULL,
95 &irobex_proc_read,
97 #endif
100 * Function irobex_init (dev)
102 * Initializes the irobex control structure, and registers as a misc
103 * device
106 __initfunc(int irobex_init(void))
108 struct irobex_cb *self;
110 self = kmalloc(sizeof(struct irobex_cb), GFP_ATOMIC);
111 if ( self == NULL)
112 return -ENOMEM;
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);
127 irobex = self;
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);
138 return 0;
142 * Function irobex_cleanup (void)
144 * Removes the IrOBEX layer
147 #ifdef MODULE
148 void irobex_cleanup(void)
150 struct sk_buff *skb;
151 struct irobex_cb *self;
153 DEBUG( 4, __FUNCTION__ "()\n");
155 self = irobex;
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);
165 if ( self->tsap) {
166 irttp_close_tsap( self->tsap);
167 self->tsap = NULL;
170 /* Stop timers */
171 del_timer( &self->watchdog_timer);
174 * Deallocate buffers
176 while (( skb = skb_dequeue( &self->rx_queue)) != NULL)
177 dev_kfree_skb( skb);
179 #ifdef CONFIG_PROC_FS
180 proc_unregister( &proc_irda, proc_irobex.low_ino);
181 #endif
183 misc_deregister( &self->dev);
185 kfree( self);
187 #endif /* MODULE */
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,
196 loff_t *noidea)
198 int len=0;
199 struct irobex_cb *self;
200 struct sk_buff *skb = NULL;
201 int ret;
203 self = irobex;
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],
211 self->eof);
213 if ( self->state != OBEX_DATA) {
214 DEBUG( 0, __FUNCTION__ "(), link not connected yet!\n");
215 return -EIO;
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:
228 self->eof = FALSE;
229 DEBUG(3, "read_irobex: returning 0\n");
230 ret = 0;
231 break;
232 case LM_LAP_DISCONNECT:
233 self->eof = FALSE;
234 ret = -EIO;
235 break;
236 case LM_LAP_RESET:
237 self->eof = FALSE;
238 ret = -ECONNRESET;
239 break;
240 default:
241 self->eof = FALSE;
242 ret = -EIO;
243 break;
245 return ret;
248 /* Return if user does not want to block */
249 if ( file->f_flags & O_NONBLOCK)
250 return -EAGAIN;
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))
260 return -ERESTARTSYS;
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
271 * empty
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
283 * current packet?
285 if ( count < skb->len) {
286 copy_to_user( buffer+len, skb->data, count);
287 len += count;
290 * Remove copied data from skb and queue
291 * it for next read
293 skb_pull( skb, count);
294 skb_queue_head( &self->rx_queue, skb);
296 return len;
297 } else {
298 copy_to_user( buffer+len, skb->data, skb->len);
299 count -= skb->len;
300 len += skb->len;
302 dev_kfree_skb( skb);
305 return 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;
318 struct sk_buff *skb;
319 int data_len = 0;
320 int len = 0;
322 self = irobex;
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");
335 return -ENOLINK;
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 */
346 while ( count) {
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
352 * boundaries.
354 if ( count < (self->irlap_data_size - IROBEX_MAX_HEADER))
355 data_len = count;
356 else
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);
363 if ( skb == NULL) {
364 DEBUG( 0, "irobex - couldn't allocate skbuff!\n");
365 return 0;
368 skb_reserve( skb, IROBEX_MAX_HEADER);
369 skb_put( skb, data_len);
371 copy_from_user( skb->data, buffer+len, data_len);
372 len += data_len;
373 count -= data_len;
375 DEBUG( 4, __FUNCTION__ "(), skb->len=%d\n", (int) skb->len);
376 ASSERT( skb->len <= (self->irlap_data_size-IROBEX_MAX_HEADER),
377 return len;);
379 irttp_data_request( self->tsap, skb);
381 return (len);
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 */
395 return 0;
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");
410 self = irobex;
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");
428 return -ESPIPE;
432 * Function irobex_ioctl (inode, filp, cmd, arg)
434 * Drivers IOCTL handler, used for connecting and disconnecting
435 * irobex connections
438 static int irobex_ioctl( struct inode *inode, struct file *filp,
439 unsigned int cmd, unsigned long arg)
441 struct irobex_cb *self;
442 int err = 0;
443 int size = _IOC_SIZE(cmd);
445 DEBUG( 4, __FUNCTION__ "()\n");
447 self = irobex;
449 ASSERT( self != NULL, return -ENOTTY;);
450 ASSERT( self->magic = IROBEX_MAGIC, return -ENOTTY;);
452 if ( _IOC_TYPE(cmd) != IROBEX_IOC_MAGIC)
453 return -EINVAL;
454 if ( _IOC_NR(cmd) > IROBEX_IOC_MAXNR)
455 return -EINVAL;
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);
461 if ( err)
462 return err;
464 switch ( cmd) {
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");
471 return 0;
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
480 * trust the address.
482 if ( self->daddr && ((jiffies - self->time_discovered) > 500))
483 self->daddr = 0;
486 * Try to discover remote remote device if it has not been
487 * discovered yet.
489 if ( !self->daddr) {
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 */
500 if ( !self->daddr) {
501 DEBUG( 0, __FUNCTION__
502 "(), Unable to discover any devices!\n");
503 return -ENOTTY;
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(
515 self->daddr,
516 "OBEX",
517 "IrDA:TinyTP:LsapSel",
518 irobex_get_value_confirm,
519 self);
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");
528 return -ENOTTY;
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,
538 NULL);
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");
547 return -ENOTTY;
550 break;
551 case IROBEX_IOCSDISCONNECT:
552 DEBUG( 4, __FUNCTION__ "(): IROBEX_IOCSDISCONNECT!\n");
554 if ( self->state != OBEX_DATA)
555 return 0;
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;
562 self->daddr = 0;
563 self->dtsap_sel = 0;
564 self->rx_flow = FLOW_START;
565 self->tx_flow = FLOW_START;
567 wake_up_interruptible( &self->read_wait);
568 break;
569 default:
570 return -EINVAL;
572 return 0;
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");
587 self = irobex;
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",
594 self->count);
595 self->count--;
596 return -EBUSY;
599 irobex_register_server( self);
601 /* Reset values for this instance */
602 self->state = OBEX_IDLE;
603 self->eof = FALSE;
604 self->daddr = 0;
605 self->dtsap_sel = 0;
606 self->rx_flow = FLOW_START;
607 self->tx_flow = FLOW_START;
609 MOD_INC_USE_COUNT;
611 return 0;
614 static int irobex_dev_close( struct inode *inode, struct file *file)
616 struct irobex_cb *self;
617 struct sk_buff *skb;
619 DEBUG( 4, __FUNCTION__ "()\n");
621 self = irobex;
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");
629 dev_kfree_skb( skb);
632 /* Close TSAP is its still there */
633 if ( self->tsap) {
634 irttp_close_tsap( self->tsap);
635 self->tsap = NULL;
637 self->state = OBEX_IDLE;
638 self->eof = FALSE;
639 self->daddr = 0;
640 self->dtsap_sel = 0;
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);
647 self->count--;
649 MOD_DEC_USE_COUNT;
651 return 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");
667 self = irobex;
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;
700 self->eof = reason;
701 self->daddr = 0;
702 self->dtsap_sel = 0;
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));
711 if ( userdata)
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);
748 if ( userdata) {
749 dev_kfree_skb( userdata);
755 * Function irobex_connect_response (handle)
757 * Accept incomming connection
760 void irobex_connect_response( struct irobex_cb *self)
762 struct sk_buff *skb;
763 /* __u8 *frame; */
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);
773 if (skb == NULL) {
774 DEBUG( 0, __FUNCTION__ "() Could not allocate sk_buff!\n");
775 return;
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;);
805 self->eof = FALSE;
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);
819 #if 1
820 mgr_event.event = EVENT_IROBEX_START;
821 sprintf( mgr_event.devname, "%s", self->devname);
822 irmanager_notify( &mgr_event);
823 #endif
824 wake_up_interruptible( &self->read_wait);
826 if ( userdata) {
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 */
869 if ( self->async)
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;);
890 switch ( flow) {
891 case FLOW_STOP:
892 DEBUG( 0, __FUNCTION__ "(), IrTTP wants us to slow down\n");
893 self->tx_flow = flow;
894 break;
895 case FLOW_START:
896 self->tx_flow = flow;
897 DEBUG( 0, __FUNCTION__ "(), IrTTP wants us to start again\n");
898 wake_up_interruptible( &self->write_wait);
899 break;
900 default:
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,
912 void *priv)
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");
923 return;
926 switch ( value->type) {
927 case IAS_INTEGER:
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);
942 } else
943 self->dtsap_sel = 0;
944 break;
945 case IAS_STRING:
946 DEBUG( 0, __FUNCTION__ "(), got string %s\n", value->t.string);
947 break;
948 case IAS_OCT_SEQ:
949 DEBUG( 0, __FUNCTION__ "(), OCT_SEQ not implemented\n");
950 break;
951 case IAS_MISSING:
952 DEBUG( 0, __FUNCTION__ "(), MISSING not implemented\n");
953 break;
954 default:
955 DEBUG( 0, __FUNCTION__ "(), unknown type!\n");
956 break;
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;
983 /* Create TSAP's */
984 self->tsap = irttp_open_tsap( LSAP_ANY, DEFAULT_INITIAL_CREDIT,
985 &notify);
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( &notify);
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,
1020 &notify);
1021 if ( self->tsap == NULL) {
1022 DEBUG( 0, __FUNCTION__ "(), Unable to allocate TSAP!\n");
1023 return;
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);
1048 break;
1049 default:
1050 break;
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;
1065 self = irobex;
1067 ASSERT( self != NULL, return -1;);
1068 ASSERT( self->magic == IROBEX_MAGIC, return -1;);
1070 len = 0;
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");
1076 return len;
1079 #endif /* CONFIG_PROC_FS */
1081 #ifdef MODULE
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)
1094 irobex_init();
1096 return 0;
1100 * Function cleanup_module (void)
1102 * Remove the IrOBEX module, this function is called by the rmmod(1)
1103 * program
1105 void cleanup_module(void)
1108 * No need to check MOD_IN_USE, as sys_delete_module() checks.
1111 /* Free some memory */
1112 irobex_cleanup();
1115 #endif /* MODULE */