Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
capi.c
Go to the documentation of this file.
1 /*
2  CMTP implementation for Linux Bluetooth stack (BlueZ).
3  Copyright (C) 2002-2003 Marcel Holtmann <[email protected]>
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;
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) {
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 
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 
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 
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 
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) {
280  }
281 
282  break;
283 
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;
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 
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  atomic_inc(&session->terminate);
390  wake_up_process(session->task);
391 }
392 
393 static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
394 {
396  struct cmtp_session *session = ctrl->driverdata;
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) {
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  }
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;
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,
479 
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;
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,
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),
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),
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 }