diff options
Diffstat (limited to 'net/irda/irttp.c')
-rw-r--r-- | net/irda/irttp.c | 156 |
1 files changed, 73 insertions, 83 deletions
diff --git a/net/irda/irttp.c b/net/irda/irttp.c index bf0624eee..8d5e31f41 100644 --- a/net/irda/irttp.c +++ b/net/irda/irttp.c @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 31 20:14:31 1997 - * Modified at: Sat Apr 10 10:32:21 1999 + * Modified at: Mon May 31 10:29:56 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, + * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -35,7 +35,7 @@ #include <net/irda/irlmp.h> #include <net/irda/irttp.h> -struct irttp_cb *irttp = NULL; +static struct irttp_cb *irttp = NULL; static void __irttp_close_tsap(struct tsap_cb *self); @@ -44,19 +44,20 @@ static int irttp_data_indication(void *instance, void *sap, static int irttp_udata_indication(void *instance, void *sap, struct sk_buff *skb); static void irttp_disconnect_indication(void *instance, void *sap, - LM_REASON reason, - struct sk_buff *); + LM_REASON reason, struct sk_buff *); static void irttp_connect_indication(void *instance, void *sap, struct qos_info *qos, __u32 max_sdu_size, - struct sk_buff *skb); - + __u8 header_size, struct sk_buff *skb); +static void irttp_connect_confirm(void *instance, void *sap, + struct qos_info *qos, __u32 max_sdu_size, + __u8 header_size, struct sk_buff *skb); static void irttp_run_tx_queue(struct tsap_cb *self); static void irttp_run_rx_queue(struct tsap_cb *self); static void irttp_flush_queues(struct tsap_cb *self); static void irttp_fragment_skb(struct tsap_cb *self, struct sk_buff *skb); -static struct sk_buff *irttp_reassemble_skb(struct tsap_cb *self); static void irttp_start_todo_timer(struct tsap_cb *self, int timeout); +static struct sk_buff *irttp_reassemble_skb(struct tsap_cb *self); /* * Function irttp_init (void) @@ -296,7 +297,7 @@ int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb) /* Check that nothing bad happens */ if ((skb->len == 0) || (!self->connected)) { - DEBUG(4, __FUNCTION__ "(), No data, or not connected\n"); + ERROR(__FUNCTION__ "(), No data, or not connected\n"); return -ENOTCONN; } @@ -305,8 +306,8 @@ int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb) * inside an IrLAP frame */ if ((self->tx_max_sdu_size == 0) && (skb->len > self->max_seg_size)) { - DEBUG(1, __FUNCTION__ - "(), SAR disabled, and data is to large for IrLAP!\n"); + ERROR(__FUNCTION__ + "(), SAR disabled, and data is to large for IrLAP!\n"); return -EMSGSIZE; } @@ -318,8 +319,8 @@ int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb) (self->tx_max_sdu_size != SAR_UNBOUND) && (skb->len > self->tx_max_sdu_size)) { - DEBUG(1, __FUNCTION__ "(), SAR enabled, " - "but data is larger than TxMaxSduSize!\n"); + ERROR(__FUNCTION__ "(), SAR enabled, " + "but data is larger than TxMaxSduSize!\n"); return -EMSGSIZE; } /* @@ -337,10 +338,10 @@ int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb) /* Queue frame, or queue frame segments */ if ((self->tx_max_sdu_size == 0) || (skb->len < self->max_seg_size)) { /* Queue frame */ + ASSERT(skb_headroom(skb) >= TTP_HEADER, return -1;); frame = skb_push(skb, TTP_HEADER); frame[0] = 0x00; /* Clear more bit */ - DEBUG(4, __FUNCTION__ "(), queueing original skb\n"); skb_queue_tail(&self->tx_queue, skb); } else { /* @@ -360,8 +361,8 @@ int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb) self->tx_sdu_busy = TRUE; if (self->notify.flow_indication) { - self->notify.flow_indication( - self->notify.instance, self, FLOW_STOP); + self->notify.flow_indication(self->notify.instance, + self, FLOW_STOP); } } @@ -381,12 +382,8 @@ static void irttp_run_tx_queue(struct tsap_cb *self) { struct sk_buff *skb = NULL; unsigned long flags; - __u8 *frame; int n; - ASSERT(self != NULL, return;); - ASSERT(self->magic == TTP_TSAP_MAGIC, return;); - if (irda_lock(&self->tx_queue_lock) == FALSE) return; @@ -421,12 +418,7 @@ static void irttp_run_tx_queue(struct tsap_cb *self) * More bit must be set by the data_request() or fragment() * functions */ - frame = skb->data; - - DEBUG(4, __FUNCTION__ "(), More=%s\n", frame[0] & 0x80 ? - "TRUE" : "FALSE" ); - - frame[0] |= (__u8) (n & 0x7f); + skb->data[0] |= (n & 0x7f); irlmp_data_request(self->lsap, skb); self->stats.tx_packets++; @@ -434,12 +426,12 @@ static void irttp_run_tx_queue(struct tsap_cb *self) /* Check if we can accept more frames from client */ if ((self->tx_sdu_busy) && (skb_queue_len(&self->tx_queue) < LOW_THRESHOLD)) - { + { self->tx_sdu_busy = FALSE; if (self->notify.flow_indication) self->notify.flow_indication( - self->notify.instance, self, + self->notify.instance, self, FLOW_START); } } @@ -472,7 +464,7 @@ void irttp_give_credit(struct tsap_cb *self) return; /* Reserve space for LMP, and LAP header */ - skb_reserve(tx_skb, LMP_HEADER+LAP_HEADER); + skb_reserve(tx_skb, self->max_header_size); /* * Since we can transmit and receive frames concurrently, @@ -538,23 +530,14 @@ static int irttp_data_indication(void *instance, void *sap, struct sk_buff *skb) { struct tsap_cb *self; - int more; int n; - __u8 *frame; - + self = (struct tsap_cb *) instance; ASSERT(self != NULL, return -1;); ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;); - ASSERT(skb != NULL, return -1;); - frame = skb->data; - - n = frame[0] & 0x7f; /* Extract the credits */ - more = frame[0] & 0x80; - - DEBUG(3, __FUNCTION__"(), got %d credits, TSAP sel=%02x\n", - n, self->stsap_sel); + n = skb->data[0] & 0x7f; /* Extract the credits */ self->stats.rx_packets++; @@ -562,10 +545,9 @@ static int irttp_data_indication(void *instance, void *sap, * Data or dataless frame? Dataless frames only contain the * TTP_HEADER */ - if (skb->len == 1) { - /* Dataless flowdata TTP-PDU */ - self->send_credit += n; - } else { + if (skb->len == 1) + self->send_credit += n; /* Dataless flowdata TTP-PDU */ + else { /* Deal with inbound credit */ self->send_credit += n; self->remote_credit--; @@ -655,15 +637,14 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel, return -ENOMEM; /* Reserve space for MUX_CONTROL and LAP header */ - skb_reserve(skb, (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER)); + skb_reserve(skb, TTP_MAX_HEADER); } else { skb = userdata; /* * Check that the client has reserved enough space for * headers */ - ASSERT(skb_headroom(userdata) >= - (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER), return -1;); + ASSERT(skb_headroom(userdata) >= TTP_MAX_HEADER, return -1;); } /* Initialize connection parameters */ @@ -691,12 +672,11 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel, /* SAR enabled? */ if (max_sdu_size > 0) { - ASSERT(skb_headroom(skb) >= - (TTP_HEADER_WITH_SAR+LMP_CONTROL_HEADER+LAP_HEADER), - return -1;); + ASSERT(skb_headroom(skb) >= (TTP_MAX_HEADER + TTP_SAR_HEADER), + return -1;); /* Insert SAR parameters */ - frame = skb_push(skb, TTP_HEADER_WITH_SAR); + frame = skb_push(skb, TTP_HEADER+TTP_SAR_HEADER); frame[0] = TTP_PARAMETERS | n; frame[1] = 0x04; /* Length */ @@ -724,8 +704,10 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel, * Sevice user confirms TSAP connection with peer. * */ -void irttp_connect_confirm(void *instance, void *sap, struct qos_info *qos, - __u32 max_seg_size, struct sk_buff *skb) +static void irttp_connect_confirm(void *instance, void *sap, + struct qos_info *qos, + __u32 max_seg_size, __u8 max_header_size, + struct sk_buff *skb) { struct tsap_cb *self; int parameters; @@ -741,7 +723,8 @@ void irttp_connect_confirm(void *instance, void *sap, struct qos_info *qos, ASSERT(self->magic == TTP_TSAP_MAGIC, return;); ASSERT(skb != NULL, return;); - self->max_seg_size = max_seg_size-LMP_HEADER-LAP_HEADER; + self->max_seg_size = max_seg_size; + self->max_header_size = max_header_size + TTP_HEADER; /* * Check if we have got some QoS parameters back! This should be the @@ -764,6 +747,10 @@ void irttp_connect_confirm(void *instance, void *sap, struct qos_info *qos, self->connected = TRUE; parameters = frame[0] & 0x80; + + ASSERT(skb->len >= TTP_HEADER, return;); + skb_pull(skb, TTP_HEADER); + if (parameters) { plen = frame[1]; pi = frame[2]; @@ -789,17 +776,19 @@ void irttp_connect_confirm(void *instance, void *sap, struct qos_info *qos, DEBUG(4, __FUNCTION__ "(), RxMaxSduSize=%d\n", self->tx_max_sdu_size); + + /* Remove parameters */ + ASSERT(skb->len >= (plen+1), return;); + skb_pull(skb, plen+1); } DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n", self->send_credit, self->avail_credit, self->remote_credit); - skb_pull(skb, TTP_HEADER); - if (self->notify.connect_confirm) { - self->notify.connect_confirm(self->notify.instance, self, - qos, self->tx_max_sdu_size, - skb); + self->notify.connect_confirm(self->notify.instance, self, qos, + self->tx_max_sdu_size, + self->max_header_size, skb); } } @@ -809,8 +798,8 @@ void irttp_connect_confirm(void *instance, void *sap, struct qos_info *qos, * Some other device is connecting to this TSAP * */ -void irttp_connect_indication(void *instance, void *sap, - struct qos_info *qos, __u32 max_seg_size, +void irttp_connect_indication(void *instance, void *sap, struct qos_info *qos, + __u32 max_seg_size, __u8 max_header_size, struct sk_buff *skb) { struct tsap_cb *self; @@ -828,7 +817,9 @@ void irttp_connect_indication(void *instance, void *sap, lsap = (struct lsap_cb *) sap; - self->max_seg_size = max_seg_size-LMP_HEADER-LAP_HEADER; + self->max_seg_size = max_seg_size; + + self->max_header_size = max_header_size+TTP_HEADER; DEBUG(4, __FUNCTION__ "(), TSAP sel=%02x\n", self->stsap_sel); @@ -841,7 +832,11 @@ void irttp_connect_indication(void *instance, void *sap, self->send_credit = n; self->tx_max_sdu_size = 0; - parameters = frame[0] & 0x80; + parameters = frame[0] & 0x80; + + ASSERT(skb->len >= TTP_HEADER, return;); + skb_pull(skb, TTP_HEADER); + if (parameters) { DEBUG(3, __FUNCTION__ "(), Contains parameters!\n"); plen = frame[1]; @@ -850,7 +845,7 @@ void irttp_connect_indication(void *instance, void *sap, switch (pl) { case 1: - self->tx_max_sdu_size = *(frame+4); + self->tx_max_sdu_size = frame[4]; break; case 2: self->tx_max_sdu_size = @@ -865,7 +860,10 @@ void irttp_connect_indication(void *instance, void *sap, "() illegal value length for max_sdu_size!\n"); self->tx_max_sdu_size = 0; }; - + + /* Remove parameters */ + ASSERT(skb->len >= (plen+1), return;); + skb_pull(skb, plen+1); DEBUG(3, __FUNCTION__ "(), MaxSduSize=%d\n", self->tx_max_sdu_size); @@ -873,12 +871,10 @@ void irttp_connect_indication(void *instance, void *sap, DEBUG(4, __FUNCTION__ "(), initial send_credit=%d\n", n); - skb_pull(skb, 1); /* Remove TTP header */ - if (self->notify.connect_indication) { self->notify.connect_indication(self->notify.instance, self, qos, self->rx_max_sdu_size, - skb); + self->max_header_size, skb); } } @@ -909,15 +905,14 @@ void irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, return; /* Reserve space for MUX_CONTROL and LAP header */ - skb_reserve(skb, (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER)); + skb_reserve(skb, TTP_MAX_HEADER); } else { skb = userdata; /* * Check that the client has reserved enough space for * headers */ - ASSERT(skb_headroom(skb) >= - (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER), return;); + ASSERT(skb_headroom(skb) >= TTP_MAX_HEADER, return;); } self->avail_credit = 0; @@ -939,12 +934,11 @@ void irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, /* SAR enabled? */ if (max_sdu_size > 0) { - ASSERT(skb_headroom(skb) >= - (TTP_HEADER_WITH_SAR+LMP_CONTROL_HEADER+LAP_HEADER), + ASSERT(skb_headroom(skb) >= (TTP_MAX_HEADER+TTP_SAR_HEADER), return;); /* Insert TTP header with SAR parameters */ - frame = skb_push(skb, TTP_HEADER_WITH_SAR); + frame = skb_push(skb, TTP_HEADER+TTP_SAR_HEADER); frame[0] = TTP_PARAMETERS | n; frame[1] = 0x04; /* Length */ @@ -1079,7 +1073,7 @@ void irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata, /* * Reserve space for MUX and LAP header */ - skb_reserve(skb, LMP_CONTROL_HEADER+LAP_HEADER); + skb_reserve(skb, TTP_MAX_HEADER); userdata = skb; } @@ -1357,13 +1351,11 @@ static void irttp_fragment_skb(struct tsap_cb *self, struct sk_buff *skb) } /* Make new segment */ - frag = dev_alloc_skb(self->max_seg_size+ - TTP_HEADER+LMP_HEADER+ - LAP_HEADER); + frag = dev_alloc_skb(self->max_seg_size+self->max_header_size); if (!frag) return; - skb_reserve(frag, LMP_HEADER+LAP_HEADER); + skb_reserve(frag, self->max_header_size); /* * Copy data from the original skb into this fragment. We @@ -1401,11 +1393,9 @@ static void irttp_todo_expired(unsigned long data) irttp_run_tx_queue(self); /* Give avay some credits to peer? */ - if ((skb_queue_empty(&self->tx_queue)) && - (self->remote_credit < LOW_THRESHOLD) && - (self->avail_credit > 0)) + if ((self->remote_credit < LOW_THRESHOLD) && + (self->avail_credit > 0) && (skb_queue_empty(&self->tx_queue))) { - DEBUG(4, __FUNCTION__ "(), sending credit!\n"); irttp_give_credit(self); } |