summaryrefslogtreecommitdiffstats
path: root/net/irda/irttp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/irda/irttp.c')
-rw-r--r--net/irda/irttp.c156
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);
}