hci_drv.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2025 Google Corporation
  4. */
  5. #include <linux/skbuff.h>
  6. #include <linux/types.h>
  7. #include <net/bluetooth/bluetooth.h>
  8. #include <net/bluetooth/hci.h>
  9. #include <net/bluetooth/hci_core.h>
  10. #include <net/bluetooth/hci_drv.h>
  11. int hci_drv_cmd_status(struct hci_dev *hdev, u16 cmd, u8 status)
  12. {
  13. struct hci_drv_ev_hdr *hdr;
  14. struct hci_drv_ev_cmd_status *ev;
  15. struct sk_buff *skb;
  16. skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*ev), GFP_KERNEL);
  17. if (!skb)
  18. return -ENOMEM;
  19. hdr = skb_put(skb, sizeof(*hdr));
  20. hdr->opcode = __cpu_to_le16(HCI_DRV_EV_CMD_STATUS);
  21. hdr->len = __cpu_to_le16(sizeof(*ev));
  22. ev = skb_put(skb, sizeof(*ev));
  23. ev->opcode = __cpu_to_le16(cmd);
  24. ev->status = status;
  25. hci_skb_pkt_type(skb) = HCI_DRV_PKT;
  26. return hci_recv_frame(hdev, skb);
  27. }
  28. EXPORT_SYMBOL(hci_drv_cmd_status);
  29. int hci_drv_cmd_complete(struct hci_dev *hdev, u16 cmd, u8 status, void *rp,
  30. size_t rp_len)
  31. {
  32. struct hci_drv_ev_hdr *hdr;
  33. struct hci_drv_ev_cmd_complete *ev;
  34. struct sk_buff *skb;
  35. skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_KERNEL);
  36. if (!skb)
  37. return -ENOMEM;
  38. hdr = skb_put(skb, sizeof(*hdr));
  39. hdr->opcode = __cpu_to_le16(HCI_DRV_EV_CMD_COMPLETE);
  40. hdr->len = __cpu_to_le16(sizeof(*ev) + rp_len);
  41. ev = skb_put(skb, sizeof(*ev));
  42. ev->opcode = __cpu_to_le16(cmd);
  43. ev->status = status;
  44. skb_put_data(skb, rp, rp_len);
  45. hci_skb_pkt_type(skb) = HCI_DRV_PKT;
  46. return hci_recv_frame(hdev, skb);
  47. }
  48. EXPORT_SYMBOL(hci_drv_cmd_complete);
  49. int hci_drv_process_cmd(struct hci_dev *hdev, struct sk_buff *skb)
  50. {
  51. struct hci_drv_cmd_hdr *hdr;
  52. const struct hci_drv_handler *handler = NULL;
  53. u16 opcode, len, ogf, ocf;
  54. hdr = skb_pull_data(skb, sizeof(*hdr));
  55. if (!hdr)
  56. return -EILSEQ;
  57. opcode = __le16_to_cpu(hdr->opcode);
  58. len = __le16_to_cpu(hdr->len);
  59. if (len != skb->len)
  60. return -EILSEQ;
  61. ogf = hci_opcode_ogf(opcode);
  62. ocf = hci_opcode_ocf(opcode);
  63. if (!hdev->hci_drv)
  64. return hci_drv_cmd_status(hdev, opcode,
  65. HCI_DRV_STATUS_UNKNOWN_COMMAND);
  66. if (ogf != HCI_DRV_OGF_DRIVER_SPECIFIC) {
  67. if (opcode < hdev->hci_drv->common_handler_count)
  68. handler = &hdev->hci_drv->common_handlers[opcode];
  69. } else {
  70. if (ocf < hdev->hci_drv->specific_handler_count)
  71. handler = &hdev->hci_drv->specific_handlers[ocf];
  72. }
  73. if (!handler || !handler->func)
  74. return hci_drv_cmd_status(hdev, opcode,
  75. HCI_DRV_STATUS_UNKNOWN_COMMAND);
  76. if (len != handler->data_len)
  77. return hci_drv_cmd_status(hdev, opcode,
  78. HCI_DRV_STATUS_INVALID_PARAMETERS);
  79. return handler->func(hdev, skb->data, len);
  80. }
  81. EXPORT_SYMBOL(hci_drv_process_cmd);