2.2.0-final
[davej-history.git] / net / irda / irttp.c
blob3da804e7deb25567fde665e1231015e9eb9b6773
1 /*********************************************************************
2 *
3 * Filename: irttp.c
4 * Version: 0.4
5 * Description: Tiny Transport Protocol (TTP) implementation
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Aug 31 20:14:31 1997
9 * Modified at: Tue Jan 19 23:56:58 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
12 * Copyright (c) 1998 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/skbuff.h>
28 #include <linux/init.h>
30 #include <asm/byteorder.h>
32 #include <net/irda/irda.h>
33 #include <net/irda/irlmp.h>
34 #include <net/irda/irttp.h>
36 struct irttp_cb *irttp = NULL;
38 static void __irttp_close_tsap( struct tsap_cb *self);
40 static void irttp_data_indication( void *instance, void *sap,
41 struct sk_buff *skb);
42 static void irttp_udata_indication( void *instance, void *sap,
43 struct sk_buff *skb);
44 static void irttp_disconnect_indication( void *instance, void *sap,
45 LM_REASON reason,
46 struct sk_buff *);
47 static void irttp_connect_indication( void *instance, void *sap,
48 struct qos_info *qos, int max_sdu_size,
49 struct sk_buff *skb);
51 static void irttp_run_tx_queue( struct tsap_cb *self);
52 static void irttp_run_rx_queue( struct tsap_cb *self);
54 static void irttp_flush_queues( struct tsap_cb *self);
55 static void irttp_fragment_skb( struct tsap_cb *self, struct sk_buff *skb);
56 static struct sk_buff *irttp_reassemble_skb( struct tsap_cb *self);
57 static void irttp_start_todo_timer( struct tsap_cb *self, int timeout);
60 * Function irttp_init (void)
62 * Initialize the IrTTP layer. Called by module initialization code
65 __initfunc(int irttp_init(void))
67 DEBUG( 4, "--> irttp_init\n");
69 /* Initialize the irttp structure. */
70 if ( irttp == NULL) {
71 irttp = kmalloc( sizeof(struct irttp_cb), GFP_KERNEL);
72 if ( irttp == NULL)
73 return -ENOMEM;
75 memset( irttp, 0, sizeof(struct irttp_cb));
77 irttp->magic = TTP_MAGIC;
79 irttp->tsaps = hashbin_new( HB_LOCAL);
80 if ( !irttp->tsaps) {
81 printk( KERN_WARNING "IrDA: Can't allocate IrTTP hashbin!\n");
82 return -ENOMEM;
85 return 0;
89 * Function irttp_cleanup (void)
91 * Called by module destruction/cleanup code
94 void irttp_cleanup(void)
96 DEBUG( 4, "irttp_cleanup\n");
98 /* Check for main structure */
99 ASSERT( irttp != NULL, return;);
100 ASSERT( irttp->magic == TTP_MAGIC, return;);
103 * Delete hashbin and close all TSAP instances in it
105 hashbin_delete( irttp->tsaps, (FREE_FUNC) __irttp_close_tsap);
107 irttp->magic = ~TTP_MAGIC;
109 /* De-allocate main structure */
110 kfree( irttp);
112 irttp = NULL;
116 * Function irttp_open_tsap (stsap, notify)
118 * Create TSAP connection endpoint,
120 struct tsap_cb *irttp_open_tsap( __u8 stsap_sel, int credit,
121 struct notify_t *notify)
123 struct notify_t ttp_notify;
124 struct tsap_cb *self;
125 struct lsap_cb *lsap;
127 ASSERT( irttp != NULL, return NULL;);
128 ASSERT( irttp->magic == TTP_MAGIC, return NULL;);
130 self = kmalloc( sizeof(struct tsap_cb), GFP_ATOMIC);
131 if ( self == NULL) {
132 printk( KERN_ERR "IrTTP: Can't allocate memory for "
133 "TSAP control block!\n");
134 return NULL;
136 memset( self, 0, sizeof(struct tsap_cb));
138 init_timer( &self->todo_timer);
140 /* Initialize callbacks for IrLMP to use */
142 irda_notify_init( &ttp_notify);
143 ttp_notify.connect_confirm = irttp_connect_confirm;
144 ttp_notify.connect_indication = irttp_connect_indication;
145 ttp_notify.disconnect_indication = irttp_disconnect_indication;
146 ttp_notify.data_indication = irttp_data_indication;
147 ttp_notify.udata_indication = irttp_udata_indication;
148 ttp_notify.instance = self;
149 strncpy( ttp_notify.name, notify->name, NOTIFY_MAX_NAME);
152 * Create LSAP at IrLMP layer
154 lsap = irlmp_open_lsap( stsap_sel, &ttp_notify);
155 if ( lsap == NULL) {
156 printk( KERN_ERR "IrTTP, Unable to get LSAP!!\n");
157 return NULL;
161 * If user specified LSAP_ANY as source TSAP selector, then IrLMP
162 * will replace it with whatever source selector which is free, so
163 * the stsap_sel we have might not be valid anymore
165 self->stsap_sel = lsap->slsap_sel;
166 DEBUG( 4, __FUNCTION__ "(), stsap_sel=%02x\n", self->stsap_sel);
168 self->notify = *notify;
169 self->lsap = lsap;
170 self->magic = TTP_TSAP_MAGIC;
172 skb_queue_head_init( &self->rx_queue);
173 skb_queue_head_init( &self->tx_queue);
174 skb_queue_head_init( &self->rx_fragments);
177 * Insert ourself into the hashbin
179 hashbin_insert( irttp->tsaps, (QUEUE *) self, self->stsap_sel, NULL);
181 if ( credit > TTP_MAX_QUEUE)
182 self->initial_credit = TTP_MAX_QUEUE;
183 else
184 self->initial_credit = credit;
186 return self;
190 * Function irttp_close (handle)
192 * Remove an instance of a TSAP. This function should only deal with the
193 * deallocation of the TSAP, and resetting of the TSAPs values;
196 static void __irttp_close_tsap( struct tsap_cb *self)
198 DEBUG( 4, __FUNCTION__ "()\n");
200 /* First make sure we're connected. */
201 ASSERT( self != NULL, return;);
202 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
204 irttp_flush_queues( self);
206 del_timer( &self->todo_timer);
208 self->connected = FALSE;
209 self->magic = ~TTP_TSAP_MAGIC;
212 * Deallocate structure
214 kfree( self);
216 DEBUG( 4, "irttp_close_tsap() -->\n");
220 * Function irttp_close (self)
222 * Remove TSAP from list of all TSAPs and then deallocate all resources
223 * associated with this TSAP
226 void irttp_close_tsap( struct tsap_cb *self)
228 struct tsap_cb *tsap;
230 ASSERT( self != NULL, return;);
231 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
233 tsap = hashbin_remove( irttp->tsaps, self->stsap_sel, NULL);
235 ASSERT( tsap == self, return;);
237 /* Close corresponding LSAP */
238 if ( self->lsap) {
239 irlmp_close_lsap( self->lsap);
240 self->lsap = NULL;
243 __irttp_close_tsap( self);
247 * Function irttp_udata_request (self, skb)
249 * Send unreliable data on this TSAP
252 int irttp_udata_request( struct tsap_cb *self, struct sk_buff *skb)
254 ASSERT( self != NULL, return -1;);
255 ASSERT( self->magic == TTP_TSAP_MAGIC, return -1;);
256 ASSERT( skb != NULL, return -1;);
258 DEBUG( 4, __FUNCTION__ "()\n");
260 /* Check that nothing bad happens */
261 if (( skb->len == 0) || ( !self->connected)) {
262 DEBUG( 0, __FUNCTION__ "(), No data, or not connected\n");
263 return -1;
266 if ( skb->len > self->max_seg_size) {
267 DEBUG( 0, __FUNCTION__ "(), UData is to large for IrLAP!\n");
268 return -1;
271 irlmp_udata_request( self->lsap, skb);
272 self->stats.tx_packets++;
274 return 0;
278 * Function irttp_data_request (handle, skb)
280 * Queue frame for transmission. If SAR is enabled, fragement the frame
281 * and queue the fragments for transmission
283 int irttp_data_request( struct tsap_cb *self, struct sk_buff *skb)
285 __u8 *frame;
287 DEBUG( 4, __FUNCTION__ "()\n");
289 ASSERT( self != NULL, return -1;);
290 ASSERT( self->magic == TTP_TSAP_MAGIC, return -1;);
291 ASSERT( skb != NULL, return -1;);
293 /* Check that nothing bad happens */
294 if (( skb->len == 0) || ( !self->connected)) {
295 DEBUG( 4, __FUNCTION__ "(), No data, or not connected\n");
296 return -1;
300 * Check if SAR is disabled, and the frame is larger than what fits
301 * inside an IrLAP frame
303 if (( self->tx_max_sdu_size == 0) &&
304 ( skb->len > self->max_seg_size))
306 DEBUG( 0, __FUNCTION__
307 "(), SAR disabled, and data is to large for IrLAP!\n");
308 return -1;
312 * Check if SAR is enabled, and the frame is larger than the
313 * TxMaxSduSize
315 if (( self->tx_max_sdu_size != 0) &&
316 (skb->len > self->tx_max_sdu_size))
318 DEBUG( 0, __FUNCTION__ "(), SAR enabled, "
319 "but data is larger than TxMaxSduSize!\n");
320 return -1;
323 * Check if transmit queue is full
325 if ( skb_queue_len( &self->tx_queue) >= TTP_MAX_QUEUE) {
327 * Give it a chance to empty itself
329 irttp_run_tx_queue( self);
331 return -1;
334 /* Queue frame, or queue frame segments */
335 if (( self->tx_max_sdu_size == 0) ||
336 ( skb->len < self->max_seg_size)) {
337 /* Queue frame */
338 frame = skb_push( skb, TTP_HEADER);
339 frame[0] = 0x00; /* Clear more bit */
341 DEBUG( 4, __FUNCTION__ "(), queueing original skb\n");
342 skb_queue_tail( &self->tx_queue, skb);
343 } else {
345 * Fragment the frame, this function will also queue the
346 * fragments, we don't care about the fact the the transmit
347 * queue may be overfilled by all the segments for a little
348 * while
350 irttp_fragment_skb( self, skb);
353 /* Check if we can accept more data from client */
354 if (( !self->tx_sdu_busy) &&
355 ( skb_queue_len( &self->tx_queue) > HIGH_THRESHOLD)) {
357 /* Tx queue filling up, so stop client */
358 self->tx_sdu_busy = TRUE;
360 if ( self->notify.flow_indication) {
361 self->notify.flow_indication( self->notify.instance,
362 self,
363 FLOW_STOP);
367 /* Try to make some progress */
368 irttp_run_tx_queue( self);
370 return 0;
374 * Function irttp_xmit (self)
376 * If possible, transmit a frame queued for transmission.
379 static void irttp_run_tx_queue( struct tsap_cb *self)
381 struct sk_buff *skb = NULL;
382 unsigned long flags;
383 __u8 *frame;
384 int n;
386 ASSERT( self != NULL, return;);
387 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
389 if ( irda_lock( &self->tx_queue_lock) == FALSE)
390 return;
392 while (( self->send_credit > 0) && !skb_queue_empty( &self->tx_queue)){
394 skb = skb_dequeue( &self->tx_queue);
395 ASSERT( skb != NULL, return;);
397 /* Make room for TTP header */
398 ASSERT( skb_headroom( skb) >= TTP_HEADER, return;);
401 * Since we can transmit and receive frames concurrently,
402 * the code below is a critical region and we must assure that
403 * nobody messes with the credits while we update them.
405 save_flags( flags);
406 cli();
408 n = self->avail_credit;
409 self->avail_credit = 0;
411 /* Only space for 127 credits in frame */
412 if ( n > 127) {
413 self->avail_credit = n-127;
414 n = 127;
416 self->remote_credit += n;
417 self->send_credit--;
419 restore_flags(flags);
421 DEBUG( 4, "irttp_xmit: Giving away %d credits\n", n);
424 * More bit must be set by the data_request() or fragment()
425 * functions
427 frame = skb->data;
429 DEBUG( 4, __FUNCTION__ "(), More=%s\n", frame[0] & 0x80 ?
430 "TRUE" : "FALSE" );
432 frame[0] |= (__u8) (n & 0x7f);
434 irlmp_data_request( self->lsap, skb);
435 self->stats.tx_packets++;
437 /* Check if we can accept more frames from client */
438 if (( self->tx_sdu_busy) &&
439 ( skb_queue_len( &self->tx_queue) < LOW_THRESHOLD)) {
440 self->tx_sdu_busy = FALSE;
442 if ( self->notify.flow_indication)
443 self->notify.flow_indication( self->notify.instance,
444 self,
445 FLOW_START);
449 /* Reset lock */
450 self->tx_queue_lock = 0;
452 /* Check if there is any disconnect request pending */
453 if ( self->disconnect_pend) {
454 if ( self->disconnect_skb) {
455 irttp_disconnect_request( self, self->disconnect_skb,
456 P_NORMAL);
457 self->disconnect_skb = NULL;
458 } else
459 irttp_disconnect_request( self, NULL, P_NORMAL);
464 * Function irttp_give_credit (self)
466 * Send a dataless flowdata TTP-PDU and give available credit to peer
467 * TSAP
469 void irttp_give_credit( struct tsap_cb *self)
471 struct sk_buff *tx_skb = NULL;
472 unsigned long flags;
473 int n;
475 ASSERT( self != NULL, return;);
476 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
478 DEBUG( 4, "irttp_give_credit() send=%d,avail=%d,remote=%d\n",
479 self->send_credit, self->avail_credit, self->remote_credit);
481 /* Give credit to peer */
482 tx_skb = dev_alloc_skb( 64);
483 if ( tx_skb == NULL) {
484 DEBUG( 0, "irttp_give_credit: "
485 "Could not allocate an sk_buff of length %d\n", 64);
486 return;
489 /* Reserve space for LMP, and LAP header */
490 skb_reserve( tx_skb, LMP_HEADER+LAP_HEADER);
493 * Since we can transmit and receive frames concurrently,
494 * the code below is a critical region and we must assure that
495 * nobody messes with the credits while we update them.
497 save_flags( flags);
498 cli();
500 n = self->avail_credit;
501 self->avail_credit = 0;
503 /* Only space for 127 credits in frame */
504 if ( n > 127) {
505 self->avail_credit = n - 127;
506 n = 127;
508 self->remote_credit += n;
510 restore_flags(flags);
512 skb_put( tx_skb, 1);
513 tx_skb->data[0] = (__u8) ( n & 0x7f);
515 irlmp_data_request( self->lsap, tx_skb);
516 self->stats.tx_packets++;
520 * Function irttp_udata_indication (instance, sap, skb)
525 void irttp_udata_indication( void *instance, void *sap, struct sk_buff *skb)
527 struct tsap_cb *self;
529 DEBUG( 4, __FUNCTION__ "()\n");
531 self = (struct tsap_cb *) instance;
533 ASSERT( self != NULL, return;);
534 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
535 ASSERT( skb != NULL, return;);
537 /* Just pass data to layer above */
538 if ( self->notify.udata_indication) {
539 self->notify.udata_indication( self->notify.instance, self,
540 skb);
542 self->stats.rx_packets++;
546 * Function irttp_data_indication (handle, skb)
548 * Receive segment from IrLMP.
551 void irttp_data_indication( void *instance, void *sap, struct sk_buff *skb)
553 struct tsap_cb *self;
554 int more;
555 int n;
556 __u8 *frame;
558 self = (struct tsap_cb *) instance;
560 ASSERT( self != NULL, return;);
561 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
562 ASSERT( skb != NULL, return;);
564 frame = skb->data;
566 n = frame[0] & 0x7f; /* Extract the credits */
567 more = frame[0] & 0x80;
569 DEBUG( 4, __FUNCTION__"(), got %d credits, TSAP sel=%02x\n",
570 n, self->stsap_sel);
572 self->stats.rx_packets++;
575 * Data or dataless frame? Dataless frames only contain the
576 * TTP_HEADER
578 if ( skb->len == 1) {
579 /* Dataless flowdata TTP-PDU */
580 self->send_credit += n;
581 } else {
582 /* Deal with inbound credit */
583 self->send_credit += n;
584 self->remote_credit--;
587 * We don't remove the TTP header, since we must preserve the
588 * more bit, so the defragment routing knows what to do
590 skb_queue_tail( &self->rx_queue, skb);
593 irttp_run_rx_queue( self);
596 * Give avay some credits to peer?
598 if (( skb_queue_empty( &self->tx_queue)) &&
599 ( self->remote_credit < LOW_THRESHOLD) &&
600 ( self->avail_credit > 0))
602 /* Schedule to start immediately after this thread */
603 irttp_start_todo_timer( self, 0);
606 /* If peer has given us some credites and we didn't have anyone
607 * from before, the we need to shedule the tx queue?
609 if ( self->send_credit == n)
610 irttp_start_todo_timer( self, 0);
614 * Function irttp_flow_request (self, command)
616 * This funtion could be used by the upper layers to tell IrTTP to stop
617 * delivering frames if the receive queues are starting to get full, or
618 * to tell IrTTP to start delivering frames again.
620 void irttp_flow_request( struct tsap_cb *self, LOCAL_FLOW flow)
622 DEBUG( 0, __FUNCTION__ "()\n");
624 ASSERT( self != NULL, return;);
625 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
627 switch ( flow) {
628 case FLOW_STOP:
629 DEBUG( 0, __FUNCTION__ "(), flow stop\n");
630 self->rx_sdu_busy = TRUE;
631 break;
632 case FLOW_START:
633 DEBUG( 0, __FUNCTION__ "(), flow start\n");
634 self->rx_sdu_busy = FALSE;
636 irttp_run_rx_queue( self);
637 break;
638 default:
639 DEBUG( 0, __FUNCTION__ "(), Unknown flow command!\n");
644 * Function irttp_connect_request (self, dtsap_sel, daddr, qos)
646 * Try to connect to remote destination TSAP selector
649 void irttp_connect_request( struct tsap_cb *self, __u8 dtsap_sel, __u32 daddr,
650 struct qos_info *qos, int max_sdu_size,
651 struct sk_buff *userdata)
653 struct sk_buff *skb;
654 __u8 *frame;
655 __u8 n;
657 DEBUG( 4, __FUNCTION__ "(), max_sdu_size=%d\n", max_sdu_size);
659 ASSERT( self != NULL, return;);
660 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
662 /* Any userdata supplied? */
663 if ( userdata == NULL) {
664 skb = dev_alloc_skb( 64);
665 if (skb == NULL) {
666 DEBUG( 0, __FUNCTION__ "Could not allocate an "
667 "sk_buff of length %d\n", 64);
668 return;
671 /* Reserve space for MUX_CONTROL and LAP header */
672 skb_reserve( skb, (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER));
673 } else {
674 skb = userdata;
676 * Check that the client has reserved enough space for
677 * headers
679 ASSERT( skb_headroom( userdata) >=
680 (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER), return;);
683 /* Initialize connection parameters */
684 self->connected = FALSE;
685 self->avail_credit = 0;
686 self->rx_max_sdu_size = max_sdu_size;
687 self->rx_sdu_size = 0;
688 self->rx_sdu_busy = FALSE;
689 self->dtsap_sel = dtsap_sel;
691 n = self->initial_credit;
693 self->remote_credit = 0;
694 self->send_credit = 0;
697 * Give away max 127 credits for now
699 if ( n > 127) {
700 self->avail_credit=n-127;
701 n = 127;
704 self->remote_credit = n;
706 /* SAR enabled? */
707 if ( max_sdu_size > 0) {
708 ASSERT( skb_headroom( skb) >=
709 (TTP_HEADER_WITH_SAR+LMP_CONTROL_HEADER+LAP_HEADER),
710 return;);
712 /* Insert SAR parameters */
713 frame = skb_push( skb, TTP_HEADER_WITH_SAR);
715 frame[0] = TTP_PARAMETERS | n;
716 frame[1] = 0x04; /* Length */
717 frame[2] = 0x01; /* MaxSduSize */
718 frame[3] = 0x02; /* Value length */
719 *((__u16 *) (frame+4))= htons( max_sdu_size); /* Big endian! */
720 } else {
721 /* Insert plain TTP header */
722 frame = skb_push( skb, TTP_HEADER);
724 /* Insert initial credit in frame */
725 frame[0] = n & 0x7f;
728 /* Connect with IrLMP. No QoS parameters for now */
729 irlmp_connect_request( self->lsap, dtsap_sel, daddr, qos, skb);
733 * Function irttp_connect_confirm (handle, qos, skb)
735 * Sevice user confirms TSAP connection with peer.
738 void irttp_connect_confirm( void *instance, void *sap, struct qos_info *qos,
739 int max_seg_size, struct sk_buff *skb)
741 struct tsap_cb *self;
742 __u8 *frame;
743 __u8 n;
744 int parameters;
746 DEBUG( 4, __FUNCTION__ "()\n");
748 self = (struct tsap_cb *) instance;
750 ASSERT( self != NULL, return;);
751 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
752 ASSERT( skb != NULL, return;);
754 /* FIXME: just remove this when we know its working */
755 ASSERT( max_seg_size == qos->data_size.value, return;);
757 self->max_seg_size = max_seg_size-LMP_HEADER-LAP_HEADER;
760 * Check if we have got some QoS parameters back! This should be the
761 * negotiated QoS for the link.
763 if ( qos) {
764 DEBUG( 4, "IrTTP, Negotiated BAUD_RATE: %02x\n",
765 qos->baud_rate.bits);
766 DEBUG( 4, "IrTTP, Negotiated BAUD_RATE: %d bps.\n",
767 qos->baud_rate.value);
770 frame = skb->data;
771 n = frame[0] & 0x7f;
773 DEBUG( 4, __FUNCTION__ "(), Initial send_credit=%d\n", n);
775 self->send_credit = n;
776 self->tx_max_sdu_size = 0;
777 self->connected = TRUE;
779 parameters = frame[0] & 0x80;
780 if ( parameters) {
781 DEBUG( 4, __FUNCTION__ "(), Contains parameters!\n");
783 self->tx_max_sdu_size = ntohs(*(__u16 *)(frame+4));
784 DEBUG( 4, __FUNCTION__ "(), RxMaxSduSize=%d\n",
785 self->tx_max_sdu_size);
788 DEBUG( 4, "irttp_connect_confirm() send=%d,avail=%d,remote=%d\n",
789 self->send_credit, self->avail_credit, self->remote_credit);
791 skb_pull( skb, TTP_HEADER);
793 if ( self->notify.connect_confirm) {
794 self->notify.connect_confirm( self->notify.instance, self,
795 qos, self->tx_max_sdu_size,
796 skb);
801 * Function irttp_connect_indication (handle, skb)
803 * Some other device is connecting to this TSAP
806 void irttp_connect_indication( void *instance, void *sap,
807 struct qos_info *qos, int max_seg_size,
808 struct sk_buff *skb)
810 struct tsap_cb *self;
811 __u8 *frame;
812 int parameters;
813 int n;
815 self = (struct tsap_cb *) instance;
817 ASSERT( self != NULL, return;);
818 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
819 ASSERT( skb != NULL, return;);
821 /* FIXME: just remove this when we know its working */
822 ASSERT( max_seg_size == qos->data_size.value, return;);
824 self->max_seg_size = max_seg_size-LMP_HEADER-LAP_HEADER;
826 DEBUG( 4, "irttp_connect_indication(), TSAP sel=%02x\n",
827 self->stsap_sel);
829 /* FIXME: Need to update dtsap_sel if its equal to LSAP_ANY */
830 /* if ( self->dtsap_sel == LSAP_ANY) */
831 /* self->dtsap_sel = lsap->dlsap_sel; */
833 frame = skb->data;
834 n = frame[0] & 0x7f;
836 self->send_credit = n;
837 self->tx_max_sdu_size = 0;
839 parameters = frame[0] & 0x80;
840 if ( parameters) {
841 DEBUG( 4, __FUNCTION__ "(), Contains parameters!\n");
843 self->tx_max_sdu_size = ntohs(*(__u16 *)(frame+4));
844 DEBUG( 4, __FUNCTION__ "(), MaxSduSize=%d\n",
845 self->tx_max_sdu_size);
848 DEBUG( 4, "irttp_connect_indication: initial send_credit=%d\n", n);
850 skb_pull( skb, 1);
852 if ( self->notify.connect_indication) {
853 self->notify.connect_indication( self->notify.instance, self,
854 qos, self->rx_max_sdu_size,
855 skb);
860 * Function irttp_connect_response (handle, userdata)
862 * Service user is accepting the connection, just pass it down to
863 * IrLMP!
866 void irttp_connect_response( struct tsap_cb *self, int max_sdu_size,
867 struct sk_buff *userdata)
869 struct sk_buff *skb;
870 __u8 *frame;
871 __u8 n;
873 ASSERT( self != NULL, return;);
874 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
876 DEBUG( 4, __FUNCTION__ "(), Source TSAP selector=%02x\n",
877 self->stsap_sel);
879 /* Any userdata supplied? */
880 if ( userdata == NULL) {
881 skb = dev_alloc_skb( 64);
882 if (skb == NULL) {
883 DEBUG( 0, __FUNCTION__ "Could not allocate an "
884 "sk_buff of length %d\n", 64);
885 return;
888 /* Reserve space for MUX_CONTROL and LAP header */
889 skb_reserve( skb, (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER));
890 } else {
891 skb = userdata;
893 * Check that the client has reserved enough space for
894 * headers
896 ASSERT( skb_headroom( skb) >=
897 (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER), return;);
900 self->avail_credit = 0;
901 self->remote_credit = 0;
902 self->rx_max_sdu_size = max_sdu_size;
903 self->rx_sdu_size = 0;
904 self->rx_sdu_busy = FALSE;
906 n = self->initial_credit;
908 /* Frame has only space for max 127 credits (7 bits) */
909 if ( n > 127) {
910 self->avail_credit = n - 127;
911 n = 127;
914 self->remote_credit = n;
915 self->connected = TRUE;
917 /* SAR enabled? */
918 if ( max_sdu_size > 0) {
919 ASSERT( skb_headroom( skb) >=
920 (TTP_HEADER_WITH_SAR+LMP_CONTROL_HEADER+LAP_HEADER),
921 return;);
923 /* Insert TTP header with SAR parameters */
924 frame = skb_push( skb, TTP_HEADER_WITH_SAR);
926 frame[0] = TTP_PARAMETERS | n;
927 frame[1] = 0x04; /* Length */
928 frame[2] = 0x01; /* MaxSduSize */
929 frame[3] = 0x02; /* Value length */
930 *((__u16 *) (frame+4))= htons( max_sdu_size);
931 } else {
932 /* Insert TTP header */
933 frame = skb_push( skb, TTP_HEADER);
935 frame[0] = n & 0x7f;
938 irlmp_connect_response( self->lsap, skb);
942 * Function irttp_disconnect_request ( self)
944 * Close this connection please! If priority is high, the queued data
945 * segments, if any, will be deallocated first
948 void irttp_disconnect_request( struct tsap_cb *self, struct sk_buff *userdata,
949 int priority)
951 struct sk_buff *skb;
953 DEBUG( 4, __FUNCTION__ "()\n");
955 ASSERT( self != NULL, return;);
956 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
958 /* Already disconnected? */
959 if ( !self->connected) {
960 DEBUG( 4, __FUNCTION__ "(), already disconnected!\n");
961 return;
964 /* Disconnect already pending? */
965 if ( self->disconnect_pend) {
966 DEBUG( 0, __FUNCTION__ "(), disconnect already pending\n");
967 if ( userdata) {
968 dev_kfree_skb( userdata);
971 /* Try to make some progress */
972 irttp_run_rx_queue( self);
973 return;
977 * Check if there is still data segments in the transmit queue
979 if ( skb_queue_len( &self->tx_queue) > 0) {
980 if ( priority == P_HIGH) {
981 DEBUG( 0, __FUNCTION__ "High priority!!()\n" );
984 * No need to send the queued data, if we are
985 * disconnecting right now since the data will
986 * not have any usable connection to be sent on
988 irttp_flush_queues( self);
989 } else if ( priority == P_NORMAL) {
991 * Must delay disconnect til after all data segments
992 * have been sent an the tx_queue is empty
994 if ( userdata)
995 self->disconnect_skb = userdata;
996 else
997 self->disconnect_skb = NULL;
999 self->disconnect_pend = TRUE;
1001 irttp_run_tx_queue( self);
1003 * irttp_xmit will call us again when the tx_queue
1004 * is empty
1006 return;
1009 DEBUG( 0, __FUNCTION__ "(), Disconnecting ...\n");
1011 self->connected = FALSE;
1013 if ( !userdata) {
1014 skb = dev_alloc_skb( 64);
1015 if (skb == NULL) {
1016 DEBUG( 0, __FUNCTION__ "(), Could not allocate an "
1017 "sk_buff of length %d\n", 64);
1018 return;
1022 * Reserve space for MUX and LAP header
1024 skb_reserve( skb, LMP_CONTROL_HEADER+LAP_HEADER);
1026 userdata = skb;
1028 irlmp_disconnect_request( self->lsap, userdata);
1032 * Function irttp_disconnect_indication (self, reason)
1034 * Disconnect indication, TSAP disconnected by peer?
1037 void irttp_disconnect_indication( void *instance, void *sap, LM_REASON reason,
1038 struct sk_buff *userdata)
1040 struct tsap_cb *self;
1042 DEBUG( 4, "irttp_disconnect_indication()\n");
1044 self = ( struct tsap_cb *) instance;
1046 ASSERT( self != NULL, return;);
1047 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
1049 self->connected = FALSE;
1052 * Use callback to notify layer above
1054 if ( self->notify.disconnect_indication)
1055 self->notify.disconnect_indication( self->notify.instance,
1056 self, reason, userdata);
1060 * Function irttp_run_rx_queue (self)
1062 * Check if we have any frames to be transmitted, or if we have any
1063 * available credit to give away.
1065 void irttp_run_rx_queue( struct tsap_cb *self)
1067 struct sk_buff *skb;
1068 __u8 *frame;
1069 int more = 0;
1070 void *instance;
1072 ASSERT( self != NULL, return;);
1073 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
1075 instance = self->notify.instance;
1076 ASSERT( instance != NULL, return;);
1078 DEBUG( 4, "irttp_do_events() send=%d,avail=%d,remote=%d\n",
1079 self->send_credit, self->avail_credit, self->remote_credit);
1081 if ( irda_lock( &self->rx_queue_lock) == FALSE)
1082 return;
1085 * Process receive queue
1087 while (( !skb_queue_empty( &self->rx_queue)) && !self->rx_sdu_busy) {
1089 skb = skb_dequeue( &self->rx_queue);
1090 if ( !skb)
1091 break; /* Should not happend, but ... */
1093 self->avail_credit++;
1095 frame = skb->data;
1096 more = frame[0] & 0x80;
1097 DEBUG( 4, __FUNCTION__ "(), More=%s\n", more ? "TRUE" :
1098 "FALSE");
1100 /* Remove TTP header */
1101 skb_pull( skb, TTP_HEADER);
1103 /* Add the length of the remaining data */
1104 self->rx_sdu_size += skb->len;
1107 * If SAR is disabled, or user has requested no reassembly
1108 * of received fragements then we just deliver them
1109 * immediately. This can be requested by clients that
1110 * implements byte streams without any message boundaries
1112 if ((self->no_defrag) || (self->rx_max_sdu_size == 0)) {
1113 self->notify.data_indication( instance, self, skb);
1114 self->rx_sdu_size = 0;
1116 continue;
1119 /* Check if this is a fragment, and not the last fragment */
1120 if ( more) {
1122 * Queue the fragment if we still are within the
1123 * limits of the maximum size of the rx_sdu
1125 if ( self->rx_sdu_size <= self->rx_max_sdu_size) {
1126 DEBUG( 4, __FUNCTION__
1127 "(), queueing fragment\n");
1129 skb_queue_tail( &self->rx_fragments, skb);
1130 } else {
1131 DEBUG( 0, __FUNCTION__ "(), Error!\n");
1133 } else {
1135 * This is the last fragment, so time to reassemble!
1137 if ( self->rx_sdu_size <= self->rx_max_sdu_size) {
1139 /* A little optimizing. Only queue the
1140 * fragment if there is other fragments. Since
1141 * if this is the last and only fragment,
1142 * there is no need to reassemble
1144 if ( !skb_queue_empty( &self->rx_fragments)) {
1146 DEBUG( 4, __FUNCTION__
1147 "(), queueing fragment\n");
1148 skb_queue_tail( &self->rx_fragments,
1149 skb);
1151 skb = irttp_reassemble_skb( self);
1153 self->notify.data_indication( instance, self,
1154 skb);
1155 } else {
1156 DEBUG( 0, __FUNCTION__
1157 "(), Truncated frame\n");
1158 self->notify.data_indication(
1159 self->notify.instance, self, skb);
1161 self->rx_sdu_size = 0;
1164 /* Reset lock */
1165 self->rx_queue_lock = 0;
1169 * Function irttp_flush_queues (self)
1171 * Flushes (removes all frames) in transitt-buffer (tx_list)
1173 void irttp_flush_queues( struct tsap_cb *self)
1175 struct sk_buff* skb;
1177 DEBUG( 4, __FUNCTION__ "()\n");
1179 ASSERT( self != NULL, return;);
1180 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
1182 /* Deallocate frames waiting to be sent */
1183 while (( skb = skb_dequeue( &self->tx_queue)) != NULL) {
1184 dev_kfree_skb( skb);
1186 /* Deallocate received frames */
1187 while (( skb = skb_dequeue( &self->rx_queue)) != NULL) {
1188 dev_kfree_skb( skb);
1190 /* Deallocate received fragments */
1191 while (( skb = skb_dequeue( &self->rx_fragments)) != NULL) {
1192 dev_kfree_skb( skb);
1198 * Function irttp_reasseble (self)
1200 * Makes a new (continuous) skb of all the fragments in the fragment
1201 * queue
1204 static struct sk_buff *irttp_reassemble_skb( struct tsap_cb *self)
1206 struct sk_buff *skb, *frag;
1207 int n = 0; /* Fragment index */
1209 ASSERT( self != NULL, return NULL;);
1210 ASSERT( self->magic == TTP_TSAP_MAGIC, return NULL;);
1212 DEBUG( 4, __FUNCTION__ "(), self->rx_sdu_size=%d\n",
1213 self->rx_sdu_size);
1215 skb = dev_alloc_skb( self->rx_sdu_size);
1216 if ( !skb) {
1217 DEBUG( 0, __FUNCTION__ "(), unable to allocate skb\n");
1218 return NULL;
1221 skb_put( skb, self->rx_sdu_size);
1224 * Copy all fragments to a new buffer
1226 while (( frag = skb_dequeue( &self->rx_fragments)) != NULL) {
1227 memcpy( skb->data+n, frag->data, frag->len);
1228 n += frag->len;
1230 dev_kfree_skb( frag);
1232 DEBUG( 4, __FUNCTION__ "(), frame len=%d\n", n);
1233 /* Set the new length */
1235 DEBUG( 4, __FUNCTION__ "(), rx_sdu_size=%d\n", self->rx_sdu_size);
1236 ASSERT( n <= self->rx_sdu_size, return NULL;);
1237 skb_trim( skb, n);
1239 self->rx_sdu_size = 0;
1241 return skb;
1245 * Function irttp_fragment_skb (skb)
1247 * Fragments a frame and queues all the fragments for transmission
1250 static void irttp_fragment_skb( struct tsap_cb *self, struct sk_buff *skb)
1252 struct sk_buff *frag;
1253 __u8 *frame;
1255 DEBUG( 4, __FUNCTION__ "()\n");
1257 ASSERT( self != NULL, return;);
1258 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
1259 ASSERT( skb != NULL, return;);
1262 * Split frame into a number of segments
1264 while ( skb->len > 0) {
1266 * Instead of making the last segment, we just
1267 * queue what is left of the original skb
1269 if ( skb->len < self->max_seg_size) {
1270 DEBUG( 4, __FUNCTION__
1271 "(), queuing last segment\n");
1273 frame = skb_push( skb, TTP_HEADER);
1274 frame[0] = 0x00; /* Clear more bit */
1275 skb_queue_tail( &self->tx_queue, skb);
1277 return;
1280 /* Make new segment */
1281 frag = dev_alloc_skb( self->max_seg_size+
1282 TTP_HEADER+LMP_HEADER+
1283 LAP_HEADER);
1284 if ( frag == NULL) {
1285 DEBUG( 0, __FUNCTION__
1286 "(), Couldn't allocate skbuff!\n");
1287 return;
1290 skb_reserve( frag, LMP_HEADER+LAP_HEADER);
1293 * Copy data from the original skb into this fragment. We
1294 * first insert the TTP header with the more bit set
1296 frame = skb_put( frag, self->max_seg_size+TTP_HEADER);
1297 frame[0] = TTP_MORE;
1298 memcpy( frag->data+1, skb->data, self->max_seg_size);
1300 /* Hide the copied data from the original skb */
1301 skb_pull( skb, self->max_seg_size);
1303 skb_queue_tail( &self->tx_queue, frag);
1308 * Function irttp_todo_expired (data)
1310 * Todo timer has expired!
1313 static void irttp_todo_expired( unsigned long data)
1315 struct tsap_cb *self = ( struct tsap_cb *) data;
1317 DEBUG( 4, __FUNCTION__ "()\n");
1319 /* Check that we still exist */
1320 if ( !self || self->magic != TTP_TSAP_MAGIC) {
1321 return;
1324 irttp_run_rx_queue( self);
1325 irttp_run_tx_queue( self);
1327 /* Give avay some credits to peer? */
1328 if (( skb_queue_empty( &self->tx_queue)) &&
1329 ( self->remote_credit < LOW_THRESHOLD) &&
1330 ( self->avail_credit > 0))
1332 DEBUG( 4, "irttp_do_events: sending credit!\n");
1333 irttp_give_credit( self);
1336 /* Rearm! */
1337 /* irttp_start_todo_timer( self, 50); */
1341 * Function irttp_start_todo_timer (self, timeout)
1343 * Start todo timer.
1346 static void irttp_start_todo_timer( struct tsap_cb *self, int timeout)
1348 ASSERT( self != NULL, return;);
1349 ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
1351 del_timer( &self->todo_timer);
1353 self->todo_timer.data = (unsigned long) self;
1354 self->todo_timer.function = &irttp_todo_expired;
1355 self->todo_timer.expires = jiffies + timeout;
1357 add_timer( &self->todo_timer);
1360 #ifdef CONFIG_PROC_FS
1362 * Function irttp_proc_read (buf, start, offset, len, unused)
1364 * Give some info to the /proc file system
1366 int irttp_proc_read( char *buf, char **start, off_t offset, int len,
1367 int unused)
1369 struct tsap_cb *self;
1370 unsigned long flags;
1371 int i = 0;
1373 ASSERT( irttp != NULL, return 0;);
1375 len = 0;
1377 save_flags(flags);
1378 cli();
1380 self = ( struct tsap_cb *) hashbin_get_first( irttp->tsaps);
1381 while ( self != NULL) {
1382 if ( !self || self->magic != TTP_TSAP_MAGIC) {
1383 DEBUG( 0, "irttp_proc_read: bad ptr self\n");
1384 return len;
1387 len += sprintf( buf+len, "TSAP %d, ", i++);
1388 len += sprintf( buf+len, "stsap_sel: %02x, ",
1389 self->stsap_sel);
1390 len += sprintf( buf+len, "dtsap_sel: %02x\n",
1391 self->dtsap_sel);
1392 len += sprintf( buf+len, " connected: %s, ",
1393 self->connected? "TRUE":"FALSE");
1394 len += sprintf( buf+len, "avail credit: %d, ",
1395 self->avail_credit);
1396 len += sprintf( buf+len, "remote credit: %d, ",
1397 self->remote_credit);
1398 len += sprintf( buf+len, "send credit: %d\n",
1399 self->send_credit);
1400 len += sprintf( buf+len, " tx packets: %d, ",
1401 self->stats.tx_packets);
1402 len += sprintf( buf+len, "rx packets: %d, ",
1403 self->stats.rx_packets);
1404 len += sprintf( buf+len, "tx_queue len: %d ",
1405 skb_queue_len( &self->tx_queue));
1406 len += sprintf( buf+len, "rx_queue len: %d\n",
1407 skb_queue_len( &self->rx_queue));
1408 len += sprintf( buf+len, " tx_sdu_busy: %s, ",
1409 self->tx_sdu_busy? "TRUE":"FALSE");
1410 len += sprintf( buf+len, "rx_sdu_busy: %s\n",
1411 self->rx_sdu_busy? "TRUE":"FALSE");
1412 len += sprintf( buf+len, " max_seg_size: %d, ",
1413 self->max_seg_size);
1414 len += sprintf( buf+len, "tx_max_sdu_size: %d, ",
1415 self->tx_max_sdu_size);
1416 len += sprintf( buf+len, "rx_max_sdu_size: %d\n",
1417 self->rx_max_sdu_size);
1419 len += sprintf( buf+len, " Used by (%s)\n",
1420 self->notify.name);
1422 len += sprintf( buf+len, "\n");
1424 self = ( struct tsap_cb *) hashbin_get_next( irttp->tsaps);
1426 restore_flags(flags);
1428 return len;
1431 #endif /* PROC_FS */