1 /* 2 * 3 * Generic Bluetooth HCI UART driver 4 * 5 * Copyright (C) 2015-2018 Intel Corporation 6 * 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 */ 23 24 #include <asm/unaligned.h> 25 26 struct h4_recv_pkt { 27 u8 type; /* Packet type */ 28 u8 hlen; /* Header length */ 29 u8 loff; /* Data length offset in header */ 30 u8 lsize; /* Data length field size */ 31 u16 maxlen; /* Max overall packet length */ 32 int (*recv)(struct hci_dev *hdev, struct sk_buff *skb); 33 }; 34 35 #define H4_RECV_ACL \ 36 .type = HCI_ACLDATA_PKT, \ 37 .hlen = HCI_ACL_HDR_SIZE, \ 38 .loff = 2, \ 39 .lsize = 2, \ 40 .maxlen = HCI_MAX_FRAME_SIZE \ 41 42 #define H4_RECV_SCO \ 43 .type = HCI_SCODATA_PKT, \ 44 .hlen = HCI_SCO_HDR_SIZE, \ 45 .loff = 2, \ 46 .lsize = 1, \ 47 .maxlen = HCI_MAX_SCO_SIZE 48 49 #define H4_RECV_EVENT \ 50 .type = HCI_EVENT_PKT, \ 51 .hlen = HCI_EVENT_HDR_SIZE, \ 52 .loff = 1, \ 53 .lsize = 1, \ 54 .maxlen = HCI_MAX_EVENT_SIZE 55 56 static inline struct sk_buff *h4_recv_buf(struct hci_dev *hdev, 57 struct sk_buff *skb, 58 const unsigned char *buffer, 59 int count, 60 const struct h4_recv_pkt *pkts, 61 int pkts_count) 62 { 63 /* Check for error from previous call */ 64 if (IS_ERR(skb)) 65 skb = NULL; 66 67 while (count) { 68 int i, len; 69 70 if (!skb) { 71 for (i = 0; i < pkts_count; i++) { 72 if (buffer[0] != (&pkts[i])->type) 73 continue; 74 75 skb = bt_skb_alloc((&pkts[i])->maxlen, 76 GFP_ATOMIC); 77 if (!skb) 78 return ERR_PTR(-ENOMEM); 79 80 hci_skb_pkt_type(skb) = (&pkts[i])->type; 81 hci_skb_expect(skb) = (&pkts[i])->hlen; 82 break; 83 } 84 85 /* Check for invalid packet type */ 86 if (!skb) 87 return ERR_PTR(-EILSEQ); 88 89 count -= 1; 90 buffer += 1; 91 } 92 93 len = min_t(uint, hci_skb_expect(skb) - skb->len, count); 94 skb_put_data(skb, buffer, len); 95 96 count -= len; 97 buffer += len; 98 99 /* Check for partial packet */ 100 if (skb->len < hci_skb_expect(skb)) 101 continue; 102 103 for (i = 0; i < pkts_count; i++) { 104 if (hci_skb_pkt_type(skb) == (&pkts[i])->type) 105 break; 106 } 107 108 if (i >= pkts_count) { 109 kfree_skb(skb); 110 return ERR_PTR(-EILSEQ); 111 } 112 113 if (skb->len == (&pkts[i])->hlen) { 114 u16 dlen; 115 116 switch ((&pkts[i])->lsize) { 117 case 0: 118 /* No variable data length */ 119 dlen = 0; 120 break; 121 case 1: 122 /* Single octet variable length */ 123 dlen = skb->data[(&pkts[i])->loff]; 124 hci_skb_expect(skb) += dlen; 125 126 if (skb_tailroom(skb) < dlen) { 127 kfree_skb(skb); 128 return ERR_PTR(-EMSGSIZE); 129 } 130 break; 131 case 2: 132 /* Double octet variable length */ 133 dlen = get_unaligned_le16(skb->data + 134 (&pkts[i])->loff); 135 hci_skb_expect(skb) += dlen; 136 137 if (skb_tailroom(skb) < dlen) { 138 kfree_skb(skb); 139 return ERR_PTR(-EMSGSIZE); 140 } 141 break; 142 default: 143 /* Unsupported variable length */ 144 kfree_skb(skb); 145 return ERR_PTR(-EILSEQ); 146 } 147 148 if (!dlen) { 149 /* No more data, complete frame */ 150 (&pkts[i])->recv(hdev, skb); 151 skb = NULL; 152 } 153 } else { 154 /* Complete frame */ 155 (&pkts[i])->recv(hdev, skb); 156 skb = NULL; 157 } 158 } 159 160 return skb; 161 } 162