📄 capi.c
字号:
} kfree_skb(skb);}void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb){ struct capi_ctr *ctrl = &session->ctrl; struct cmtp_application *application; __u16 cmd, appl; __u32 contr; BT_DBG("session %p skb %p len %d", session, skb, skb->len); if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) { cmtp_recv_interopmsg(session, skb); return; } if (session->flags & (1 << CMTP_LOOPBACK)) { kfree_skb(skb); return; } cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data)); appl = CAPIMSG_APPID(skb->data); contr = CAPIMSG_CONTROL(skb->data); application = cmtp_application_get(session, CMTP_MAPPING, appl); if (application) { appl = application->appl; CAPIMSG_SETAPPID(skb->data, appl); } else { BT_ERR("Can't find application with id %d", appl); kfree_skb(skb); return; } if ((contr & 0x7f) == 0x01) { contr = (contr & 0xffffff80) | session->num; CAPIMSG_SETCONTROL(skb->data, contr); } if (!ctrl) { BT_ERR("Can't find controller %d for message", session->num); kfree_skb(skb); return; } capi_ctr_handle_message(ctrl, appl, skb);}static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data){ BT_DBG("ctrl %p data %p", ctrl, data); return 0;}static void cmtp_reset_ctr(struct capi_ctr *ctrl){ struct cmtp_session *session = ctrl->driverdata; BT_DBG("ctrl %p", ctrl); capi_ctr_reseted(ctrl); atomic_inc(&session->terminate); cmtp_schedule(session);}static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp){ DECLARE_WAITQUEUE(wait, current); struct cmtp_session *session = ctrl->driverdata; struct cmtp_application *application; unsigned long timeo = CMTP_INTEROP_TIMEOUT; unsigned char buf[8]; int err = 0, nconn, want = rp->level3cnt; BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d", ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen); application = cmtp_application_add(session, appl); if (!application) { BT_ERR("Can't allocate memory for new application"); return; } if (want < 0) nconn = ctrl->profile.nbchannel * -want; else nconn = want; if (nconn == 0) nconn = ctrl->profile.nbchannel; capimsg_setu16(buf, 0, nconn); capimsg_setu16(buf, 2, rp->datablkcnt); capimsg_setu16(buf, 4, rp->datablklen); application->state = BT_CONFIG; application->msgnum = cmtp_msgnum_get(session); cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum, CAPI_FUNCTION_REGISTER, buf, 6); add_wait_queue(&session->wait, &wait); while (1) { set_current_state(TASK_INTERRUPTIBLE); if (!timeo) { err = -EAGAIN; break; } if (application->state == BT_CLOSED) { err = -application->err; break; } if (application->state == BT_CONNECTED) break; if (signal_pending(current)) { err = -EINTR; break; } timeo = schedule_timeout(timeo); } set_current_state(TASK_RUNNING); remove_wait_queue(&session->wait, &wait); if (err) { cmtp_application_del(session, application); return; }}static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl){ struct cmtp_session *session = ctrl->driverdata; struct cmtp_application *application; BT_DBG("ctrl %p appl %d", ctrl, appl); application = cmtp_application_get(session, CMTP_APPLID, appl); if (!application) { BT_ERR("Can't find application"); return; } application->msgnum = cmtp_msgnum_get(session); cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum, CAPI_FUNCTION_RELEASE, NULL, 0); wait_event_interruptible_timeout(session->wait, (application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT); cmtp_application_del(session, application);}static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb){ struct cmtp_session *session = ctrl->driverdata; struct cmtp_application *application; __u16 appl; __u32 contr; BT_DBG("ctrl %p skb %p", ctrl, skb); appl = CAPIMSG_APPID(skb->data); contr = CAPIMSG_CONTROL(skb->data); application = cmtp_application_get(session, CMTP_APPLID, appl); if ((!application) || (application->state != BT_CONNECTED)) { BT_ERR("Can't find application with id %d", appl); return CAPI_ILLAPPNR; } CAPIMSG_SETAPPID(skb->data, application->mapping); if ((contr & 0x7f) == session->num) { contr = (contr & 0xffffff80) | 0x01; CAPIMSG_SETCONTROL(skb->data, contr); } cmtp_send_capimsg(session, skb); return CAPI_NOERROR;}static char *cmtp_procinfo(struct capi_ctr *ctrl){ return "CAPI Message Transport Protocol";}static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl){ struct cmtp_session *session = ctrl->driverdata; struct cmtp_application *app; struct list_head *p, *n; int len = 0; len += sprintf(page + len, "%s\n\n", cmtp_procinfo(ctrl)); len += sprintf(page + len, "addr %s\n", session->name); len += sprintf(page + len, "ctrl %d\n", session->num); list_for_each_safe(p, n, &session->applications) { app = list_entry(p, struct cmtp_application, list); len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping); } if (off + count >= len) *eof = 1; if (len < off) return 0; *start = page + off; return ((count < len - off) ? count : len - off);}int cmtp_attach_device(struct cmtp_session *session){ unsigned char buf[4]; long ret; BT_DBG("session %p", session); capimsg_setu32(buf, 0, 0); cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM, CAPI_FUNCTION_GET_PROFILE, buf, 4); ret = wait_event_interruptible_timeout(session->wait, session->ncontroller, CMTP_INTEROP_TIMEOUT); BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name); if (!ret) return -ETIMEDOUT; if (!session->ncontroller) return -ENODEV; if (session->ncontroller > 1) BT_INFO("Setting up only CAPI controller 1"); session->ctrl.owner = THIS_MODULE; session->ctrl.driverdata = session; strcpy(session->ctrl.name, session->name); session->ctrl.driver_name = "cmtp"; session->ctrl.load_firmware = cmtp_load_firmware; session->ctrl.reset_ctr = cmtp_reset_ctr; session->ctrl.register_appl = cmtp_register_appl; session->ctrl.release_appl = cmtp_release_appl; session->ctrl.send_message = cmtp_send_message; session->ctrl.procinfo = cmtp_procinfo; session->ctrl.ctr_read_proc = cmtp_ctr_read_proc; if (attach_capi_ctr(&session->ctrl) < 0) { BT_ERR("Can't attach new controller"); return -EBUSY; } session->num = session->ctrl.cnr; BT_DBG("session %p num %d", session, session->num); capimsg_setu32(buf, 0, 1); cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session), CAPI_FUNCTION_GET_MANUFACTURER, buf, 4); cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session), CAPI_FUNCTION_GET_VERSION, buf, 4); cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session), CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4); cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session), CAPI_FUNCTION_GET_PROFILE, buf, 4); return 0;}void cmtp_detach_device(struct cmtp_session *session){ BT_DBG("session %p", session); detach_capi_ctr(&session->ctrl);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -