1 /*********************************************************************
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
,
42 static void irttp_udata_indication( void *instance
, void *sap
,
44 static void irttp_disconnect_indication( void *instance
, void *sap
,
47 static void irttp_connect_indication( void *instance
, void *sap
,
48 struct qos_info
*qos
, int max_sdu_size
,
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. */
71 irttp
= kmalloc( sizeof(struct irttp_cb
), GFP_KERNEL
);
75 memset( irttp
, 0, sizeof(struct irttp_cb
));
77 irttp
->magic
= TTP_MAGIC
;
79 irttp
->tsaps
= hashbin_new( HB_LOCAL
);
81 printk( KERN_WARNING
"IrDA: Can't allocate IrTTP hashbin!\n");
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 */
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
);
132 printk( KERN_ERR
"IrTTP: Can't allocate memory for "
133 "TSAP control block!\n");
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
);
156 printk( KERN_ERR
"IrTTP, Unable to get LSAP!!\n");
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
;
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
;
184 self
->initial_credit
= credit
;
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
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 */
239 irlmp_close_lsap( self
->lsap
);
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");
266 if ( skb
->len
> self
->max_seg_size
) {
267 DEBUG( 0, __FUNCTION__
"(), UData is to large for IrLAP!\n");
271 irlmp_udata_request( self
->lsap
, skb
);
272 self
->stats
.tx_packets
++;
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
)
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");
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");
312 * Check if SAR is enabled, and the frame is larger than the
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");
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
);
334 /* Queue frame, or queue frame segments */
335 if (( self
->tx_max_sdu_size
== 0) ||
336 ( skb
->len
< self
->max_seg_size
)) {
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
);
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
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
,
367 /* Try to make some progress */
368 irttp_run_tx_queue( self
);
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
;
386 ASSERT( self
!= NULL
, return;);
387 ASSERT( self
->magic
== TTP_TSAP_MAGIC
, return;);
389 if ( irda_lock( &self
->tx_queue_lock
) == FALSE
)
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.
408 n
= self
->avail_credit
;
409 self
->avail_credit
= 0;
411 /* Only space for 127 credits in frame */
413 self
->avail_credit
= n
-127;
416 self
->remote_credit
+= n
;
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()
429 DEBUG( 4, __FUNCTION__
"(), More=%s\n", frame
[0] & 0x80 ?
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
,
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
,
457 self
->disconnect_skb
= NULL
;
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
469 void irttp_give_credit( struct tsap_cb
*self
)
471 struct sk_buff
*tx_skb
= NULL
;
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);
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.
500 n
= self
->avail_credit
;
501 self
->avail_credit
= 0;
503 /* Only space for 127 credits in frame */
505 self
->avail_credit
= n
- 127;
508 self
->remote_credit
+= n
;
510 restore_flags(flags
);
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
,
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
;
558 self
= (struct tsap_cb
*) instance
;
560 ASSERT( self
!= NULL
, return;);
561 ASSERT( self
->magic
== TTP_TSAP_MAGIC
, return;);
562 ASSERT( skb
!= NULL
, return;);
566 n
= frame
[0] & 0x7f; /* Extract the credits */
567 more
= frame
[0] & 0x80;
569 DEBUG( 4, __FUNCTION__
"(), got %d credits, TSAP sel=%02x\n",
572 self
->stats
.rx_packets
++;
575 * Data or dataless frame? Dataless frames only contain the
578 if ( skb
->len
== 1) {
579 /* Dataless flowdata TTP-PDU */
580 self
->send_credit
+= n
;
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;);
629 DEBUG( 0, __FUNCTION__
"(), flow stop\n");
630 self
->rx_sdu_busy
= TRUE
;
633 DEBUG( 0, __FUNCTION__
"(), flow start\n");
634 self
->rx_sdu_busy
= FALSE
;
636 irttp_run_rx_queue( self
);
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
)
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);
666 DEBUG( 0, __FUNCTION__
"Could not allocate an "
667 "sk_buff of length %d\n", 64);
671 /* Reserve space for MUX_CONTROL and LAP header */
672 skb_reserve( skb
, (TTP_HEADER
+LMP_CONTROL_HEADER
+LAP_HEADER
));
676 * Check that the client has reserved enough space for
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
700 self
->avail_credit
=n
-127;
704 self
->remote_credit
= n
;
707 if ( max_sdu_size
> 0) {
708 ASSERT( skb_headroom( skb
) >=
709 (TTP_HEADER_WITH_SAR
+LMP_CONTROL_HEADER
+LAP_HEADER
),
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! */
721 /* Insert plain TTP header */
722 frame
= skb_push( skb
, TTP_HEADER
);
724 /* Insert initial credit in frame */
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
;
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.
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
);
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;
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
,
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
,
810 struct tsap_cb
*self
;
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",
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; */
836 self
->send_credit
= n
;
837 self
->tx_max_sdu_size
= 0;
839 parameters
= frame
[0] & 0x80;
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
);
852 if ( self
->notify
.connect_indication
) {
853 self
->notify
.connect_indication( self
->notify
.instance
, self
,
854 qos
, self
->rx_max_sdu_size
,
860 * Function irttp_connect_response (handle, userdata)
862 * Service user is accepting the connection, just pass it down to
866 void irttp_connect_response( struct tsap_cb
*self
, int max_sdu_size
,
867 struct sk_buff
*userdata
)
873 ASSERT( self
!= NULL
, return;);
874 ASSERT( self
->magic
== TTP_TSAP_MAGIC
, return;);
876 DEBUG( 4, __FUNCTION__
"(), Source TSAP selector=%02x\n",
879 /* Any userdata supplied? */
880 if ( userdata
== NULL
) {
881 skb
= dev_alloc_skb( 64);
883 DEBUG( 0, __FUNCTION__
"Could not allocate an "
884 "sk_buff of length %d\n", 64);
888 /* Reserve space for MUX_CONTROL and LAP header */
889 skb_reserve( skb
, (TTP_HEADER
+LMP_CONTROL_HEADER
+LAP_HEADER
));
893 * Check that the client has reserved enough space for
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) */
910 self
->avail_credit
= n
- 127;
914 self
->remote_credit
= n
;
915 self
->connected
= TRUE
;
918 if ( max_sdu_size
> 0) {
919 ASSERT( skb_headroom( skb
) >=
920 (TTP_HEADER_WITH_SAR
+LMP_CONTROL_HEADER
+LAP_HEADER
),
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
);
932 /* Insert TTP header */
933 frame
= skb_push( skb
, TTP_HEADER
);
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
,
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");
964 /* Disconnect already pending? */
965 if ( self
->disconnect_pend
) {
966 DEBUG( 0, __FUNCTION__
"(), disconnect already pending\n");
968 dev_kfree_skb( userdata
);
971 /* Try to make some progress */
972 irttp_run_rx_queue( self
);
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
995 self
->disconnect_skb
= userdata
;
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
1009 DEBUG( 0, __FUNCTION__
"(), Disconnecting ...\n");
1011 self
->connected
= FALSE
;
1014 skb
= dev_alloc_skb( 64);
1016 DEBUG( 0, __FUNCTION__
"(), Could not allocate an "
1017 "sk_buff of length %d\n", 64);
1022 * Reserve space for MUX and LAP header
1024 skb_reserve( skb
, LMP_CONTROL_HEADER
+LAP_HEADER
);
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
;
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
)
1085 * Process receive queue
1087 while (( !skb_queue_empty( &self
->rx_queue
)) && !self
->rx_sdu_busy
) {
1089 skb
= skb_dequeue( &self
->rx_queue
);
1091 break; /* Should not happend, but ... */
1093 self
->avail_credit
++;
1096 more
= frame
[0] & 0x80;
1097 DEBUG( 4, __FUNCTION__
"(), More=%s\n", more
? "TRUE" :
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;
1119 /* Check if this is a fragment, and not the last fragment */
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
);
1131 DEBUG( 0, __FUNCTION__
"(), Error!\n");
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
,
1151 skb
= irttp_reassemble_skb( self
);
1153 self
->notify
.data_indication( instance
, self
,
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;
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
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",
1215 skb
= dev_alloc_skb( self
->rx_sdu_size
);
1217 DEBUG( 0, __FUNCTION__
"(), unable to allocate skb\n");
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
);
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
;);
1239 self
->rx_sdu_size
= 0;
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
;
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
);
1280 /* Make new segment */
1281 frag
= dev_alloc_skb( self
->max_seg_size
+
1282 TTP_HEADER
+LMP_HEADER
+
1284 if ( frag
== NULL
) {
1285 DEBUG( 0, __FUNCTION__
1286 "(), Couldn't allocate skbuff!\n");
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
) {
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
);
1337 /* irttp_start_todo_timer( self, 50); */
1341 * Function irttp_start_todo_timer (self, timeout)
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
,
1369 struct tsap_cb
*self
;
1370 unsigned long flags
;
1373 ASSERT( irttp
!= NULL
, return 0;);
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");
1387 len
+= sprintf( buf
+len
, "TSAP %d, ", i
++);
1388 len
+= sprintf( buf
+len
, "stsap_sel: %02x, ",
1390 len
+= sprintf( buf
+len
, "dtsap_sel: %02x\n",
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",
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",
1422 len
+= sprintf( buf
+len
, "\n");
1424 self
= ( struct tsap_cb
*) hashbin_get_next( irttp
->tsaps
);
1426 restore_flags(flags
);
1431 #endif /* PROC_FS */