diff options
Diffstat (limited to 'net/bluetooth/hci_sock.c')
-rw-r--r-- | net/bluetooth/hci_sock.c | 209 |
1 files changed, 177 insertions, 32 deletions
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index b1eb8c09a660..1298d723c0e0 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -25,6 +25,7 @@ | |||
25 | /* Bluetooth HCI sockets. */ | 25 | /* Bluetooth HCI sockets. */ |
26 | 26 | ||
27 | #include <linux/export.h> | 27 | #include <linux/export.h> |
28 | #include <linux/utsname.h> | ||
28 | #include <asm/unaligned.h> | 29 | #include <asm/unaligned.h> |
29 | 30 | ||
30 | #include <net/bluetooth/bluetooth.h> | 31 | #include <net/bluetooth/bluetooth.h> |
@@ -120,13 +121,13 @@ static bool is_filtered_packet(struct sock *sk, struct sk_buff *skb) | |||
120 | /* Apply filter */ | 121 | /* Apply filter */ |
121 | flt = &hci_pi(sk)->filter; | 122 | flt = &hci_pi(sk)->filter; |
122 | 123 | ||
123 | flt_type = bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS; | 124 | flt_type = hci_skb_pkt_type(skb) & HCI_FLT_TYPE_BITS; |
124 | 125 | ||
125 | if (!test_bit(flt_type, &flt->type_mask)) | 126 | if (!test_bit(flt_type, &flt->type_mask)) |
126 | return true; | 127 | return true; |
127 | 128 | ||
128 | /* Extra filter for event packets only */ | 129 | /* Extra filter for event packets only */ |
129 | if (bt_cb(skb)->pkt_type != HCI_EVENT_PKT) | 130 | if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT) |
130 | return false; | 131 | return false; |
131 | 132 | ||
132 | flt_event = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS); | 133 | flt_event = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS); |
@@ -170,19 +171,19 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) | |||
170 | continue; | 171 | continue; |
171 | 172 | ||
172 | if (hci_pi(sk)->channel == HCI_CHANNEL_RAW) { | 173 | if (hci_pi(sk)->channel == HCI_CHANNEL_RAW) { |
173 | if (bt_cb(skb)->pkt_type != HCI_COMMAND_PKT && | 174 | if (hci_skb_pkt_type(skb) != HCI_COMMAND_PKT && |
174 | bt_cb(skb)->pkt_type != HCI_EVENT_PKT && | 175 | hci_skb_pkt_type(skb) != HCI_EVENT_PKT && |
175 | bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT && | 176 | hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && |
176 | bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) | 177 | hci_skb_pkt_type(skb) != HCI_SCODATA_PKT) |
177 | continue; | 178 | continue; |
178 | if (is_filtered_packet(sk, skb)) | 179 | if (is_filtered_packet(sk, skb)) |
179 | continue; | 180 | continue; |
180 | } else if (hci_pi(sk)->channel == HCI_CHANNEL_USER) { | 181 | } else if (hci_pi(sk)->channel == HCI_CHANNEL_USER) { |
181 | if (!bt_cb(skb)->incoming) | 182 | if (!bt_cb(skb)->incoming) |
182 | continue; | 183 | continue; |
183 | if (bt_cb(skb)->pkt_type != HCI_EVENT_PKT && | 184 | if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT && |
184 | bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT && | 185 | hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && |
185 | bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) | 186 | hci_skb_pkt_type(skb) != HCI_SCODATA_PKT) |
186 | continue; | 187 | continue; |
187 | } else { | 188 | } else { |
188 | /* Don't send frame to other channel types */ | 189 | /* Don't send frame to other channel types */ |
@@ -196,7 +197,7 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) | |||
196 | continue; | 197 | continue; |
197 | 198 | ||
198 | /* Put type byte before the data */ | 199 | /* Put type byte before the data */ |
199 | memcpy(skb_push(skb_copy, 1), &bt_cb(skb)->pkt_type, 1); | 200 | memcpy(skb_push(skb_copy, 1), &hci_skb_pkt_type(skb), 1); |
200 | } | 201 | } |
201 | 202 | ||
202 | nskb = skb_clone(skb_copy, GFP_ATOMIC); | 203 | nskb = skb_clone(skb_copy, GFP_ATOMIC); |
@@ -262,7 +263,7 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) | |||
262 | 263 | ||
263 | BT_DBG("hdev %p len %d", hdev, skb->len); | 264 | BT_DBG("hdev %p len %d", hdev, skb->len); |
264 | 265 | ||
265 | switch (bt_cb(skb)->pkt_type) { | 266 | switch (hci_skb_pkt_type(skb)) { |
266 | case HCI_COMMAND_PKT: | 267 | case HCI_COMMAND_PKT: |
267 | opcode = cpu_to_le16(HCI_MON_COMMAND_PKT); | 268 | opcode = cpu_to_le16(HCI_MON_COMMAND_PKT); |
268 | break; | 269 | break; |
@@ -294,7 +295,7 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) | |||
294 | return; | 295 | return; |
295 | 296 | ||
296 | /* Put header before the data */ | 297 | /* Put header before the data */ |
297 | hdr = (void *) skb_push(skb_copy, HCI_MON_HDR_SIZE); | 298 | hdr = (void *)skb_push(skb_copy, HCI_MON_HDR_SIZE); |
298 | hdr->opcode = opcode; | 299 | hdr->opcode = opcode; |
299 | hdr->index = cpu_to_le16(hdev->id); | 300 | hdr->index = cpu_to_le16(hdev->id); |
300 | hdr->len = cpu_to_le16(skb->len); | 301 | hdr->len = cpu_to_le16(skb->len); |
@@ -375,7 +376,7 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event) | |||
375 | 376 | ||
376 | __net_timestamp(skb); | 377 | __net_timestamp(skb); |
377 | 378 | ||
378 | hdr = (void *) skb_push(skb, HCI_MON_HDR_SIZE); | 379 | hdr = (void *)skb_push(skb, HCI_MON_HDR_SIZE); |
379 | hdr->opcode = opcode; | 380 | hdr->opcode = opcode; |
380 | hdr->index = cpu_to_le16(hdev->id); | 381 | hdr->index = cpu_to_le16(hdev->id); |
381 | hdr->len = cpu_to_le16(skb->len - HCI_MON_HDR_SIZE); | 382 | hdr->len = cpu_to_le16(skb->len - HCI_MON_HDR_SIZE); |
@@ -383,6 +384,38 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event) | |||
383 | return skb; | 384 | return skb; |
384 | } | 385 | } |
385 | 386 | ||
387 | static void __printf(2, 3) | ||
388 | send_monitor_note(struct sock *sk, const char *fmt, ...) | ||
389 | { | ||
390 | size_t len; | ||
391 | struct hci_mon_hdr *hdr; | ||
392 | struct sk_buff *skb; | ||
393 | va_list args; | ||
394 | |||
395 | va_start(args, fmt); | ||
396 | len = vsnprintf(NULL, 0, fmt, args); | ||
397 | va_end(args); | ||
398 | |||
399 | skb = bt_skb_alloc(len + 1, GFP_ATOMIC); | ||
400 | if (!skb) | ||
401 | return; | ||
402 | |||
403 | va_start(args, fmt); | ||
404 | vsprintf(skb_put(skb, len), fmt, args); | ||
405 | *skb_put(skb, 1) = 0; | ||
406 | va_end(args); | ||
407 | |||
408 | __net_timestamp(skb); | ||
409 | |||
410 | hdr = (void *)skb_push(skb, HCI_MON_HDR_SIZE); | ||
411 | hdr->opcode = cpu_to_le16(HCI_MON_SYSTEM_NOTE); | ||
412 | hdr->index = cpu_to_le16(HCI_DEV_NONE); | ||
413 | hdr->len = cpu_to_le16(skb->len - HCI_MON_HDR_SIZE); | ||
414 | |||
415 | if (sock_queue_rcv_skb(sk, skb)) | ||
416 | kfree_skb(skb); | ||
417 | } | ||
418 | |||
386 | static void send_monitor_replay(struct sock *sk) | 419 | static void send_monitor_replay(struct sock *sk) |
387 | { | 420 | { |
388 | struct hci_dev *hdev; | 421 | struct hci_dev *hdev; |
@@ -436,18 +469,18 @@ static void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data) | |||
436 | if (!skb) | 469 | if (!skb) |
437 | return; | 470 | return; |
438 | 471 | ||
439 | hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE); | 472 | hdr = (void *)skb_put(skb, HCI_EVENT_HDR_SIZE); |
440 | hdr->evt = HCI_EV_STACK_INTERNAL; | 473 | hdr->evt = HCI_EV_STACK_INTERNAL; |
441 | hdr->plen = sizeof(*ev) + dlen; | 474 | hdr->plen = sizeof(*ev) + dlen; |
442 | 475 | ||
443 | ev = (void *) skb_put(skb, sizeof(*ev) + dlen); | 476 | ev = (void *)skb_put(skb, sizeof(*ev) + dlen); |
444 | ev->type = type; | 477 | ev->type = type; |
445 | memcpy(ev->data, data, dlen); | 478 | memcpy(ev->data, data, dlen); |
446 | 479 | ||
447 | bt_cb(skb)->incoming = 1; | 480 | bt_cb(skb)->incoming = 1; |
448 | __net_timestamp(skb); | 481 | __net_timestamp(skb); |
449 | 482 | ||
450 | bt_cb(skb)->pkt_type = HCI_EVENT_PKT; | 483 | hci_skb_pkt_type(skb) = HCI_EVENT_PKT; |
451 | hci_send_to_sock(hdev, skb); | 484 | hci_send_to_sock(hdev, skb); |
452 | kfree_skb(skb); | 485 | kfree_skb(skb); |
453 | } | 486 | } |
@@ -653,20 +686,20 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, | |||
653 | return -EOPNOTSUPP; | 686 | return -EOPNOTSUPP; |
654 | 687 | ||
655 | case HCIGETCONNINFO: | 688 | case HCIGETCONNINFO: |
656 | return hci_get_conn_info(hdev, (void __user *) arg); | 689 | return hci_get_conn_info(hdev, (void __user *)arg); |
657 | 690 | ||
658 | case HCIGETAUTHINFO: | 691 | case HCIGETAUTHINFO: |
659 | return hci_get_auth_info(hdev, (void __user *) arg); | 692 | return hci_get_auth_info(hdev, (void __user *)arg); |
660 | 693 | ||
661 | case HCIBLOCKADDR: | 694 | case HCIBLOCKADDR: |
662 | if (!capable(CAP_NET_ADMIN)) | 695 | if (!capable(CAP_NET_ADMIN)) |
663 | return -EPERM; | 696 | return -EPERM; |
664 | return hci_sock_blacklist_add(hdev, (void __user *) arg); | 697 | return hci_sock_blacklist_add(hdev, (void __user *)arg); |
665 | 698 | ||
666 | case HCIUNBLOCKADDR: | 699 | case HCIUNBLOCKADDR: |
667 | if (!capable(CAP_NET_ADMIN)) | 700 | if (!capable(CAP_NET_ADMIN)) |
668 | return -EPERM; | 701 | return -EPERM; |
669 | return hci_sock_blacklist_del(hdev, (void __user *) arg); | 702 | return hci_sock_blacklist_del(hdev, (void __user *)arg); |
670 | } | 703 | } |
671 | 704 | ||
672 | return -ENOIOCTLCMD; | 705 | return -ENOIOCTLCMD; |
@@ -675,7 +708,7 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, | |||
675 | static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, | 708 | static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, |
676 | unsigned long arg) | 709 | unsigned long arg) |
677 | { | 710 | { |
678 | void __user *argp = (void __user *) arg; | 711 | void __user *argp = (void __user *)arg; |
679 | struct sock *sk = sock->sk; | 712 | struct sock *sk = sock->sk; |
680 | int err; | 713 | int err; |
681 | 714 | ||
@@ -872,11 +905,28 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, | |||
872 | */ | 905 | */ |
873 | hci_sock_set_flag(sk, HCI_SOCK_TRUSTED); | 906 | hci_sock_set_flag(sk, HCI_SOCK_TRUSTED); |
874 | 907 | ||
908 | send_monitor_note(sk, "Linux version %s (%s)", | ||
909 | init_utsname()->release, | ||
910 | init_utsname()->machine); | ||
911 | send_monitor_note(sk, "Bluetooth subsystem version %s", | ||
912 | BT_SUBSYS_VERSION); | ||
875 | send_monitor_replay(sk); | 913 | send_monitor_replay(sk); |
876 | 914 | ||
877 | atomic_inc(&monitor_promisc); | 915 | atomic_inc(&monitor_promisc); |
878 | break; | 916 | break; |
879 | 917 | ||
918 | case HCI_CHANNEL_LOGGING: | ||
919 | if (haddr.hci_dev != HCI_DEV_NONE) { | ||
920 | err = -EINVAL; | ||
921 | goto done; | ||
922 | } | ||
923 | |||
924 | if (!capable(CAP_NET_ADMIN)) { | ||
925 | err = -EPERM; | ||
926 | goto done; | ||
927 | } | ||
928 | break; | ||
929 | |||
880 | default: | 930 | default: |
881 | if (!hci_mgmt_chan_find(haddr.hci_channel)) { | 931 | if (!hci_mgmt_chan_find(haddr.hci_channel)) { |
882 | err = -EINVAL; | 932 | err = -EINVAL; |
@@ -926,7 +976,7 @@ done: | |||
926 | static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, | 976 | static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, |
927 | int *addr_len, int peer) | 977 | int *addr_len, int peer) |
928 | { | 978 | { |
929 | struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr; | 979 | struct sockaddr_hci *haddr = (struct sockaddr_hci *)addr; |
930 | struct sock *sk = sock->sk; | 980 | struct sock *sk = sock->sk; |
931 | struct hci_dev *hdev; | 981 | struct hci_dev *hdev; |
932 | int err = 0; | 982 | int err = 0; |
@@ -991,8 +1041,8 @@ static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, | |||
991 | } | 1041 | } |
992 | } | 1042 | } |
993 | 1043 | ||
994 | static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | 1044 | static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, |
995 | int flags) | 1045 | size_t len, int flags) |
996 | { | 1046 | { |
997 | int noblock = flags & MSG_DONTWAIT; | 1047 | int noblock = flags & MSG_DONTWAIT; |
998 | struct sock *sk = sock->sk; | 1048 | struct sock *sk = sock->sk; |
@@ -1004,6 +1054,9 @@ static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
1004 | if (flags & MSG_OOB) | 1054 | if (flags & MSG_OOB) |
1005 | return -EOPNOTSUPP; | 1055 | return -EOPNOTSUPP; |
1006 | 1056 | ||
1057 | if (hci_pi(sk)->channel == HCI_CHANNEL_LOGGING) | ||
1058 | return -EOPNOTSUPP; | ||
1059 | |||
1007 | if (sk->sk_state == BT_CLOSED) | 1060 | if (sk->sk_state == BT_CLOSED) |
1008 | return 0; | 1061 | return 0; |
1009 | 1062 | ||
@@ -1150,6 +1203,90 @@ done: | |||
1150 | return err; | 1203 | return err; |
1151 | } | 1204 | } |
1152 | 1205 | ||
1206 | static int hci_logging_frame(struct sock *sk, struct msghdr *msg, int len) | ||
1207 | { | ||
1208 | struct hci_mon_hdr *hdr; | ||
1209 | struct sk_buff *skb; | ||
1210 | struct hci_dev *hdev; | ||
1211 | u16 index; | ||
1212 | int err; | ||
1213 | |||
1214 | /* The logging frame consists at minimum of the standard header, | ||
1215 | * the priority byte, the ident length byte and at least one string | ||
1216 | * terminator NUL byte. Anything shorter are invalid packets. | ||
1217 | */ | ||
1218 | if (len < sizeof(*hdr) + 3) | ||
1219 | return -EINVAL; | ||
1220 | |||
1221 | skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err); | ||
1222 | if (!skb) | ||
1223 | return err; | ||
1224 | |||
1225 | if (memcpy_from_msg(skb_put(skb, len), msg, len)) { | ||
1226 | err = -EFAULT; | ||
1227 | goto drop; | ||
1228 | } | ||
1229 | |||
1230 | hdr = (void *)skb->data; | ||
1231 | |||
1232 | if (__le16_to_cpu(hdr->len) != len - sizeof(*hdr)) { | ||
1233 | err = -EINVAL; | ||
1234 | goto drop; | ||
1235 | } | ||
1236 | |||
1237 | if (__le16_to_cpu(hdr->opcode) == 0x0000) { | ||
1238 | __u8 priority = skb->data[sizeof(*hdr)]; | ||
1239 | __u8 ident_len = skb->data[sizeof(*hdr) + 1]; | ||
1240 | |||
1241 | /* Only the priorities 0-7 are valid and with that any other | ||
1242 | * value results in an invalid packet. | ||
1243 | * | ||
1244 | * The priority byte is followed by an ident length byte and | ||
1245 | * the NUL terminated ident string. Check that the ident | ||
1246 | * length is not overflowing the packet and also that the | ||
1247 | * ident string itself is NUL terminated. In case the ident | ||
1248 | * length is zero, the length value actually doubles as NUL | ||
1249 | * terminator identifier. | ||
1250 | * | ||
1251 | * The message follows the ident string (if present) and | ||
1252 | * must be NUL terminated. Otherwise it is not a valid packet. | ||
1253 | */ | ||
1254 | if (priority > 7 || skb->data[len - 1] != 0x00 || | ||
1255 | ident_len > len - sizeof(*hdr) - 3 || | ||
1256 | skb->data[sizeof(*hdr) + ident_len + 1] != 0x00) { | ||
1257 | err = -EINVAL; | ||
1258 | goto drop; | ||
1259 | } | ||
1260 | } else { | ||
1261 | err = -EINVAL; | ||
1262 | goto drop; | ||
1263 | } | ||
1264 | |||
1265 | index = __le16_to_cpu(hdr->index); | ||
1266 | |||
1267 | if (index != MGMT_INDEX_NONE) { | ||
1268 | hdev = hci_dev_get(index); | ||
1269 | if (!hdev) { | ||
1270 | err = -ENODEV; | ||
1271 | goto drop; | ||
1272 | } | ||
1273 | } else { | ||
1274 | hdev = NULL; | ||
1275 | } | ||
1276 | |||
1277 | hdr->opcode = cpu_to_le16(HCI_MON_USER_LOGGING); | ||
1278 | |||
1279 | hci_send_to_channel(HCI_CHANNEL_MONITOR, skb, HCI_SOCK_TRUSTED, NULL); | ||
1280 | err = len; | ||
1281 | |||
1282 | if (hdev) | ||
1283 | hci_dev_put(hdev); | ||
1284 | |||
1285 | drop: | ||
1286 | kfree_skb(skb); | ||
1287 | return err; | ||
1288 | } | ||
1289 | |||
1153 | static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, | 1290 | static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, |
1154 | size_t len) | 1291 | size_t len) |
1155 | { | 1292 | { |
@@ -1179,6 +1316,9 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1179 | case HCI_CHANNEL_MONITOR: | 1316 | case HCI_CHANNEL_MONITOR: |
1180 | err = -EOPNOTSUPP; | 1317 | err = -EOPNOTSUPP; |
1181 | goto done; | 1318 | goto done; |
1319 | case HCI_CHANNEL_LOGGING: | ||
1320 | err = hci_logging_frame(sk, msg, len); | ||
1321 | goto done; | ||
1182 | default: | 1322 | default: |
1183 | mutex_lock(&mgmt_chan_list_lock); | 1323 | mutex_lock(&mgmt_chan_list_lock); |
1184 | chan = __hci_mgmt_chan_find(hci_pi(sk)->channel); | 1324 | chan = __hci_mgmt_chan_find(hci_pi(sk)->channel); |
@@ -1211,7 +1351,7 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1211 | goto drop; | 1351 | goto drop; |
1212 | } | 1352 | } |
1213 | 1353 | ||
1214 | bt_cb(skb)->pkt_type = *((unsigned char *) skb->data); | 1354 | hci_skb_pkt_type(skb) = skb->data[0]; |
1215 | skb_pull(skb, 1); | 1355 | skb_pull(skb, 1); |
1216 | 1356 | ||
1217 | if (hci_pi(sk)->channel == HCI_CHANNEL_USER) { | 1357 | if (hci_pi(sk)->channel == HCI_CHANNEL_USER) { |
@@ -1220,16 +1360,16 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1220 | * | 1360 | * |
1221 | * However check that the packet type is valid. | 1361 | * However check that the packet type is valid. |
1222 | */ | 1362 | */ |
1223 | if (bt_cb(skb)->pkt_type != HCI_COMMAND_PKT && | 1363 | if (hci_skb_pkt_type(skb) != HCI_COMMAND_PKT && |
1224 | bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT && | 1364 | hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && |
1225 | bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) { | 1365 | hci_skb_pkt_type(skb) != HCI_SCODATA_PKT) { |
1226 | err = -EINVAL; | 1366 | err = -EINVAL; |
1227 | goto drop; | 1367 | goto drop; |
1228 | } | 1368 | } |
1229 | 1369 | ||
1230 | skb_queue_tail(&hdev->raw_q, skb); | 1370 | skb_queue_tail(&hdev->raw_q, skb); |
1231 | queue_work(hdev->workqueue, &hdev->tx_work); | 1371 | queue_work(hdev->workqueue, &hdev->tx_work); |
1232 | } else if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { | 1372 | } else if (hci_skb_pkt_type(skb) == HCI_COMMAND_PKT) { |
1233 | u16 opcode = get_unaligned_le16(skb->data); | 1373 | u16 opcode = get_unaligned_le16(skb->data); |
1234 | u16 ogf = hci_opcode_ogf(opcode); | 1374 | u16 ogf = hci_opcode_ogf(opcode); |
1235 | u16 ocf = hci_opcode_ocf(opcode); | 1375 | u16 ocf = hci_opcode_ocf(opcode); |
@@ -1242,6 +1382,11 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1242 | goto drop; | 1382 | goto drop; |
1243 | } | 1383 | } |
1244 | 1384 | ||
1385 | /* Since the opcode has already been extracted here, store | ||
1386 | * a copy of the value for later use by the drivers. | ||
1387 | */ | ||
1388 | hci_skb_opcode(skb) = opcode; | ||
1389 | |||
1245 | if (ogf == 0x3f) { | 1390 | if (ogf == 0x3f) { |
1246 | skb_queue_tail(&hdev->raw_q, skb); | 1391 | skb_queue_tail(&hdev->raw_q, skb); |
1247 | queue_work(hdev->workqueue, &hdev->tx_work); | 1392 | queue_work(hdev->workqueue, &hdev->tx_work); |
@@ -1249,7 +1394,7 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1249 | /* Stand-alone HCI commands must be flagged as | 1394 | /* Stand-alone HCI commands must be flagged as |
1250 | * single-command requests. | 1395 | * single-command requests. |
1251 | */ | 1396 | */ |
1252 | bt_cb(skb)->hci.req_start = true; | 1397 | bt_cb(skb)->hci.req_flags |= HCI_REQ_START; |
1253 | 1398 | ||
1254 | skb_queue_tail(&hdev->cmd_q, skb); | 1399 | skb_queue_tail(&hdev->cmd_q, skb); |
1255 | queue_work(hdev->workqueue, &hdev->cmd_work); | 1400 | queue_work(hdev->workqueue, &hdev->cmd_work); |
@@ -1260,8 +1405,8 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1260 | goto drop; | 1405 | goto drop; |
1261 | } | 1406 | } |
1262 | 1407 | ||
1263 | if (bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT && | 1408 | if (hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && |
1264 | bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) { | 1409 | hci_skb_pkt_type(skb) != HCI_SCODATA_PKT) { |
1265 | err = -EINVAL; | 1410 | err = -EINVAL; |
1266 | goto drop; | 1411 | goto drop; |
1267 | } | 1412 | } |