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