xref: /linux/net/bluetooth/cmtp/capi.c (revision 2c1ba398ac9da3305815f6ae8e95ae2b9fd3b5ff)
1 /*
2    CMTP implementation for Linux Bluetooth stack (BlueZ).
3    Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
4 
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;
8 
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.
17 
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.
21 */
22 
23 #include <linux/module.h>
24 #include <linux/proc_fs.h>
25 #include <linux/seq_file.h>
26 #include <linux/types.h>
27 #include <linux/errno.h>
28 #include <linux/kernel.h>
29 #include <linux/sched.h>
30 #include <linux/slab.h>
31 #include <linux/poll.h>
32 #include <linux/fcntl.h>
33 #include <linux/skbuff.h>
34 #include <linux/socket.h>
35 #include <linux/ioctl.h>
36 #include <linux/file.h>
37 #include <linux/wait.h>
38 #include <linux/kthread.h>
39 #include <net/sock.h>
40 
41 #include <linux/isdn/capilli.h>
42 #include <linux/isdn/capicmd.h>
43 #include <linux/isdn/capiutil.h>
44 
45 #include "cmtp.h"
46 
47 #define CAPI_INTEROPERABILITY		0x20
48 
49 #define CAPI_INTEROPERABILITY_REQ	CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
50 #define CAPI_INTEROPERABILITY_CONF	CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
51 #define CAPI_INTEROPERABILITY_IND	CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
52 #define CAPI_INTEROPERABILITY_RESP	CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
53 
54 #define CAPI_INTEROPERABILITY_REQ_LEN	(CAPI_MSG_BASELEN + 2)
55 #define CAPI_INTEROPERABILITY_CONF_LEN	(CAPI_MSG_BASELEN + 4)
56 #define CAPI_INTEROPERABILITY_IND_LEN	(CAPI_MSG_BASELEN + 2)
57 #define CAPI_INTEROPERABILITY_RESP_LEN	(CAPI_MSG_BASELEN + 2)
58 
59 #define CAPI_FUNCTION_REGISTER		0
60 #define CAPI_FUNCTION_RELEASE		1
61 #define CAPI_FUNCTION_GET_PROFILE	2
62 #define CAPI_FUNCTION_GET_MANUFACTURER	3
63 #define CAPI_FUNCTION_GET_VERSION	4
64 #define CAPI_FUNCTION_GET_SERIAL_NUMBER	5
65 #define CAPI_FUNCTION_MANUFACTURER	6
66 #define CAPI_FUNCTION_LOOPBACK		7
67 
68 
69 #define CMTP_MSGNUM	1
70 #define CMTP_APPLID	2
71 #define CMTP_MAPPING	3
72 
73 static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
74 {
75 	struct cmtp_application *app = kzalloc(sizeof(*app), GFP_KERNEL);
76 
77 	BT_DBG("session %p application %p appl %d", session, app, appl);
78 
79 	if (!app)
80 		return NULL;
81 
82 	app->state = BT_OPEN;
83 	app->appl = appl;
84 
85 	list_add_tail(&app->list, &session->applications);
86 
87 	return app;
88 }
89 
90 static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
91 {
92 	BT_DBG("session %p application %p", session, app);
93 
94 	if (app) {
95 		list_del(&app->list);
96 		kfree(app);
97 	}
98 }
99 
100 static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
101 {
102 	struct cmtp_application *app;
103 	struct list_head *p, *n;
104 
105 	list_for_each_safe(p, n, &session->applications) {
106 		app = list_entry(p, struct cmtp_application, list);
107 		switch (pattern) {
108 		case CMTP_MSGNUM:
109 			if (app->msgnum == value)
110 				return app;
111 			break;
112 		case CMTP_APPLID:
113 			if (app->appl == value)
114 				return app;
115 			break;
116 		case CMTP_MAPPING:
117 			if (app->mapping == value)
118 				return app;
119 			break;
120 		}
121 	}
122 
123 	return NULL;
124 }
125 
126 static int cmtp_msgnum_get(struct cmtp_session *session)
127 {
128 	session->msgnum++;
129 
130 	if ((session->msgnum & 0xff) > 200)
131 		session->msgnum = CMTP_INITIAL_MSGNUM + 1;
132 
133 	return session->msgnum;
134 }
135 
136 static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
137 {
138 	struct cmtp_scb *scb = (void *) skb->cb;
139 
140 	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
141 
142 	scb->id = -1;
143 	scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
144 
145 	skb_queue_tail(&session->transmit, skb);
146 
147 	wake_up_interruptible(sk_sleep(session->sock->sk));
148 }
149 
150 static void cmtp_send_interopmsg(struct cmtp_session *session,
151 					__u8 subcmd, __u16 appl, __u16 msgnum,
152 					__u16 function, unsigned char *buf, int len)
153 {
154 	struct sk_buff *skb;
155 	unsigned char *s;
156 
157 	BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
158 
159 	skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC);
160 	if (!skb) {
161 		BT_ERR("Can't allocate memory for interoperability packet");
162 		return;
163 	}
164 
165 	s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
166 
167 	capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
168 	capimsg_setu16(s, 2, appl);
169 	capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
170 	capimsg_setu8 (s, 5, subcmd);
171 	capimsg_setu16(s, 6, msgnum);
172 
173 	/* Interoperability selector (Bluetooth Device Management) */
174 	capimsg_setu16(s, 8, 0x0001);
175 
176 	capimsg_setu8 (s, 10, 3 + len);
177 	capimsg_setu16(s, 11, function);
178 	capimsg_setu8 (s, 13, len);
179 
180 	if (len > 0)
181 		memcpy(s + 14, buf, len);
182 
183 	cmtp_send_capimsg(session, skb);
184 }
185 
186 static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
187 {
188 	struct capi_ctr *ctrl = &session->ctrl;
189 	struct cmtp_application *application;
190 	__u16 appl, msgnum, func, info;
191 	__u32 controller;
192 
193 	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
194 
195 	switch (CAPIMSG_SUBCOMMAND(skb->data)) {
196 	case CAPI_CONF:
197 		if (skb->len < CAPI_MSG_BASELEN + 10)
198 			break;
199 
200 		func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
201 		info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
202 
203 		switch (func) {
204 		case CAPI_FUNCTION_REGISTER:
205 			msgnum = CAPIMSG_MSGID(skb->data);
206 
207 			application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
208 			if (application) {
209 				application->state = BT_CONNECTED;
210 				application->msgnum = 0;
211 				application->mapping = CAPIMSG_APPID(skb->data);
212 				wake_up_interruptible(&session->wait);
213 			}
214 
215 			break;
216 
217 		case CAPI_FUNCTION_RELEASE:
218 			appl = CAPIMSG_APPID(skb->data);
219 
220 			application = cmtp_application_get(session, CMTP_MAPPING, appl);
221 			if (application) {
222 				application->state = BT_CLOSED;
223 				application->msgnum = 0;
224 				wake_up_interruptible(&session->wait);
225 			}
226 
227 			break;
228 
229 		case CAPI_FUNCTION_GET_PROFILE:
230 			if (skb->len < CAPI_MSG_BASELEN + 11 + sizeof(capi_profile))
231 				break;
232 
233 			controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
234 			msgnum = CAPIMSG_MSGID(skb->data);
235 
236 			if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
237 				session->ncontroller = controller;
238 				wake_up_interruptible(&session->wait);
239 				break;
240 			}
241 
242 			if (!info && ctrl) {
243 				memcpy(&ctrl->profile,
244 					skb->data + CAPI_MSG_BASELEN + 11,
245 					sizeof(capi_profile));
246 				session->state = BT_CONNECTED;
247 				capi_ctr_ready(ctrl);
248 			}
249 
250 			break;
251 
252 		case CAPI_FUNCTION_GET_MANUFACTURER:
253 			if (skb->len < CAPI_MSG_BASELEN + 15)
254 				break;
255 
256 			controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
257 
258 			if (!info && ctrl) {
259 				int len = min_t(uint, CAPI_MANUFACTURER_LEN,
260 						skb->data[CAPI_MSG_BASELEN + 14]);
261 
262 				memset(ctrl->manu, 0, CAPI_MANUFACTURER_LEN);
263 				strncpy(ctrl->manu,
264 					skb->data + CAPI_MSG_BASELEN + 15, len);
265 			}
266 
267 			break;
268 
269 		case CAPI_FUNCTION_GET_VERSION:
270 			if (skb->len < CAPI_MSG_BASELEN + 32)
271 				break;
272 
273 			controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
274 
275 			if (!info && ctrl) {
276 				ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
277 				ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
278 				ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
279 				ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
280 			}
281 
282 			break;
283 
284 		case CAPI_FUNCTION_GET_SERIAL_NUMBER:
285 			if (skb->len < CAPI_MSG_BASELEN + 17)
286 				break;
287 
288 			controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
289 
290 			if (!info && ctrl) {
291 				int len = min_t(uint, CAPI_SERIAL_LEN,
292 						skb->data[CAPI_MSG_BASELEN + 16]);
293 
294 				memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
295 				strncpy(ctrl->serial,
296 					skb->data + CAPI_MSG_BASELEN + 17, len);
297 			}
298 
299 			break;
300 		}
301 
302 		break;
303 
304 	case CAPI_IND:
305 		if (skb->len < CAPI_MSG_BASELEN + 6)
306 			break;
307 
308 		func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
309 
310 		if (func == CAPI_FUNCTION_LOOPBACK) {
311 			int len = min_t(uint, skb->len - CAPI_MSG_BASELEN - 6,
312 						skb->data[CAPI_MSG_BASELEN + 5]);
313 			appl = CAPIMSG_APPID(skb->data);
314 			msgnum = CAPIMSG_MSGID(skb->data);
315 			cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
316 						skb->data + CAPI_MSG_BASELEN + 6, len);
317 		}
318 
319 		break;
320 	}
321 
322 	kfree_skb(skb);
323 }
324 
325 void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
326 {
327 	struct capi_ctr *ctrl = &session->ctrl;
328 	struct cmtp_application *application;
329 	__u16 appl;
330 	__u32 contr;
331 
332 	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
333 
334 	if (skb->len < CAPI_MSG_BASELEN)
335 		return;
336 
337 	if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
338 		cmtp_recv_interopmsg(session, skb);
339 		return;
340 	}
341 
342 	if (session->flags & (1 << CMTP_LOOPBACK)) {
343 		kfree_skb(skb);
344 		return;
345 	}
346 
347 	appl = CAPIMSG_APPID(skb->data);
348 	contr = CAPIMSG_CONTROL(skb->data);
349 
350 	application = cmtp_application_get(session, CMTP_MAPPING, appl);
351 	if (application) {
352 		appl = application->appl;
353 		CAPIMSG_SETAPPID(skb->data, appl);
354 	} else {
355 		BT_ERR("Can't find application with id %d", appl);
356 		kfree_skb(skb);
357 		return;
358 	}
359 
360 	if ((contr & 0x7f) == 0x01) {
361 		contr = (contr & 0xffffff80) | session->num;
362 		CAPIMSG_SETCONTROL(skb->data, contr);
363 	}
364 
365 	if (!ctrl) {
366 		BT_ERR("Can't find controller %d for message", session->num);
367 		kfree_skb(skb);
368 		return;
369 	}
370 
371 	capi_ctr_handle_message(ctrl, appl, skb);
372 }
373 
374 static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
375 {
376 	BT_DBG("ctrl %p data %p", ctrl, data);
377 
378 	return 0;
379 }
380 
381 static void cmtp_reset_ctr(struct capi_ctr *ctrl)
382 {
383 	struct cmtp_session *session = ctrl->driverdata;
384 
385 	BT_DBG("ctrl %p", ctrl);
386 
387 	capi_ctr_down(ctrl);
388 
389 	kthread_stop(session->task);
390 }
391 
392 static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
393 {
394 	DECLARE_WAITQUEUE(wait, current);
395 	struct cmtp_session *session = ctrl->driverdata;
396 	struct cmtp_application *application;
397 	unsigned long timeo = CMTP_INTEROP_TIMEOUT;
398 	unsigned char buf[8];
399 	int err = 0, nconn, want = rp->level3cnt;
400 
401 	BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
402 		ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
403 
404 	application = cmtp_application_add(session, appl);
405 	if (!application) {
406 		BT_ERR("Can't allocate memory for new application");
407 		return;
408 	}
409 
410 	if (want < 0)
411 		nconn = ctrl->profile.nbchannel * -want;
412 	else
413 		nconn = want;
414 
415 	if (nconn == 0)
416 		nconn = ctrl->profile.nbchannel;
417 
418 	capimsg_setu16(buf, 0, nconn);
419 	capimsg_setu16(buf, 2, rp->datablkcnt);
420 	capimsg_setu16(buf, 4, rp->datablklen);
421 
422 	application->state = BT_CONFIG;
423 	application->msgnum = cmtp_msgnum_get(session);
424 
425 	cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
426 				CAPI_FUNCTION_REGISTER, buf, 6);
427 
428 	add_wait_queue(&session->wait, &wait);
429 	while (1) {
430 		set_current_state(TASK_INTERRUPTIBLE);
431 
432 		if (!timeo) {
433 			err = -EAGAIN;
434 			break;
435 		}
436 
437 		if (application->state == BT_CLOSED) {
438 			err = -application->err;
439 			break;
440 		}
441 
442 		if (application->state == BT_CONNECTED)
443 			break;
444 
445 		if (signal_pending(current)) {
446 			err = -EINTR;
447 			break;
448 		}
449 
450 		timeo = schedule_timeout(timeo);
451 	}
452 	set_current_state(TASK_RUNNING);
453 	remove_wait_queue(&session->wait, &wait);
454 
455 	if (err) {
456 		cmtp_application_del(session, application);
457 		return;
458 	}
459 }
460 
461 static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
462 {
463 	struct cmtp_session *session = ctrl->driverdata;
464 	struct cmtp_application *application;
465 
466 	BT_DBG("ctrl %p appl %d", ctrl, appl);
467 
468 	application = cmtp_application_get(session, CMTP_APPLID, appl);
469 	if (!application) {
470 		BT_ERR("Can't find application");
471 		return;
472 	}
473 
474 	application->msgnum = cmtp_msgnum_get(session);
475 
476 	cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
477 				CAPI_FUNCTION_RELEASE, NULL, 0);
478 
479 	wait_event_interruptible_timeout(session->wait,
480 			(application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);
481 
482 	cmtp_application_del(session, application);
483 }
484 
485 static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
486 {
487 	struct cmtp_session *session = ctrl->driverdata;
488 	struct cmtp_application *application;
489 	__u16 appl;
490 	__u32 contr;
491 
492 	BT_DBG("ctrl %p skb %p", ctrl, skb);
493 
494 	appl = CAPIMSG_APPID(skb->data);
495 	contr = CAPIMSG_CONTROL(skb->data);
496 
497 	application = cmtp_application_get(session, CMTP_APPLID, appl);
498 	if ((!application) || (application->state != BT_CONNECTED)) {
499 		BT_ERR("Can't find application with id %d", appl);
500 		return CAPI_ILLAPPNR;
501 	}
502 
503 	CAPIMSG_SETAPPID(skb->data, application->mapping);
504 
505 	if ((contr & 0x7f) == session->num) {
506 		contr = (contr & 0xffffff80) | 0x01;
507 		CAPIMSG_SETCONTROL(skb->data, contr);
508 	}
509 
510 	cmtp_send_capimsg(session, skb);
511 
512 	return CAPI_NOERROR;
513 }
514 
515 static char *cmtp_procinfo(struct capi_ctr *ctrl)
516 {
517 	return "CAPI Message Transport Protocol";
518 }
519 
520 static int cmtp_proc_show(struct seq_file *m, void *v)
521 {
522 	struct capi_ctr *ctrl = m->private;
523 	struct cmtp_session *session = ctrl->driverdata;
524 	struct cmtp_application *app;
525 	struct list_head *p, *n;
526 
527 	seq_printf(m, "%s\n\n", cmtp_procinfo(ctrl));
528 	seq_printf(m, "addr %s\n", session->name);
529 	seq_printf(m, "ctrl %d\n", session->num);
530 
531 	list_for_each_safe(p, n, &session->applications) {
532 		app = list_entry(p, struct cmtp_application, list);
533 		seq_printf(m, "appl %d -> %d\n", app->appl, app->mapping);
534 	}
535 
536 	return 0;
537 }
538 
539 static int cmtp_proc_open(struct inode *inode, struct file *file)
540 {
541 	return single_open(file, cmtp_proc_show, PDE(inode)->data);
542 }
543 
544 static const struct file_operations cmtp_proc_fops = {
545 	.owner		= THIS_MODULE,
546 	.open		= cmtp_proc_open,
547 	.read		= seq_read,
548 	.llseek		= seq_lseek,
549 	.release	= single_release,
550 };
551 
552 int cmtp_attach_device(struct cmtp_session *session)
553 {
554 	unsigned char buf[4];
555 	long ret;
556 
557 	BT_DBG("session %p", session);
558 
559 	capimsg_setu32(buf, 0, 0);
560 
561 	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
562 				CAPI_FUNCTION_GET_PROFILE, buf, 4);
563 
564 	ret = wait_event_interruptible_timeout(session->wait,
565 			session->ncontroller, CMTP_INTEROP_TIMEOUT);
566 
567 	BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
568 
569 	if (!ret)
570 		return -ETIMEDOUT;
571 
572 	if (!session->ncontroller)
573 		return -ENODEV;
574 
575 	if (session->ncontroller > 1)
576 		BT_INFO("Setting up only CAPI controller 1");
577 
578 	session->ctrl.owner      = THIS_MODULE;
579 	session->ctrl.driverdata = session;
580 	strcpy(session->ctrl.name, session->name);
581 
582 	session->ctrl.driver_name   = "cmtp";
583 	session->ctrl.load_firmware = cmtp_load_firmware;
584 	session->ctrl.reset_ctr     = cmtp_reset_ctr;
585 	session->ctrl.register_appl = cmtp_register_appl;
586 	session->ctrl.release_appl  = cmtp_release_appl;
587 	session->ctrl.send_message  = cmtp_send_message;
588 
589 	session->ctrl.procinfo      = cmtp_procinfo;
590 	session->ctrl.proc_fops = &cmtp_proc_fops;
591 
592 	if (attach_capi_ctr(&session->ctrl) < 0) {
593 		BT_ERR("Can't attach new controller");
594 		return -EBUSY;
595 	}
596 
597 	session->num = session->ctrl.cnr;
598 
599 	BT_DBG("session %p num %d", session, session->num);
600 
601 	capimsg_setu32(buf, 0, 1);
602 
603 	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
604 				CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
605 
606 	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
607 				CAPI_FUNCTION_GET_VERSION, buf, 4);
608 
609 	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
610 				CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
611 
612 	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
613 				CAPI_FUNCTION_GET_PROFILE, buf, 4);
614 
615 	return 0;
616 }
617 
618 void cmtp_detach_device(struct cmtp_session *session)
619 {
620 	BT_DBG("session %p", session);
621 
622 	detach_capi_ctr(&session->ctrl);
623 }
624