blob: 6ea08b05b53a0ed19db047cc69c780aca7c05389 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 RFCOMM implementation for Linux Bluetooth stack (BlueZ).
3 Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
4 Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation;
9
10 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
13 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090014 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
15 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070017 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
20 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070021 SOFTWARE IS DISCLAIMED.
22*/
23
24/*
25 * RFCOMM TTY.
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 */
27
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/module.h>
29
30#include <linux/tty.h>
31#include <linux/tty_driver.h>
32#include <linux/tty_flip.h>
33
Linus Torvalds1da177e2005-04-16 15:20:36 -070034#include <net/bluetooth/bluetooth.h>
Marcel Holtmann0a85b962006-07-06 13:09:02 +020035#include <net/bluetooth/hci_core.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070036#include <net/bluetooth/rfcomm.h>
37
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#define RFCOMM_TTY_MAGIC 0x6d02 /* magic number for rfcomm struct */
39#define RFCOMM_TTY_PORTS RFCOMM_MAX_DEV /* whole lotta rfcomm devices */
40#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */
41#define RFCOMM_TTY_MINOR 0
42
43static struct tty_driver *rfcomm_tty_driver;
44
45struct rfcomm_dev {
Jiri Slabyf60db8c2012-04-02 13:54:50 +020046 struct tty_port port;
Linus Torvalds1da177e2005-04-16 15:20:36 -070047 struct list_head list;
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
49 char name[12];
50 int id;
51 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -070052 int err;
53
Peter Hurley1c648342014-02-09 20:59:07 -050054 unsigned long status; /* don't export to userspace */
55
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 bdaddr_t src;
57 bdaddr_t dst;
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020058 u8 channel;
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020060 uint modem_status;
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
62 struct rfcomm_dlc *dlc;
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
Marcel Holtmannc1a33132007-02-17 23:58:57 +010064 struct device *tty_dev;
65
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020066 atomic_t wmem_alloc;
Marcel Holtmanna0c22f22008-07-14 20:13:52 +020067
68 struct sk_buff_head pending;
Linus Torvalds1da177e2005-04-16 15:20:36 -070069};
70
71static LIST_HEAD(rfcomm_dev_list);
Gustavo F. Padovan393432c2011-12-27 15:28:45 -020072static DEFINE_SPINLOCK(rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070073
74static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
75static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
76static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
77
Linus Torvalds1da177e2005-04-16 15:20:36 -070078/* ---- Device functions ---- */
Jiri Slaby67054012012-04-02 13:54:51 +020079
Jiri Slaby67054012012-04-02 13:54:51 +020080static void rfcomm_dev_destruct(struct tty_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -070081{
Jiri Slaby67054012012-04-02 13:54:51 +020082 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
Linus Torvalds1da177e2005-04-16 15:20:36 -070083 struct rfcomm_dlc *dlc = dev->dlc;
84
85 BT_DBG("dev %p dlc %p", dev, dlc);
86
87 rfcomm_dlc_lock(dlc);
88 /* Detach DLC if it's owned by this dev */
89 if (dlc->owner == dev)
90 dlc->owner = NULL;
91 rfcomm_dlc_unlock(dlc);
92
93 rfcomm_dlc_put(dlc);
94
95 tty_unregister_device(rfcomm_tty_driver, dev->id);
96
Peter Hurleyc949c222014-02-09 20:59:09 -050097 spin_lock(&rfcomm_dev_lock);
98 list_del(&dev->list);
99 spin_unlock(&rfcomm_dev_lock);
100
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 kfree(dev);
102
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900103 /* It's safe to call module_put() here because socket still
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 holds reference to this module. */
105 module_put(THIS_MODULE);
106}
107
Gianluca Anzolincad348a2013-07-29 17:08:11 +0200108/* device-specific initialization: open the dlc */
109static int rfcomm_dev_activate(struct tty_port *port, struct tty_struct *tty)
110{
111 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
112
Peter Hurley136c3732014-02-09 20:59:02 -0500113 return rfcomm_dlc_open(dev->dlc, &dev->src, &dev->dst, dev->channel);
Gianluca Anzolincad348a2013-07-29 17:08:11 +0200114}
115
Peter Hurley7f717b92014-02-09 20:59:01 -0500116/* we block the open until the dlc->state becomes BT_CONNECTED */
117static int rfcomm_dev_carrier_raised(struct tty_port *port)
118{
119 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
120
121 return (dev->dlc->state == BT_CONNECTED);
122}
123
Gianluca Anzolincad348a2013-07-29 17:08:11 +0200124/* device-specific cleanup: close the dlc */
125static void rfcomm_dev_shutdown(struct tty_port *port)
126{
127 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
128
129 if (dev->tty_dev->parent)
130 device_move(dev->tty_dev, NULL, DPM_ORDER_DEV_LAST);
131
132 /* close the dlc */
133 rfcomm_dlc_close(dev->dlc, 0);
134}
135
Jiri Slaby67054012012-04-02 13:54:51 +0200136static const struct tty_port_operations rfcomm_port_ops = {
137 .destruct = rfcomm_dev_destruct,
Gianluca Anzolincad348a2013-07-29 17:08:11 +0200138 .activate = rfcomm_dev_activate,
139 .shutdown = rfcomm_dev_shutdown,
Peter Hurley136c3732014-02-09 20:59:02 -0500140 .carrier_raised = rfcomm_dev_carrier_raised,
Jiri Slaby67054012012-04-02 13:54:51 +0200141};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142
143static struct rfcomm_dev *__rfcomm_dev_get(int id)
144{
145 struct rfcomm_dev *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200147 list_for_each_entry(dev, &rfcomm_dev_list, list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 if (dev->id == id)
149 return dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150
151 return NULL;
152}
153
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300154static struct rfcomm_dev *rfcomm_dev_get(int id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155{
156 struct rfcomm_dev *dev;
157
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200158 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159
160 dev = __rfcomm_dev_get(id);
Ville Tervo8de0a152007-07-11 09:23:41 +0200161
Peter Hurley082a1532014-02-09 20:59:05 -0500162 if (dev && !tty_port_get(&dev->port))
163 dev = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200165 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166
167 return dev;
168}
169
Peter Hurleyf87c24e2014-02-09 20:59:03 -0500170static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
171{
172 struct hci_dev *hdev;
173 struct hci_conn *conn;
174
175 hdev = hci_get_route(&dev->dst, &dev->src);
176 if (!hdev)
177 return NULL;
178
179 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
180
181 hci_dev_put(hdev);
182
183 return conn ? &conn->dev : NULL;
184}
185
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200186static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
187{
188 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +0300189 return sprintf(buf, "%pMR\n", &dev->dst);
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200190}
191
192static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf)
193{
194 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
195 return sprintf(buf, "%d\n", dev->channel);
196}
197
198static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
199static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
200
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
202{
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200203 struct rfcomm_dev *dev, *entry;
Luiz Augusto von Dentze57d758a2012-03-07 20:20:14 +0200204 struct list_head *head = &rfcomm_dev_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 int err = 0;
206
207 BT_DBG("id %d channel %d", req->dev_id, req->channel);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900208
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200209 dev = kzalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 if (!dev)
211 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200213 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214
215 if (req->dev_id < 0) {
216 dev->id = 0;
217
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200218 list_for_each_entry(entry, &rfcomm_dev_list, list) {
219 if (entry->id != dev->id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 break;
221
222 dev->id++;
Luiz Augusto von Dentze57d758a2012-03-07 20:20:14 +0200223 head = &entry->list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 }
225 } else {
226 dev->id = req->dev_id;
227
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200228 list_for_each_entry(entry, &rfcomm_dev_list, list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 if (entry->id == dev->id) {
230 err = -EADDRINUSE;
231 goto out;
232 }
233
234 if (entry->id > dev->id - 1)
235 break;
236
Luiz Augusto von Dentze57d758a2012-03-07 20:20:14 +0200237 head = &entry->list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238 }
239 }
240
241 if ((dev->id < 0) || (dev->id > RFCOMM_MAX_DEV - 1)) {
242 err = -ENFILE;
243 goto out;
244 }
245
246 sprintf(dev->name, "rfcomm%d", dev->id);
247
248 list_add(&dev->list, head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249
250 bacpy(&dev->src, &req->src);
251 bacpy(&dev->dst, &req->dst);
252 dev->channel = req->channel;
253
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900254 dev->flags = req->flags &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255 ((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
256
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200257 tty_port_init(&dev->port);
Jiri Slaby67054012012-04-02 13:54:51 +0200258 dev->port.ops = &rfcomm_port_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200260 skb_queue_head_init(&dev->pending);
261
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 rfcomm_dlc_lock(dlc);
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200263
264 if (req->flags & (1 << RFCOMM_REUSE_DLC)) {
265 struct sock *sk = dlc->owner;
266 struct sk_buff *skb;
267
268 BUG_ON(!sk);
269
270 rfcomm_dlc_throttle(dlc);
271
272 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
273 skb_orphan(skb);
274 skb_queue_tail(&dev->pending, skb);
275 atomic_sub(skb->len, &sk->sk_rmem_alloc);
276 }
277 }
278
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 dlc->data_ready = rfcomm_dev_data_ready;
280 dlc->state_change = rfcomm_dev_state_change;
281 dlc->modem_status = rfcomm_dev_modem_status;
282
283 dlc->owner = dev;
284 dev->dlc = dlc;
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +0200285
286 rfcomm_dev_modem_status(dlc, dlc->remote_v24_sig);
287
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 rfcomm_dlc_unlock(dlc);
289
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900290 /* It's safe to call __module_get() here because socket already
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 holds reference to this module. */
292 __module_get(THIS_MODULE);
293
294out:
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200295 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800297 if (err < 0)
298 goto free;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299
Jiri Slaby734cc172012-08-07 21:47:47 +0200300 dev->tty_dev = tty_port_register_device(&dev->port, rfcomm_tty_driver,
301 dev->id, NULL);
Ville Tervo8de0a152007-07-11 09:23:41 +0200302 if (IS_ERR(dev->tty_dev)) {
Marcel Holtmann09c7d822007-07-26 00:12:25 -0700303 err = PTR_ERR(dev->tty_dev);
Gianluca Anzolinebe937f2013-07-29 17:08:09 +0200304 spin_lock(&rfcomm_dev_lock);
Ville Tervo8de0a152007-07-11 09:23:41 +0200305 list_del(&dev->list);
Gianluca Anzolinebe937f2013-07-29 17:08:09 +0200306 spin_unlock(&rfcomm_dev_lock);
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800307 goto free;
Ville Tervo8de0a152007-07-11 09:23:41 +0200308 }
309
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200310 dev_set_drvdata(dev->tty_dev, dev);
311
312 if (device_create_file(dev->tty_dev, &dev_attr_address) < 0)
313 BT_ERR("Failed to create address attribute");
314
315 if (device_create_file(dev->tty_dev, &dev_attr_channel) < 0)
316 BT_ERR("Failed to create channel attribute");
317
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 return dev->id;
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800319
320free:
321 kfree(dev);
322 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323}
324
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325/* ---- Send buffer ---- */
326static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
327{
328 /* We can't let it be zero, because we don't get a callback
329 when tx_credits becomes nonzero, hence we'd never wake up */
330 return dlc->mtu * (dlc->tx_credits?:1);
331}
332
333static void rfcomm_wfree(struct sk_buff *skb)
334{
335 struct rfcomm_dev *dev = (void *) skb->sk;
336 atomic_sub(skb->truesize, &dev->wmem_alloc);
Gianluca Anzolin396dc222013-07-29 17:08:08 +0200337 if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
338 tty_port_tty_wakeup(&dev->port);
Jiri Slaby67054012012-04-02 13:54:51 +0200339 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340}
341
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300342static void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343{
Jiri Slaby67054012012-04-02 13:54:51 +0200344 tty_port_get(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 atomic_add(skb->truesize, &dev->wmem_alloc);
346 skb->sk = (void *) dev;
347 skb->destructor = rfcomm_wfree;
348}
349
Al Virodd0fc662005-10-07 07:46:04 +0100350static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351{
352 if (atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
353 struct sk_buff *skb = alloc_skb(size, priority);
354 if (skb) {
355 rfcomm_set_owner_w(skb, dev);
356 return skb;
357 }
358 }
359 return NULL;
360}
361
362/* ---- Device IOCTLs ---- */
363
364#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
365
366static int rfcomm_create_dev(struct sock *sk, void __user *arg)
367{
368 struct rfcomm_dev_req req;
369 struct rfcomm_dlc *dlc;
370 int id;
371
372 if (copy_from_user(&req, arg, sizeof(req)))
373 return -EFAULT;
374
Ville Tervo8de0a152007-07-11 09:23:41 +0200375 BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376
377 if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
378 return -EPERM;
379
380 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
381 /* Socket must be connected */
382 if (sk->sk_state != BT_CONNECTED)
383 return -EBADFD;
384
385 dlc = rfcomm_pi(sk)->dlc;
386 rfcomm_dlc_hold(dlc);
387 } else {
388 dlc = rfcomm_dlc_alloc(GFP_KERNEL);
389 if (!dlc)
390 return -ENOMEM;
391 }
392
393 id = rfcomm_dev_add(&req, dlc);
394 if (id < 0) {
395 rfcomm_dlc_put(dlc);
396 return id;
397 }
398
399 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
400 /* DLC is now used by device.
401 * Socket must be disconnected */
402 sk->sk_state = BT_CLOSED;
403 }
404
405 return id;
406}
407
408static int rfcomm_release_dev(void __user *arg)
409{
410 struct rfcomm_dev_req req;
411 struct rfcomm_dev *dev;
Gianluca Anzolin396dc222013-07-29 17:08:08 +0200412 struct tty_struct *tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413
414 if (copy_from_user(&req, arg, sizeof(req)))
415 return -EFAULT;
416
Ville Tervo8de0a152007-07-11 09:23:41 +0200417 BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200419 dev = rfcomm_dev_get(req.dev_id);
420 if (!dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 return -ENODEV;
422
423 if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
Jiri Slaby67054012012-04-02 13:54:51 +0200424 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 return -EPERM;
426 }
427
Peter Hurley1c648342014-02-09 20:59:07 -0500428 /* only release once */
429 if (test_and_set_bit(RFCOMM_DEV_RELEASED, &dev->status)) {
430 tty_port_put(&dev->port);
431 return -EALREADY;
432 }
433
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 if (req.flags & (1 << RFCOMM_HANGUP_NOW))
435 rfcomm_dlc_close(dev->dlc, 0);
436
Mikko Rapeli84950cf2007-07-11 09:18:15 +0200437 /* Shut down TTY synchronously before freeing rfcomm_dev */
Gianluca Anzolin396dc222013-07-29 17:08:08 +0200438 tty = tty_port_tty_get(&dev->port);
439 if (tty) {
440 tty_vhangup(tty);
441 tty_kref_put(tty);
442 }
Mikko Rapeli84950cf2007-07-11 09:18:15 +0200443
Peter Hurley80ea7332014-02-09 20:59:08 -0500444 if (!test_bit(RFCOMM_TTY_OWNED, &dev->status))
Gianluca Anzolinece31502013-07-29 17:08:12 +0200445 tty_port_put(&dev->port);
446
Jiri Slaby67054012012-04-02 13:54:51 +0200447 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 return 0;
449}
450
451static int rfcomm_get_dev_list(void __user *arg)
452{
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200453 struct rfcomm_dev *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454 struct rfcomm_dev_list_req *dl;
455 struct rfcomm_dev_info *di;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456 int n = 0, size, err;
457 u16 dev_num;
458
459 BT_DBG("");
460
461 if (get_user(dev_num, (u16 __user *) arg))
462 return -EFAULT;
463
464 if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di))
465 return -EINVAL;
466
467 size = sizeof(*dl) + dev_num * sizeof(*di);
468
Mathias Krausef9432c52012-08-15 11:31:49 +0000469 dl = kzalloc(size, GFP_KERNEL);
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200470 if (!dl)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 return -ENOMEM;
472
473 di = dl->dev_info;
474
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200475 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200477 list_for_each_entry(dev, &rfcomm_dev_list, list) {
Peter Hurley960603a2014-02-09 20:59:06 -0500478 if (!tty_port_get(&dev->port))
Ville Tervo8de0a152007-07-11 09:23:41 +0200479 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 (di + n)->id = dev->id;
481 (di + n)->flags = dev->flags;
482 (di + n)->state = dev->dlc->state;
483 (di + n)->channel = dev->channel;
484 bacpy(&(di + n)->src, &dev->src);
485 bacpy(&(di + n)->dst, &dev->dst);
Peter Hurley960603a2014-02-09 20:59:06 -0500486 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 if (++n >= dev_num)
488 break;
489 }
490
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200491 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492
493 dl->dev_num = n;
494 size = sizeof(*dl) + n * sizeof(*di);
495
496 err = copy_to_user(arg, dl, size);
497 kfree(dl);
498
499 return err ? -EFAULT : 0;
500}
501
502static int rfcomm_get_dev_info(void __user *arg)
503{
504 struct rfcomm_dev *dev;
505 struct rfcomm_dev_info di;
506 int err = 0;
507
508 BT_DBG("");
509
510 if (copy_from_user(&di, arg, sizeof(di)))
511 return -EFAULT;
512
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200513 dev = rfcomm_dev_get(di.id);
514 if (!dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 return -ENODEV;
516
517 di.flags = dev->flags;
518 di.channel = dev->channel;
519 di.state = dev->dlc->state;
520 bacpy(&di.src, &dev->src);
521 bacpy(&di.dst, &dev->dst);
522
523 if (copy_to_user(arg, &di, sizeof(di)))
524 err = -EFAULT;
525
Jiri Slaby67054012012-04-02 13:54:51 +0200526 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 return err;
528}
529
530int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
531{
532 BT_DBG("cmd %d arg %p", cmd, arg);
533
534 switch (cmd) {
535 case RFCOMMCREATEDEV:
536 return rfcomm_create_dev(sk, arg);
537
538 case RFCOMMRELEASEDEV:
539 return rfcomm_release_dev(arg);
540
541 case RFCOMMGETDEVLIST:
542 return rfcomm_get_dev_list(arg);
543
544 case RFCOMMGETDEVINFO:
545 return rfcomm_get_dev_info(arg);
546 }
547
548 return -EINVAL;
549}
550
551/* ---- DLC callbacks ---- */
552static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
553{
554 struct rfcomm_dev *dev = dlc->owner;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900555
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200556 if (!dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 kfree_skb(skb);
558 return;
559 }
560
Jiri Slaby2e124b42013-01-03 15:53:06 +0100561 if (!skb_queue_empty(&dev->pending)) {
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200562 skb_queue_tail(&dev->pending, skb);
563 return;
564 }
565
Jiri Slaby2e124b42013-01-03 15:53:06 +0100566 BT_DBG("dlc %p len %d", dlc, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567
Jiri Slaby05c7cd32013-01-03 15:53:04 +0100568 tty_insert_flip_string(&dev->port, skb->data, skb->len);
Jiri Slaby2e124b42013-01-03 15:53:06 +0100569 tty_flip_buffer_push(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570
571 kfree_skb(skb);
572}
573
574static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
575{
576 struct rfcomm_dev *dev = dlc->owner;
577 if (!dev)
578 return;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900579
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
581
582 dev->err = err;
Peter Hurley136c3732014-02-09 20:59:02 -0500583 if (dlc->state == BT_CONNECTED) {
584 device_move(dev->tty_dev, rfcomm_get_device(dev),
585 DPM_ORDER_DEV_AFTER_PARENT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586
Peter Hurley136c3732014-02-09 20:59:02 -0500587 wake_up_interruptible(&dev->port.open_wait);
588 } else if (dlc->state == BT_CLOSED)
Gianluca Anzolin29cd7182013-08-27 18:28:46 +0200589 tty_port_tty_hangup(&dev->port, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590}
591
592static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
593{
594 struct rfcomm_dev *dev = dlc->owner;
595 if (!dev)
596 return;
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700597
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
599
Gianluca Anzolin396dc222013-07-29 17:08:08 +0200600 if ((dev->modem_status & TIOCM_CD) && !(v24_sig & RFCOMM_V24_DV))
601 tty_port_tty_hangup(&dev->port, true);
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700602
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900603 dev->modem_status =
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 ((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
605 ((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
606 ((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
607 ((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
608}
609
610/* ---- TTY functions ---- */
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200611static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev)
612{
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200613 struct sk_buff *skb;
614 int inserted = 0;
615
Jiri Slaby2e124b42013-01-03 15:53:06 +0100616 BT_DBG("dev %p", dev);
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200617
618 rfcomm_dlc_lock(dev->dlc);
619
620 while ((skb = skb_dequeue(&dev->pending))) {
Jiri Slaby05c7cd32013-01-03 15:53:04 +0100621 inserted += tty_insert_flip_string(&dev->port, skb->data,
622 skb->len);
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200623 kfree_skb(skb);
624 }
625
626 rfcomm_dlc_unlock(dev->dlc);
627
628 if (inserted > 0)
Jiri Slaby2e124b42013-01-03 15:53:06 +0100629 tty_flip_buffer_push(&dev->port);
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200630}
631
Gianluca Anzolin54b926a2013-07-29 17:08:10 +0200632/* do the reverse of install, clearing the tty fields and releasing the
633 * reference to tty_port
634 */
635static void rfcomm_tty_cleanup(struct tty_struct *tty)
636{
637 struct rfcomm_dev *dev = tty->driver_data;
638
Gianluca Anzolin54b926a2013-07-29 17:08:10 +0200639 clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
640
641 rfcomm_dlc_lock(dev->dlc);
642 tty->driver_data = NULL;
Gianluca Anzolin54b926a2013-07-29 17:08:10 +0200643 rfcomm_dlc_unlock(dev->dlc);
644
Gianluca Anzolinffe6b682013-07-29 17:08:13 +0200645 /*
646 * purge the dlc->tx_queue to avoid circular dependencies
647 * between dev and dlc
648 */
649 skb_queue_purge(&dev->dlc->tx_queue);
650
Gianluca Anzolin54b926a2013-07-29 17:08:10 +0200651 tty_port_put(&dev->port);
652}
653
654/* we acquire the tty_port reference since it's here the tty is first used
655 * by setting the termios. We also populate the driver_data field and install
656 * the tty port
657 */
658static int rfcomm_tty_install(struct tty_driver *driver, struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 struct rfcomm_dev *dev;
661 struct rfcomm_dlc *dlc;
Gianluca Anzolin54b926a2013-07-29 17:08:10 +0200662 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663
Gianluca Anzolin54b926a2013-07-29 17:08:10 +0200664 dev = rfcomm_dev_get(tty->index);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 if (!dev)
666 return -ENODEV;
667
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 dlc = dev->dlc;
669
670 /* Attach TTY and open DLC */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 rfcomm_dlc_lock(dlc);
672 tty->driver_data = dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 rfcomm_dlc_unlock(dlc);
674 set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
675
Gianluca Anzolin54b926a2013-07-29 17:08:10 +0200676 /* install the tty_port */
677 err = tty_port_install(&dev->port, driver, tty);
Gianluca Anzolin5b899242014-01-06 21:23:50 +0100678 if (err) {
Gianluca Anzolincad348a2013-07-29 17:08:11 +0200679 rfcomm_tty_cleanup(tty);
Gianluca Anzolin5b899242014-01-06 21:23:50 +0100680 return err;
681 }
Gianluca Anzolin54b926a2013-07-29 17:08:10 +0200682
Gianluca Anzolin5b899242014-01-06 21:23:50 +0100683 /* take over the tty_port reference if the port was created with the
684 * flag RFCOMM_RELEASE_ONHUP. This will force the release of the port
685 * when the last process closes the tty. The behaviour is expected by
686 * userspace.
687 */
Peter Hurley80ea7332014-02-09 20:59:08 -0500688 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
689 set_bit(RFCOMM_TTY_OWNED, &dev->status);
Gianluca Anzolin5b899242014-01-06 21:23:50 +0100690 tty_port_put(&dev->port);
Peter Hurley80ea7332014-02-09 20:59:08 -0500691 }
Gianluca Anzolin5b899242014-01-06 21:23:50 +0100692
693 return 0;
Gianluca Anzolin54b926a2013-07-29 17:08:10 +0200694}
695
696static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
697{
698 struct rfcomm_dev *dev = tty->driver_data;
Gianluca Anzolincad348a2013-07-29 17:08:11 +0200699 int err;
Gianluca Anzolin54b926a2013-07-29 17:08:10 +0200700
701 BT_DBG("tty %p id %d", tty, tty->index);
702
703 BT_DBG("dev %p dst %pMR channel %d opened %d", dev, &dev->dst,
704 dev->channel, dev->port.count);
705
Gianluca Anzolincad348a2013-07-29 17:08:11 +0200706 err = tty_port_open(&dev->port, tty, filp);
707 if (err)
708 return err;
Gianluca Anzolin54b926a2013-07-29 17:08:10 +0200709
710 /*
711 * FIXME: rfcomm should use proper flow control for
712 * received data. This hack will be unnecessary and can
713 * be removed when that's implemented
714 */
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200715 rfcomm_tty_copy_pending(dev);
716
717 rfcomm_dlc_unthrottle(dev->dlc);
718
Gianluca Anzolin54b926a2013-07-29 17:08:10 +0200719 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720}
721
722static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
723{
724 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Jiri Slabyf997a012012-04-02 13:54:53 +0200725
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100726 BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc,
Jiri Slabyf997a012012-04-02 13:54:53 +0200727 dev->port.count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728
Gianluca Anzolincad348a2013-07-29 17:08:11 +0200729 tty_port_close(&dev->port, tty, filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730}
731
732static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
733{
734 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
735 struct rfcomm_dlc *dlc = dev->dlc;
736 struct sk_buff *skb;
737 int err = 0, sent = 0, size;
738
739 BT_DBG("tty %p count %d", tty, count);
740
741 while (count) {
742 size = min_t(uint, count, dlc->mtu);
743
744 skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900745
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 if (!skb)
747 break;
748
749 skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
750
751 memcpy(skb_put(skb, size), buf + sent, size);
752
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200753 err = rfcomm_dlc_send(dlc, skb);
754 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 kfree_skb(skb);
756 break;
757 }
758
759 sent += size;
760 count -= size;
761 }
762
763 return sent ? sent : err;
764}
765
766static int rfcomm_tty_write_room(struct tty_struct *tty)
767{
768 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
769 int room;
770
771 BT_DBG("tty %p", tty);
772
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100773 if (!dev || !dev->dlc)
774 return 0;
775
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
777 if (room < 0)
778 room = 0;
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100779
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 return room;
781}
782
Alan Cox6caa76b2011-02-14 16:27:22 +0000783static int rfcomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784{
785 BT_DBG("tty %p cmd 0x%02x", tty, cmd);
786
787 switch (cmd) {
788 case TCGETS:
789 BT_DBG("TCGETS is not supported");
790 return -ENOIOCTLCMD;
791
792 case TCSETS:
793 BT_DBG("TCSETS is not supported");
794 return -ENOIOCTLCMD;
795
796 case TIOCMIWAIT:
797 BT_DBG("TIOCMIWAIT");
798 break;
799
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 case TIOCGSERIAL:
801 BT_ERR("TIOCGSERIAL is not supported");
802 return -ENOIOCTLCMD;
803
804 case TIOCSSERIAL:
805 BT_ERR("TIOCSSERIAL is not supported");
806 return -ENOIOCTLCMD;
807
808 case TIOCSERGSTRUCT:
809 BT_ERR("TIOCSERGSTRUCT is not supported");
810 return -ENOIOCTLCMD;
811
812 case TIOCSERGETLSR:
813 BT_ERR("TIOCSERGETLSR is not supported");
814 return -ENOIOCTLCMD;
815
816 case TIOCSERCONFIG:
817 BT_ERR("TIOCSERCONFIG is not supported");
818 return -ENOIOCTLCMD;
819
820 default:
821 return -ENOIOCTLCMD; /* ioctls which we must ignore */
822
823 }
824
825 return -ENOIOCTLCMD;
826}
827
Alan Cox606d0992006-12-08 02:38:45 -0800828static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829{
Alan Coxadc8d742012-07-14 15:31:47 +0100830 struct ktermios *new = &tty->termios;
J. Suter3a5e9032005-08-09 20:28:46 -0700831 int old_baud_rate = tty_termios_baud_rate(old);
832 int new_baud_rate = tty_termios_baud_rate(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833
J. Suter3a5e9032005-08-09 20:28:46 -0700834 u8 baud, data_bits, stop_bits, parity, x_on, x_off;
835 u16 changes = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836
J. Suter3a5e9032005-08-09 20:28:46 -0700837 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
838
839 BT_DBG("tty %p termios %p", tty, old);
840
Marcel Holtmannff2d3672006-11-18 22:14:42 +0100841 if (!dev || !dev->dlc || !dev->dlc->session)
Marcel Holtmanncb19d9e2006-10-15 17:31:10 +0200842 return;
843
J. Suter3a5e9032005-08-09 20:28:46 -0700844 /* Handle turning off CRTSCTS */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900845 if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
J. Suter3a5e9032005-08-09 20:28:46 -0700846 BT_DBG("Turning off CRTSCTS unsupported");
847
848 /* Parity on/off and when on, odd/even */
849 if (((old->c_cflag & PARENB) != (new->c_cflag & PARENB)) ||
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200850 ((old->c_cflag & PARODD) != (new->c_cflag & PARODD))) {
J. Suter3a5e9032005-08-09 20:28:46 -0700851 changes |= RFCOMM_RPN_PM_PARITY;
852 BT_DBG("Parity change detected.");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 }
J. Suter3a5e9032005-08-09 20:28:46 -0700854
855 /* Mark and space parity are not supported! */
856 if (new->c_cflag & PARENB) {
857 if (new->c_cflag & PARODD) {
858 BT_DBG("Parity is ODD");
859 parity = RFCOMM_RPN_PARITY_ODD;
860 } else {
861 BT_DBG("Parity is EVEN");
862 parity = RFCOMM_RPN_PARITY_EVEN;
863 }
864 } else {
865 BT_DBG("Parity is OFF");
866 parity = RFCOMM_RPN_PARITY_NONE;
867 }
868
869 /* Setting the x_on / x_off characters */
870 if (old->c_cc[VSTOP] != new->c_cc[VSTOP]) {
871 BT_DBG("XOFF custom");
872 x_on = new->c_cc[VSTOP];
873 changes |= RFCOMM_RPN_PM_XON;
874 } else {
875 BT_DBG("XOFF default");
876 x_on = RFCOMM_RPN_XON_CHAR;
877 }
878
879 if (old->c_cc[VSTART] != new->c_cc[VSTART]) {
880 BT_DBG("XON custom");
881 x_off = new->c_cc[VSTART];
882 changes |= RFCOMM_RPN_PM_XOFF;
883 } else {
884 BT_DBG("XON default");
885 x_off = RFCOMM_RPN_XOFF_CHAR;
886 }
887
888 /* Handle setting of stop bits */
889 if ((old->c_cflag & CSTOPB) != (new->c_cflag & CSTOPB))
890 changes |= RFCOMM_RPN_PM_STOP;
891
892 /* POSIX does not support 1.5 stop bits and RFCOMM does not
893 * support 2 stop bits. So a request for 2 stop bits gets
894 * translated to 1.5 stop bits */
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200895 if (new->c_cflag & CSTOPB)
J. Suter3a5e9032005-08-09 20:28:46 -0700896 stop_bits = RFCOMM_RPN_STOP_15;
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200897 else
J. Suter3a5e9032005-08-09 20:28:46 -0700898 stop_bits = RFCOMM_RPN_STOP_1;
J. Suter3a5e9032005-08-09 20:28:46 -0700899
900 /* Handle number of data bits [5-8] */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900901 if ((old->c_cflag & CSIZE) != (new->c_cflag & CSIZE))
J. Suter3a5e9032005-08-09 20:28:46 -0700902 changes |= RFCOMM_RPN_PM_DATA;
903
904 switch (new->c_cflag & CSIZE) {
905 case CS5:
906 data_bits = RFCOMM_RPN_DATA_5;
907 break;
908 case CS6:
909 data_bits = RFCOMM_RPN_DATA_6;
910 break;
911 case CS7:
912 data_bits = RFCOMM_RPN_DATA_7;
913 break;
914 case CS8:
915 data_bits = RFCOMM_RPN_DATA_8;
916 break;
917 default:
918 data_bits = RFCOMM_RPN_DATA_8;
919 break;
920 }
921
922 /* Handle baudrate settings */
923 if (old_baud_rate != new_baud_rate)
924 changes |= RFCOMM_RPN_PM_BITRATE;
925
926 switch (new_baud_rate) {
927 case 2400:
928 baud = RFCOMM_RPN_BR_2400;
929 break;
930 case 4800:
931 baud = RFCOMM_RPN_BR_4800;
932 break;
933 case 7200:
934 baud = RFCOMM_RPN_BR_7200;
935 break;
936 case 9600:
937 baud = RFCOMM_RPN_BR_9600;
938 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900939 case 19200:
J. Suter3a5e9032005-08-09 20:28:46 -0700940 baud = RFCOMM_RPN_BR_19200;
941 break;
942 case 38400:
943 baud = RFCOMM_RPN_BR_38400;
944 break;
945 case 57600:
946 baud = RFCOMM_RPN_BR_57600;
947 break;
948 case 115200:
949 baud = RFCOMM_RPN_BR_115200;
950 break;
951 case 230400:
952 baud = RFCOMM_RPN_BR_230400;
953 break;
954 default:
955 /* 9600 is standard accordinag to the RFCOMM specification */
956 baud = RFCOMM_RPN_BR_9600;
957 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900958
J. Suter3a5e9032005-08-09 20:28:46 -0700959 }
960
961 if (changes)
962 rfcomm_send_rpn(dev->dlc->session, 1, dev->dlc->dlci, baud,
963 data_bits, stop_bits, parity,
964 RFCOMM_RPN_FLOW_NONE, x_on, x_off, changes);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965}
966
967static void rfcomm_tty_throttle(struct tty_struct *tty)
968{
969 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
970
971 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -0700972
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 rfcomm_dlc_throttle(dev->dlc);
974}
975
976static void rfcomm_tty_unthrottle(struct tty_struct *tty)
977{
978 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
979
980 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -0700981
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982 rfcomm_dlc_unthrottle(dev->dlc);
983}
984
985static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
986{
987 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988
989 BT_DBG("tty %p dev %p", tty, dev);
990
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100991 if (!dev || !dev->dlc)
992 return 0;
993
994 if (!skb_queue_empty(&dev->dlc->tx_queue))
995 return dev->dlc->mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996
997 return 0;
998}
999
1000static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
1001{
1002 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003
1004 BT_DBG("tty %p dev %p", tty, dev);
1005
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001006 if (!dev || !dev->dlc)
1007 return;
1008
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009 skb_queue_purge(&dev->dlc->tx_queue);
Alan Coxa352def2008-07-16 21:53:12 +01001010 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011}
1012
1013static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
1014{
1015 BT_DBG("tty %p ch %c", tty, ch);
1016}
1017
1018static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
1019{
1020 BT_DBG("tty %p timeout %d", tty, timeout);
1021}
1022
1023static void rfcomm_tty_hangup(struct tty_struct *tty)
1024{
1025 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026
1027 BT_DBG("tty %p dev %p", tty, dev);
1028
Gianluca Anzolincad348a2013-07-29 17:08:11 +02001029 tty_port_hangup(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030}
1031
Alan Cox60b33c12011-02-14 16:26:14 +00001032static int rfcomm_tty_tiocmget(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001034 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035
1036 BT_DBG("tty %p dev %p", tty, dev);
1037
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001038 return dev->modem_status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039}
1040
Alan Cox20b9d172011-02-14 16:26:50 +00001041static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042{
J. Suter3a5e9032005-08-09 20:28:46 -07001043 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1044 struct rfcomm_dlc *dlc = dev->dlc;
1045 u8 v24_sig;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046
1047 BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear);
1048
J. Suter3a5e9032005-08-09 20:28:46 -07001049 rfcomm_dlc_get_modem_status(dlc, &v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050
J. Suter3a5e9032005-08-09 20:28:46 -07001051 if (set & TIOCM_DSR || set & TIOCM_DTR)
1052 v24_sig |= RFCOMM_V24_RTC;
1053 if (set & TIOCM_RTS || set & TIOCM_CTS)
1054 v24_sig |= RFCOMM_V24_RTR;
1055 if (set & TIOCM_RI)
1056 v24_sig |= RFCOMM_V24_IC;
1057 if (set & TIOCM_CD)
1058 v24_sig |= RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059
J. Suter3a5e9032005-08-09 20:28:46 -07001060 if (clear & TIOCM_DSR || clear & TIOCM_DTR)
1061 v24_sig &= ~RFCOMM_V24_RTC;
1062 if (clear & TIOCM_RTS || clear & TIOCM_CTS)
1063 v24_sig &= ~RFCOMM_V24_RTR;
1064 if (clear & TIOCM_RI)
1065 v24_sig &= ~RFCOMM_V24_IC;
1066 if (clear & TIOCM_CD)
1067 v24_sig &= ~RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
J. Suter3a5e9032005-08-09 20:28:46 -07001069 rfcomm_dlc_set_modem_status(dlc, v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070
J. Suter3a5e9032005-08-09 20:28:46 -07001071 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072}
1073
1074/* ---- TTY structure ---- */
1075
Jeff Dikeb68e31d2006-10-02 02:17:18 -07001076static const struct tty_operations rfcomm_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 .open = rfcomm_tty_open,
1078 .close = rfcomm_tty_close,
1079 .write = rfcomm_tty_write,
1080 .write_room = rfcomm_tty_write_room,
1081 .chars_in_buffer = rfcomm_tty_chars_in_buffer,
1082 .flush_buffer = rfcomm_tty_flush_buffer,
1083 .ioctl = rfcomm_tty_ioctl,
1084 .throttle = rfcomm_tty_throttle,
1085 .unthrottle = rfcomm_tty_unthrottle,
1086 .set_termios = rfcomm_tty_set_termios,
1087 .send_xchar = rfcomm_tty_send_xchar,
1088 .hangup = rfcomm_tty_hangup,
1089 .wait_until_sent = rfcomm_tty_wait_until_sent,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090 .tiocmget = rfcomm_tty_tiocmget,
1091 .tiocmset = rfcomm_tty_tiocmset,
Gianluca Anzolin54b926a2013-07-29 17:08:10 +02001092 .install = rfcomm_tty_install,
1093 .cleanup = rfcomm_tty_cleanup,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094};
1095
Gustavo F. Padovan2f8362a2010-07-24 02:04:45 -03001096int __init rfcomm_init_ttys(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097{
David Herrmann5ada9912011-10-24 15:30:57 +02001098 int error;
1099
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS);
1101 if (!rfcomm_tty_driver)
David Herrmann5ada9912011-10-24 15:30:57 +02001102 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104 rfcomm_tty_driver->driver_name = "rfcomm";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105 rfcomm_tty_driver->name = "rfcomm";
1106 rfcomm_tty_driver->major = RFCOMM_TTY_MAJOR;
1107 rfcomm_tty_driver->minor_start = RFCOMM_TTY_MINOR;
1108 rfcomm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
1109 rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
Greg Kroah-Hartman331b8312005-06-20 21:15:16 -07001110 rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 rfcomm_tty_driver->init_termios = tty_std_termios;
Peter Hurley136c3732014-02-09 20:59:02 -05001112 rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
Marcel Holtmannca37bdd2008-07-14 20:13:52 +02001113 rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
1115
David Herrmann5ada9912011-10-24 15:30:57 +02001116 error = tty_register_driver(rfcomm_tty_driver);
1117 if (error) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 BT_ERR("Can't register RFCOMM TTY driver");
1119 put_tty_driver(rfcomm_tty_driver);
David Herrmann5ada9912011-10-24 15:30:57 +02001120 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 }
1122
1123 BT_INFO("RFCOMM TTY layer initialized");
1124
1125 return 0;
1126}
1127
Gustavo F. Padovan28e95092010-07-31 19:57:05 -03001128void rfcomm_cleanup_ttys(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129{
1130 tty_unregister_driver(rfcomm_tty_driver);
1131 put_tty_driver(rfcomm_tty_driver);
1132}