OSDN Git Service

monitor: Add support for handling Broadcom vendor commands
authorMarcel Holtmann <marcel@holtmann.org>
Sat, 17 Oct 2015 22:22:06 +0000 (00:22 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Sat, 17 Oct 2015 22:28:22 +0000 (00:28 +0200)
monitor/broadcom.c
monitor/broadcom.h
monitor/packet.c
monitor/vendor.h

index b9c70b4..7c76b97 100644 (file)
 #include "packet.h"
 #include "lmp.h"
 #include "ll.h"
+#include "vendor.h"
 #include "broadcom.h"
 
+static const struct vendor_ocf vendor_ocf_table[] = {
+       { 0x001, "Write BD ADDR"                        },
+       { 0x018, "Update UART Baud Rate"                },
+       { 0x027, "Set Sleepmode Param"                  },
+       { 0x02e, "Download Minidriver"                  },
+       { 0x03b, "Enable USB HID Emulation"             },
+       { 0x045, "Write UART Clock Setting"             },
+       { 0x04c, "Write RAM"                            },
+       { 0x04e, "Launch RAM"                           },
+       { 0x05a, "Read VID PID"                         },
+       { 0x079, "Read Verbose Config Version Info"     },
+       { }
+};
+
+const struct vendor_ocf *broadcom_vendor_ocf(uint16_t ocf)
+{
+       int i;
+
+       for (i = 0; vendor_ocf_table[i].str; i++) {
+               if (vendor_ocf_table[i].ocf == ocf)
+                       return &vendor_ocf_table[i];
+       }
+
+       return NULL;
+}
+
 void broadcom_lm_diag(const void *data, uint8_t size)
 {
        uint8_t type;
index 2aec912..f91f25b 100644 (file)
@@ -24,4 +24,7 @@
 
 #include <stdint.h>
 
+struct vendor_ocf;
+
+const struct vendor_ocf *broadcom_vendor_ocf(uint16_t ocf);
 void broadcom_lm_diag(const void *data, uint8_t size);
index 439b5dc..a353193 100644 (file)
@@ -7256,6 +7256,23 @@ static const char *get_supported_command(int bit)
        return NULL;
 }
 
+static const struct vendor_ocf *current_vendor_ocf(uint16_t ocf)
+{
+       uint16_t manufacturer;
+
+       if (index_current < MAX_INDEX)
+               manufacturer = index_list[index_current].manufacturer;
+       else
+               manufacturer = UNKNOWN_MANUFACTURER;
+
+       switch (manufacturer) {
+       case 15:
+               return broadcom_vendor_ocf(ocf);
+       }
+
+       return NULL;
+}
+
 static void inquiry_complete_evt(const void *data, uint8_t size)
 {
        const struct bt_hci_evt_inquiry_complete *evt = data;
@@ -7404,6 +7421,7 @@ static void cmd_complete_evt(const void *data, uint8_t size)
        uint16_t opcode = le16_to_cpu(evt->opcode);
        uint16_t ogf = cmd_opcode_ogf(opcode);
        uint16_t ocf = cmd_opcode_ocf(opcode);
+       struct opcode_data vendor_data;
        const struct opcode_data *opcode_data = NULL;
        const char *opcode_color, *opcode_str;
        int i;
@@ -7423,8 +7441,20 @@ static void cmd_complete_evt(const void *data, uint8_t size)
                opcode_str = opcode_data->str;
        } else {
                if (ogf == 0x3f) {
-                       opcode_color = COLOR_HCI_COMMAND;
-                       opcode_str = "Vendor";
+                       const struct vendor_ocf *vnd = current_vendor_ocf(ocf);
+
+                       if (vnd) {
+                               vendor_data.str = vnd->str;
+                               vendor_data.rsp_func = NULL;
+
+                               opcode_data = &vendor_data;
+
+                               opcode_color = COLOR_HCI_COMMAND;
+                               opcode_str = opcode_data->str;
+                       } else {
+                               opcode_color = COLOR_HCI_COMMAND;
+                               opcode_str = "Vendor";
+                       }
                } else {
                        opcode_color = COLOR_HCI_COMMAND_UNKNOWN;
                        opcode_str = "Unknown";
@@ -8570,6 +8600,7 @@ void packet_hci_command(struct timeval *tv, uint16_t index,
        uint16_t opcode = le16_to_cpu(hdr->opcode);
        uint16_t ogf = cmd_opcode_ogf(opcode);
        uint16_t ocf = cmd_opcode_ocf(opcode);
+       struct opcode_data vendor_data;
        const struct opcode_data *opcode_data = NULL;
        const char *opcode_color, *opcode_str;
        char extra_str[25];
@@ -8601,8 +8632,20 @@ void packet_hci_command(struct timeval *tv, uint16_t index,
                opcode_str = opcode_data->str;
        } else {
                if (ogf == 0x3f) {
-                       opcode_color = COLOR_HCI_COMMAND;
-                       opcode_str = "Vendor";
+                       const struct vendor_ocf *vnd = current_vendor_ocf(ocf);
+
+                       if (vnd) {
+                               vendor_data.str = vnd->str;
+                               vendor_data.cmd_func = NULL;
+
+                               opcode_data = &vendor_data;
+
+                               opcode_color = COLOR_HCI_COMMAND;
+                               opcode_str = opcode_data->str;
+                       } else {
+                               opcode_color = COLOR_HCI_COMMAND;
+                               opcode_str = "Vendor";
+                       }
                } else {
                        opcode_color = COLOR_HCI_COMMAND_UNKNOWN;
                        opcode_str = "Unknown";
index 9ac9a4b..be7baab 100644 (file)
 
 #include <stdint.h>
 
+struct vendor_ocf {
+       uint16_t ocf;
+       const char *str;
+       void (*cmd_func) (const void *data, uint8_t size);
+       uint8_t cmd_size;
+       bool cmd_fixed;
+       void (*rsp_func) (const void *data, uint8_t size);
+       uint8_t rsp_size;
+       bool rsp_fixed;
+};
+
 void vendor_event(uint16_t manufacturer, const void *data, uint8_t size);