From: Denis KENZIOR <denis.kenzior@trolltech.com>
To: bluez-devel@lists.sourceforge.net
Subject: [Bluez-devel] [PATCH] Fixes for RFCOMM #2
Date: Fri, 20 Jun 2008 15:04:07 +1000 [thread overview]
Message-ID: <200806201504.07195.denis.kenzior@trolltech.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 492 bytes --]
rfcomm-keep-tty-data:
Fix the problem of disappearing packets when the socket is meant to be
used as an rfcomm tty server. The data needs to be queued since
packets might arrive after the socket has been connected, but
before the tty has been opened
Signed-off-by: Denis Kenzior <denis.kenzior@trolltech.com>
rfcomm-keep-modem-status:
Keep the modem status around in case the tty really needs it.
Signed-off-by: Denis Kenzior <denis.kenzior@trolltech.com>
[-- Attachment #2: rfcomm-keep-modem-status.patch --]
[-- Type: text/x-diff, Size: 1636 bytes --]
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 98ec7a3..d74094d 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -180,6 +180,7 @@ struct rfcomm_dlc {
u8 addr;
u8 priority;
u8 v24_sig;
+ u8 remote_v24_sig;
u8 mscex;
u32 link_mode;
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 0c2c937..2e37bb0 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1459,6 +1459,7 @@ static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb
clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
rfcomm_dlc_lock(d);
+ d->remote_v24_sig = msc->v24_sig;
if (d->modem_status)
d->modem_status(d, msc->v24_sig);
rfcomm_dlc_unlock(d);
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 2488027..41041ff 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -271,6 +271,9 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
dlc->owner = dev;
dev->dlc = dlc;
+
+ /* Update the modem_status, call under lock */
+ rfcomm_dev_modem_status(dlc, dlc->remote_v24_sig);
rfcomm_dlc_unlock(dlc);
/* It's safe to call __module_get() here because socket already
@@ -588,6 +591,7 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
}
}
+/* This is called under dlc lock, so we can safely mess with dlc here */
static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
{
struct rfcomm_dev *dev = dlc->owner;
[-- Attachment #3: rfcomm-keep-tty-data.patch --]
[-- Type: text/x-diff, Size: 3807 bytes --]
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 2e37bb0..a90fe94 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -457,7 +457,6 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
if (len > d->mtu)
return -EINVAL;
- rfcomm_make_uih(skb, d->addr);
skb_queue_tail(&d->tx_queue, skb);
if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags))
@@ -1675,6 +1674,7 @@ static inline int rfcomm_process_tx(struct rfcomm_dlc *d)
return skb_queue_len(&d->tx_queue);
while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) {
+ rfcomm_make_uih(skb, d->addr);
err = rfcomm_send_frame(d->session, skb->data, skb->len);
if (err < 0) {
skb_queue_head(&d->tx_queue, skb);
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 41041ff..0600c54 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -77,6 +77,8 @@ struct rfcomm_dev {
struct device *tty_dev;
atomic_t wmem_alloc;
+
+ struct sk_buff_head pending_queue;
};
static LIST_HEAD(rfcomm_dev_list);
@@ -88,6 +90,8 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
static void rfcomm_tty_wakeup(unsigned long arg);
+static void rfcomm_tty_copy_buffered(struct rfcomm_dev *dev);
+
/* ---- Device functions ---- */
static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
{
@@ -207,6 +211,8 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
struct rfcomm_dev *dev;
struct list_head *head = &rfcomm_dev_list, *p;
int err = 0;
+ struct sock *sk;
+ struct sk_buff *skb;
BT_DBG("id %d channel %d", req->dev_id, req->channel);
@@ -263,8 +269,19 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
init_waitqueue_head(&dev->wait);
tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev);
+ skb_queue_head_init(&dev->pending_queue);
rfcomm_dlc_lock(dlc);
+
+ if ((req->flags & (1 << RFCOMM_REUSE_DLC)) && (sk = dlc->owner)) {
+ rfcomm_dlc_throttle(dlc);
+ while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
+ skb_orphan(skb);
+ atomic_sub(skb->len, &sk->sk_rmem_alloc);
+ skb_queue_tail(&dev->pending_queue, skb);
+ }
+ }
+
dlc->data_ready = rfcomm_dev_data_ready;
dlc->state_change = rfcomm_dev_state_change;
dlc->modem_status = rfcomm_dev_modem_status;
@@ -542,11 +559,16 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
struct rfcomm_dev *dev = dlc->owner;
struct tty_struct *tty;
- if (!dev || !(tty = dev->tty)) {
+ if (!dev) {
kfree_skb(skb);
return;
}
+ if (!(tty = dev->tty) || !skb_queue_empty(&dev->pending_queue)) {
+ skb_queue_tail(&dev->pending_queue, skb);
+ return;
+ }
+
BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
tty_insert_flip_string(tty, skb->data, skb->len);
@@ -631,6 +653,33 @@ static void rfcomm_tty_wakeup(unsigned long arg)
#endif
}
+static void rfcomm_tty_copy_buffered(struct rfcomm_dev *dev)
+{
+ struct tty_struct *tty = dev->tty;
+ struct sk_buff *skb;
+ int inserted;
+
+ if (!tty)
+ return;
+
+ BT_DBG("dev %p tty %p", dev, tty);
+
+ rfcomm_dlc_lock(dev->dlc);
+
+ inserted = 0;
+ while ((skb = skb_dequeue(&dev->pending_queue))) {
+ inserted += tty_insert_flip_string(tty, skb->data, skb->len);
+ kfree_skb(skb);
+ }
+
+ rfcomm_dlc_unlock(dev->dlc);
+
+ if (inserted) {
+ tty_flip_buffer_push(tty);
+ rfcomm_dlc_unthrottle(dev->dlc);
+ }
+}
+
static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
{
DECLARE_WAITQUEUE(wait, current);
@@ -695,6 +744,8 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
if (err == 0)
device_move(dev->tty_dev, rfcomm_get_device(dev));
+ rfcomm_tty_copy_buffered(dev);
+
return err;
}
[-- Attachment #4: Type: text/plain, Size: 247 bytes --]
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
[-- Attachment #5: Type: text/plain, Size: 164 bytes --]
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel
reply other threads:[~2008-06-20 5:04 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200806201504.07195.denis.kenzior@trolltech.com \
--to=denis.kenzior@trolltech.com \
--cc=bluez-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox