2
CMTP implementation for Linux Bluetooth stack (BlueZ).
3
Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License version 2 as
7
published by the Free Software Foundation;
9
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20
SOFTWARE IS DISCLAIMED.
23
#include <linux/module.h>
25
#include <linux/types.h>
26
#include <linux/errno.h>
27
#include <linux/kernel.h>
28
#include <linux/sched.h>
29
#include <linux/slab.h>
30
#include <linux/poll.h>
31
#include <linux/fcntl.h>
32
#include <linux/freezer.h>
33
#include <linux/skbuff.h>
34
#include <linux/socket.h>
35
#include <linux/ioctl.h>
36
#include <linux/file.h>
37
#include <linux/init.h>
40
#include <linux/isdn/capilli.h>
42
#include <net/bluetooth/bluetooth.h>
43
#include <net/bluetooth/l2cap.h>
49
static DECLARE_RWSEM(cmtp_session_sem);
50
static LIST_HEAD(cmtp_session_list);
52
static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr)
54
struct cmtp_session *session;
59
list_for_each(p, &cmtp_session_list) {
60
session = list_entry(p, struct cmtp_session, list);
61
if (!bacmp(bdaddr, &session->bdaddr))
67
static void __cmtp_link_session(struct cmtp_session *session)
69
__module_get(THIS_MODULE);
70
list_add(&session->list, &cmtp_session_list);
73
static void __cmtp_unlink_session(struct cmtp_session *session)
75
list_del(&session->list);
76
module_put(THIS_MODULE);
79
static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
81
memset(ci, 0, sizeof(*ci));
82
bacpy(&ci->bdaddr, &session->bdaddr);
84
ci->flags = session->flags;
85
ci->state = session->state;
87
ci->num = session->num;
91
static inline int cmtp_alloc_block_id(struct cmtp_session *session)
95
for (i = 0; i < 16; i++)
96
if (!test_and_set_bit(i, &session->blockids)) {
104
static inline void cmtp_free_block_id(struct cmtp_session *session, int id)
106
clear_bit(id, &session->blockids);
109
static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const unsigned char *buf, int count)
111
struct sk_buff *skb = session->reassembly[id], *nskb;
114
BT_DBG("session %p buf %p count %d", session, buf, count);
116
size = (skb) ? skb->len + count : count;
118
nskb = alloc_skb(size, GFP_ATOMIC);
120
BT_ERR("Can't allocate memory for CAPI message");
124
if (skb && (skb->len > 0))
125
skb_copy_from_linear_data(skb, skb_put(nskb, skb->len), skb->len);
127
memcpy(skb_put(nskb, count), buf, count);
129
session->reassembly[id] = nskb;
134
static inline int cmtp_recv_frame(struct cmtp_session *session, struct sk_buff *skb)
136
__u8 hdr, hdrlen, id;
139
BT_DBG("session %p skb %p len %d", session, skb, skb->len);
141
while (skb->len > 0) {
144
switch (hdr & 0xc0) {
151
len = skb->data[1] | (skb->data[2] << 8);
159
id = (hdr & 0x3c) >> 2;
161
BT_DBG("hdr 0x%02x hdrlen %d len %d id %d", hdr, hdrlen, len, id);
163
if (hdrlen + len > skb->len) {
164
BT_ERR("Wrong size or header information in CMTP frame");
169
skb_pull(skb, hdrlen);
173
switch (hdr & 0x03) {
175
cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
176
cmtp_recv_capimsg(session, session->reassembly[id]);
177
session->reassembly[id] = NULL;
180
cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
183
if (session->reassembly[id] != NULL)
184
kfree_skb(session->reassembly[id]);
185
session->reassembly[id] = NULL;
189
skb_pull(skb, hdrlen + len);
196
static int cmtp_send_frame(struct cmtp_session *session, unsigned char *data, int len)
198
struct socket *sock = session->sock;
199
struct kvec iv = { data, len };
202
BT_DBG("session %p data %p len %d", session, data, len);
207
memset(&msg, 0, sizeof(msg));
209
return kernel_sendmsg(sock, &msg, &iv, 1, len);
212
static void cmtp_process_transmit(struct cmtp_session *session)
214
struct sk_buff *skb, *nskb;
216
unsigned int size, tail;
218
BT_DBG("session %p", session);
220
nskb = alloc_skb(session->mtu, GFP_ATOMIC);
222
BT_ERR("Can't allocate memory for new frame");
226
while ((skb = skb_dequeue(&session->transmit))) {
227
struct cmtp_scb *scb = (void *) skb->cb;
229
tail = session->mtu - nskb->len;
231
cmtp_send_frame(session, nskb->data, nskb->len);
236
size = min_t(uint, ((tail < 258) ? (tail - 2) : (tail - 3)), skb->len);
238
if ((scb->id < 0) && ((scb->id = cmtp_alloc_block_id(session)) < 0)) {
239
skb_queue_head(&session->transmit, skb);
244
hdr = skb_put(nskb, 2);
246
| ((scb->id << 2) & 0x3c)
247
| ((skb->len == size) ? 0x00 : 0x01);
250
hdr = skb_put(nskb, 3);
252
| ((scb->id << 2) & 0x3c)
253
| ((skb->len == size) ? 0x00 : 0x01);
254
hdr[1] = size & 0xff;
258
skb_copy_from_linear_data(skb, skb_put(nskb, size), size);
262
skb_queue_head(&session->transmit, skb);
264
cmtp_free_block_id(session, scb->id);
266
cmtp_send_frame(session, nskb->data, nskb->len);
273
cmtp_send_frame(session, nskb->data, nskb->len);
278
static int cmtp_session(void *arg)
280
struct cmtp_session *session = arg;
281
struct sock *sk = session->sock->sk;
285
BT_DBG("session %p", session);
287
daemonize("kcmtpd_ctr_%d", session->num);
288
set_user_nice(current, -15);
290
init_waitqueue_entry(&wait, current);
291
add_wait_queue(sk_sleep(sk), &wait);
292
while (!atomic_read(&session->terminate)) {
293
set_current_state(TASK_INTERRUPTIBLE);
295
if (sk->sk_state != BT_CONNECTED)
298
while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
300
cmtp_recv_frame(session, skb);
303
cmtp_process_transmit(session);
307
set_current_state(TASK_RUNNING);
308
remove_wait_queue(sk_sleep(sk), &wait);
310
down_write(&cmtp_session_sem);
312
if (!(session->flags & (1 << CMTP_LOOPBACK)))
313
cmtp_detach_device(session);
315
fput(session->sock->file);
317
__cmtp_unlink_session(session);
319
up_write(&cmtp_session_sem);
325
int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
327
struct cmtp_session *session, *s;
332
session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL);
336
down_write(&cmtp_session_sem);
338
s = __cmtp_get_session(&bt_sk(sock->sk)->dst);
339
if (s && s->state == BT_CONNECTED) {
344
bacpy(&session->bdaddr, &bt_sk(sock->sk)->dst);
346
session->mtu = min_t(uint, l2cap_pi(sock->sk)->omtu, l2cap_pi(sock->sk)->imtu);
348
BT_DBG("mtu %d", session->mtu);
350
sprintf(session->name, "%s", batostr(&bt_sk(sock->sk)->dst));
352
session->sock = sock;
353
session->state = BT_CONFIG;
355
init_waitqueue_head(&session->wait);
357
session->msgnum = CMTP_INITIAL_MSGNUM;
359
INIT_LIST_HEAD(&session->applications);
361
skb_queue_head_init(&session->transmit);
363
for (i = 0; i < 16; i++)
364
session->reassembly[i] = NULL;
366
session->flags = req->flags;
368
__cmtp_link_session(session);
370
err = kernel_thread(cmtp_session, session, CLONE_KERNEL);
374
if (!(session->flags & (1 << CMTP_LOOPBACK))) {
375
err = cmtp_attach_device(session);
380
up_write(&cmtp_session_sem);
384
cmtp_detach_device(session);
387
__cmtp_unlink_session(session);
390
up_write(&cmtp_session_sem);
395
int cmtp_del_connection(struct cmtp_conndel_req *req)
397
struct cmtp_session *session;
402
down_read(&cmtp_session_sem);
404
session = __cmtp_get_session(&req->bdaddr);
406
/* Flush the transmit queue */
407
skb_queue_purge(&session->transmit);
409
/* Kill session thread */
410
atomic_inc(&session->terminate);
411
cmtp_schedule(session);
415
up_read(&cmtp_session_sem);
419
int cmtp_get_connlist(struct cmtp_connlist_req *req)
426
down_read(&cmtp_session_sem);
428
list_for_each(p, &cmtp_session_list) {
429
struct cmtp_session *session;
430
struct cmtp_conninfo ci;
432
session = list_entry(p, struct cmtp_session, list);
434
__cmtp_copy_session(session, &ci);
436
if (copy_to_user(req->ci, &ci, sizeof(ci))) {
441
if (++n >= req->cnum)
448
up_read(&cmtp_session_sem);
452
int cmtp_get_conninfo(struct cmtp_conninfo *ci)
454
struct cmtp_session *session;
457
down_read(&cmtp_session_sem);
459
session = __cmtp_get_session(&ci->bdaddr);
461
__cmtp_copy_session(session, ci);
465
up_read(&cmtp_session_sem);
470
static int __init cmtp_init(void)
472
BT_INFO("CMTP (CAPI Emulation) ver %s", VERSION);
479
static void __exit cmtp_exit(void)
481
cmtp_cleanup_sockets();
484
module_init(cmtp_init);
485
module_exit(cmtp_exit);
487
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
488
MODULE_DESCRIPTION("Bluetooth CMTP ver " VERSION);
489
MODULE_VERSION(VERSION);
490
MODULE_LICENSE("GPL");
491
MODULE_ALIAS("bt-proto-5");