0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include <linux/export.h>
0024 #include <linux/proc_fs.h>
0025 #include <linux/seq_file.h>
0026 #include <linux/types.h>
0027 #include <linux/errno.h>
0028 #include <linux/kernel.h>
0029 #include <linux/sched/signal.h>
0030 #include <linux/slab.h>
0031 #include <linux/poll.h>
0032 #include <linux/fcntl.h>
0033 #include <linux/skbuff.h>
0034 #include <linux/socket.h>
0035 #include <linux/ioctl.h>
0036 #include <linux/file.h>
0037 #include <linux/wait.h>
0038 #include <linux/kthread.h>
0039 #include <net/sock.h>
0040
0041 #include <linux/isdn/capilli.h>
0042 #include <linux/isdn/capicmd.h>
0043 #include <linux/isdn/capiutil.h>
0044
0045 #include "cmtp.h"
0046
0047 #define CAPI_INTEROPERABILITY 0x20
0048
0049 #define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
0050 #define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
0051 #define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
0052 #define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
0053
0054 #define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
0055 #define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
0056 #define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
0057 #define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
0058
0059 #define CAPI_FUNCTION_REGISTER 0
0060 #define CAPI_FUNCTION_RELEASE 1
0061 #define CAPI_FUNCTION_GET_PROFILE 2
0062 #define CAPI_FUNCTION_GET_MANUFACTURER 3
0063 #define CAPI_FUNCTION_GET_VERSION 4
0064 #define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
0065 #define CAPI_FUNCTION_MANUFACTURER 6
0066 #define CAPI_FUNCTION_LOOPBACK 7
0067
0068
0069 #define CMTP_MSGNUM 1
0070 #define CMTP_APPLID 2
0071 #define CMTP_MAPPING 3
0072
0073 static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
0074 {
0075 struct cmtp_application *app = kzalloc(sizeof(*app), GFP_KERNEL);
0076
0077 BT_DBG("session %p application %p appl %u", session, app, appl);
0078
0079 if (!app)
0080 return NULL;
0081
0082 app->state = BT_OPEN;
0083 app->appl = appl;
0084
0085 list_add_tail(&app->list, &session->applications);
0086
0087 return app;
0088 }
0089
0090 static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
0091 {
0092 BT_DBG("session %p application %p", session, app);
0093
0094 if (app) {
0095 list_del(&app->list);
0096 kfree(app);
0097 }
0098 }
0099
0100 static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
0101 {
0102 struct cmtp_application *app;
0103
0104 list_for_each_entry(app, &session->applications, list) {
0105 switch (pattern) {
0106 case CMTP_MSGNUM:
0107 if (app->msgnum == value)
0108 return app;
0109 break;
0110 case CMTP_APPLID:
0111 if (app->appl == value)
0112 return app;
0113 break;
0114 case CMTP_MAPPING:
0115 if (app->mapping == value)
0116 return app;
0117 break;
0118 }
0119 }
0120
0121 return NULL;
0122 }
0123
0124 static int cmtp_msgnum_get(struct cmtp_session *session)
0125 {
0126 session->msgnum++;
0127
0128 if ((session->msgnum & 0xff) > 200)
0129 session->msgnum = CMTP_INITIAL_MSGNUM + 1;
0130
0131 return session->msgnum;
0132 }
0133
0134 static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
0135 {
0136 struct cmtp_scb *scb = (void *) skb->cb;
0137
0138 BT_DBG("session %p skb %p len %u", session, skb, skb->len);
0139
0140 scb->id = -1;
0141 scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
0142
0143 skb_queue_tail(&session->transmit, skb);
0144
0145 wake_up_interruptible(sk_sleep(session->sock->sk));
0146 }
0147
0148 static void cmtp_send_interopmsg(struct cmtp_session *session,
0149 __u8 subcmd, __u16 appl, __u16 msgnum,
0150 __u16 function, unsigned char *buf, int len)
0151 {
0152 struct sk_buff *skb;
0153 unsigned char *s;
0154
0155 BT_DBG("session %p subcmd 0x%02x appl %u msgnum %u", session, subcmd, appl, msgnum);
0156
0157 skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC);
0158 if (!skb) {
0159 BT_ERR("Can't allocate memory for interoperability packet");
0160 return;
0161 }
0162
0163 s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
0164
0165 capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
0166 capimsg_setu16(s, 2, appl);
0167 capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
0168 capimsg_setu8 (s, 5, subcmd);
0169 capimsg_setu16(s, 6, msgnum);
0170
0171
0172 capimsg_setu16(s, 8, 0x0001);
0173
0174 capimsg_setu8 (s, 10, 3 + len);
0175 capimsg_setu16(s, 11, function);
0176 capimsg_setu8 (s, 13, len);
0177
0178 if (len > 0)
0179 memcpy(s + 14, buf, len);
0180
0181 cmtp_send_capimsg(session, skb);
0182 }
0183
0184 static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
0185 {
0186 struct capi_ctr *ctrl = &session->ctrl;
0187 struct cmtp_application *application;
0188 __u16 appl, msgnum, func, info;
0189 __u32 controller;
0190
0191 BT_DBG("session %p skb %p len %u", session, skb, skb->len);
0192
0193 switch (CAPIMSG_SUBCOMMAND(skb->data)) {
0194 case CAPI_CONF:
0195 if (skb->len < CAPI_MSG_BASELEN + 10)
0196 break;
0197
0198 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
0199 info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
0200
0201 switch (func) {
0202 case CAPI_FUNCTION_REGISTER:
0203 msgnum = CAPIMSG_MSGID(skb->data);
0204
0205 application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
0206 if (application) {
0207 application->state = BT_CONNECTED;
0208 application->msgnum = 0;
0209 application->mapping = CAPIMSG_APPID(skb->data);
0210 wake_up_interruptible(&session->wait);
0211 }
0212
0213 break;
0214
0215 case CAPI_FUNCTION_RELEASE:
0216 appl = CAPIMSG_APPID(skb->data);
0217
0218 application = cmtp_application_get(session, CMTP_MAPPING, appl);
0219 if (application) {
0220 application->state = BT_CLOSED;
0221 application->msgnum = 0;
0222 wake_up_interruptible(&session->wait);
0223 }
0224
0225 break;
0226
0227 case CAPI_FUNCTION_GET_PROFILE:
0228 if (skb->len < CAPI_MSG_BASELEN + 11 + sizeof(capi_profile))
0229 break;
0230
0231 controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
0232 msgnum = CAPIMSG_MSGID(skb->data);
0233
0234 if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
0235 session->ncontroller = controller;
0236 wake_up_interruptible(&session->wait);
0237 break;
0238 }
0239
0240 if (!info && ctrl) {
0241 memcpy(&ctrl->profile,
0242 skb->data + CAPI_MSG_BASELEN + 11,
0243 sizeof(capi_profile));
0244 session->state = BT_CONNECTED;
0245 capi_ctr_ready(ctrl);
0246 }
0247
0248 break;
0249
0250 case CAPI_FUNCTION_GET_MANUFACTURER:
0251 if (skb->len < CAPI_MSG_BASELEN + 15)
0252 break;
0253
0254 if (!info && ctrl) {
0255 int len = min_t(uint, CAPI_MANUFACTURER_LEN,
0256 skb->data[CAPI_MSG_BASELEN + 14]);
0257
0258 memset(ctrl->manu, 0, CAPI_MANUFACTURER_LEN);
0259 strncpy(ctrl->manu,
0260 skb->data + CAPI_MSG_BASELEN + 15, len);
0261 }
0262
0263 break;
0264
0265 case CAPI_FUNCTION_GET_VERSION:
0266 if (skb->len < CAPI_MSG_BASELEN + 32)
0267 break;
0268
0269 if (!info && ctrl) {
0270 ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
0271 ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
0272 ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
0273 ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
0274 }
0275
0276 break;
0277
0278 case CAPI_FUNCTION_GET_SERIAL_NUMBER:
0279 if (skb->len < CAPI_MSG_BASELEN + 17)
0280 break;
0281
0282 if (!info && ctrl) {
0283 int len = min_t(uint, CAPI_SERIAL_LEN,
0284 skb->data[CAPI_MSG_BASELEN + 16]);
0285
0286 memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
0287 strncpy(ctrl->serial,
0288 skb->data + CAPI_MSG_BASELEN + 17, len);
0289 }
0290
0291 break;
0292 }
0293
0294 break;
0295
0296 case CAPI_IND:
0297 if (skb->len < CAPI_MSG_BASELEN + 6)
0298 break;
0299
0300 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
0301
0302 if (func == CAPI_FUNCTION_LOOPBACK) {
0303 int len = min_t(uint, skb->len - CAPI_MSG_BASELEN - 6,
0304 skb->data[CAPI_MSG_BASELEN + 5]);
0305 appl = CAPIMSG_APPID(skb->data);
0306 msgnum = CAPIMSG_MSGID(skb->data);
0307 cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
0308 skb->data + CAPI_MSG_BASELEN + 6, len);
0309 }
0310
0311 break;
0312 }
0313
0314 kfree_skb(skb);
0315 }
0316
0317 void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
0318 {
0319 struct capi_ctr *ctrl = &session->ctrl;
0320 struct cmtp_application *application;
0321 __u16 appl;
0322 __u32 contr;
0323
0324 BT_DBG("session %p skb %p len %u", session, skb, skb->len);
0325
0326 if (skb->len < CAPI_MSG_BASELEN)
0327 return;
0328
0329 if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
0330 cmtp_recv_interopmsg(session, skb);
0331 return;
0332 }
0333
0334 if (session->flags & BIT(CMTP_LOOPBACK)) {
0335 kfree_skb(skb);
0336 return;
0337 }
0338
0339 appl = CAPIMSG_APPID(skb->data);
0340 contr = CAPIMSG_CONTROL(skb->data);
0341
0342 application = cmtp_application_get(session, CMTP_MAPPING, appl);
0343 if (application) {
0344 appl = application->appl;
0345 CAPIMSG_SETAPPID(skb->data, appl);
0346 } else {
0347 BT_ERR("Can't find application with id %u", appl);
0348 kfree_skb(skb);
0349 return;
0350 }
0351
0352 if ((contr & 0x7f) == 0x01) {
0353 contr = (contr & 0xffffff80) | session->num;
0354 CAPIMSG_SETCONTROL(skb->data, contr);
0355 }
0356
0357 capi_ctr_handle_message(ctrl, appl, skb);
0358 }
0359
0360 static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
0361 {
0362 BT_DBG("ctrl %p data %p", ctrl, data);
0363
0364 return 0;
0365 }
0366
0367 static void cmtp_reset_ctr(struct capi_ctr *ctrl)
0368 {
0369 struct cmtp_session *session = ctrl->driverdata;
0370
0371 BT_DBG("ctrl %p", ctrl);
0372
0373 capi_ctr_down(ctrl);
0374
0375 atomic_inc(&session->terminate);
0376 wake_up_process(session->task);
0377 }
0378
0379 static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
0380 {
0381 DECLARE_WAITQUEUE(wait, current);
0382 struct cmtp_session *session = ctrl->driverdata;
0383 struct cmtp_application *application;
0384 unsigned long timeo = CMTP_INTEROP_TIMEOUT;
0385 unsigned char buf[8];
0386 int err = 0, nconn, want = rp->level3cnt;
0387
0388 BT_DBG("ctrl %p appl %u level3cnt %u datablkcnt %u datablklen %u",
0389 ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
0390
0391 application = cmtp_application_add(session, appl);
0392 if (!application) {
0393 BT_ERR("Can't allocate memory for new application");
0394 return;
0395 }
0396
0397 if (want < 0)
0398 nconn = ctrl->profile.nbchannel * -want;
0399 else
0400 nconn = want;
0401
0402 if (nconn == 0)
0403 nconn = ctrl->profile.nbchannel;
0404
0405 capimsg_setu16(buf, 0, nconn);
0406 capimsg_setu16(buf, 2, rp->datablkcnt);
0407 capimsg_setu16(buf, 4, rp->datablklen);
0408
0409 application->state = BT_CONFIG;
0410 application->msgnum = cmtp_msgnum_get(session);
0411
0412 cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
0413 CAPI_FUNCTION_REGISTER, buf, 6);
0414
0415 add_wait_queue(&session->wait, &wait);
0416 while (1) {
0417 set_current_state(TASK_INTERRUPTIBLE);
0418
0419 if (!timeo) {
0420 err = -EAGAIN;
0421 break;
0422 }
0423
0424 if (application->state == BT_CLOSED) {
0425 err = -application->err;
0426 break;
0427 }
0428
0429 if (application->state == BT_CONNECTED)
0430 break;
0431
0432 if (signal_pending(current)) {
0433 err = -EINTR;
0434 break;
0435 }
0436
0437 timeo = schedule_timeout(timeo);
0438 }
0439 set_current_state(TASK_RUNNING);
0440 remove_wait_queue(&session->wait, &wait);
0441
0442 if (err) {
0443 cmtp_application_del(session, application);
0444 return;
0445 }
0446 }
0447
0448 static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
0449 {
0450 struct cmtp_session *session = ctrl->driverdata;
0451 struct cmtp_application *application;
0452
0453 BT_DBG("ctrl %p appl %u", ctrl, appl);
0454
0455 application = cmtp_application_get(session, CMTP_APPLID, appl);
0456 if (!application) {
0457 BT_ERR("Can't find application");
0458 return;
0459 }
0460
0461 application->msgnum = cmtp_msgnum_get(session);
0462
0463 cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
0464 CAPI_FUNCTION_RELEASE, NULL, 0);
0465
0466 wait_event_interruptible_timeout(session->wait,
0467 (application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);
0468
0469 cmtp_application_del(session, application);
0470 }
0471
0472 static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
0473 {
0474 struct cmtp_session *session = ctrl->driverdata;
0475 struct cmtp_application *application;
0476 __u16 appl;
0477 __u32 contr;
0478
0479 BT_DBG("ctrl %p skb %p", ctrl, skb);
0480
0481 appl = CAPIMSG_APPID(skb->data);
0482 contr = CAPIMSG_CONTROL(skb->data);
0483
0484 application = cmtp_application_get(session, CMTP_APPLID, appl);
0485 if ((!application) || (application->state != BT_CONNECTED)) {
0486 BT_ERR("Can't find application with id %u", appl);
0487 return CAPI_ILLAPPNR;
0488 }
0489
0490 CAPIMSG_SETAPPID(skb->data, application->mapping);
0491
0492 if ((contr & 0x7f) == session->num) {
0493 contr = (contr & 0xffffff80) | 0x01;
0494 CAPIMSG_SETCONTROL(skb->data, contr);
0495 }
0496
0497 cmtp_send_capimsg(session, skb);
0498
0499 return CAPI_NOERROR;
0500 }
0501
0502 static char *cmtp_procinfo(struct capi_ctr *ctrl)
0503 {
0504 return "CAPI Message Transport Protocol";
0505 }
0506
0507 static int cmtp_proc_show(struct seq_file *m, void *v)
0508 {
0509 struct capi_ctr *ctrl = m->private;
0510 struct cmtp_session *session = ctrl->driverdata;
0511 struct cmtp_application *app;
0512
0513 seq_printf(m, "%s\n\n", cmtp_procinfo(ctrl));
0514 seq_printf(m, "addr %s\n", session->name);
0515 seq_printf(m, "ctrl %d\n", session->num);
0516
0517 list_for_each_entry(app, &session->applications, list) {
0518 seq_printf(m, "appl %u -> %u\n", app->appl, app->mapping);
0519 }
0520
0521 return 0;
0522 }
0523
0524 int cmtp_attach_device(struct cmtp_session *session)
0525 {
0526 unsigned char buf[4];
0527 long ret;
0528
0529 BT_DBG("session %p", session);
0530
0531 capimsg_setu32(buf, 0, 0);
0532
0533 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
0534 CAPI_FUNCTION_GET_PROFILE, buf, 4);
0535
0536 ret = wait_event_interruptible_timeout(session->wait,
0537 session->ncontroller, CMTP_INTEROP_TIMEOUT);
0538
0539 BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
0540
0541 if (!ret)
0542 return -ETIMEDOUT;
0543
0544 if (!session->ncontroller)
0545 return -ENODEV;
0546
0547 if (session->ncontroller > 1)
0548 BT_INFO("Setting up only CAPI controller 1");
0549
0550 session->ctrl.owner = THIS_MODULE;
0551 session->ctrl.driverdata = session;
0552 strcpy(session->ctrl.name, session->name);
0553
0554 session->ctrl.driver_name = "cmtp";
0555 session->ctrl.load_firmware = cmtp_load_firmware;
0556 session->ctrl.reset_ctr = cmtp_reset_ctr;
0557 session->ctrl.register_appl = cmtp_register_appl;
0558 session->ctrl.release_appl = cmtp_release_appl;
0559 session->ctrl.send_message = cmtp_send_message;
0560
0561 session->ctrl.procinfo = cmtp_procinfo;
0562 session->ctrl.proc_show = cmtp_proc_show;
0563
0564 if (attach_capi_ctr(&session->ctrl) < 0) {
0565 BT_ERR("Can't attach new controller");
0566 return -EBUSY;
0567 }
0568
0569 session->num = session->ctrl.cnr;
0570
0571 BT_DBG("session %p num %d", session, session->num);
0572
0573 capimsg_setu32(buf, 0, 1);
0574
0575 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
0576 CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
0577
0578 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
0579 CAPI_FUNCTION_GET_VERSION, buf, 4);
0580
0581 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
0582 CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
0583
0584 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
0585 CAPI_FUNCTION_GET_PROFILE, buf, 4);
0586
0587 return 0;
0588 }
0589
0590 void cmtp_detach_device(struct cmtp_session *session)
0591 {
0592 BT_DBG("session %p", session);
0593
0594 detach_capi_ctr(&session->ctrl);
0595 }