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