USBFN Dump Packet Patchset

来源:互联网 发布:阿里云虚拟主机 编辑:程序博客网 时间:2024/05/19 14:54

1 Diag

diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index 734552c..fe682fd 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -209,6 +209,99 @@ static void diag_update_pid_and_serial_num(struct diag_context *ctxt)
         }
 }
 
+// oem-start
+// ref to <vendor/qcom/proprietary/diag/include/diagcmd.h>
+// <PeripheralManagerServer.cpp>
+// Solution:
+// 00022553 How to generate crash individual cores through QXDM
+
+//#define HOOK_CMD_CODE
+#define CMD_CODE 39    // 39: write nv, 38: read nv, 75: ss crash
+
+static void oem_dump_diag_packet(bool epout, struct usb_request *req)
+{
+    char *buf = req->buf;
+    unsigned int len = req->actual;
+    unsigned int i = 0;
+    unsigned char cmd_code = 0;
+    unsigned char subsys_id = 0;
+    unsigned short subsys_cmd_code = 0;
+
+#if defined(HOOK_CMD_CODE)
+    if (CMD_CODE == buf[0]) {
+        printk("[oem][diag][%s]: %d bytes\n",
+            epout ? "request" : "response", len);
+        cmd_code = buf[0];
+        subsys_id = buf[1];
+        printk("    cmd_code: 0x%02x\n", cmd_code);
+        printk("    subsys_id: 0x%02x\n", subsys_id);
+
+        if (len >= 4) {
+            subsys_cmd_code = get_unaligned_le16(&buf[2]);
+            printk("    subsys_cmd_code: 0x%04x\n",
+                subsys_cmd_code);
+            if (len > 255) {
+                printk("    Too long data, don't print");
+                goto hook_out;
+            }
+            printk("    ");
+            for (i = 4; i < len; i++) {
+                printk("%02x ", buf[i]);
+            }
+        } else {
+            if (len > 255) {
+                printk("    Too long data, don't print");
+                goto hook_out;
+            }
+            printk("    ");
+            for (i = 2; i < len; i++) {
+                printk("%02x ", buf[i]);
+            }
+        }
+hook_out:
+        printk("\n");
+        if (!epout) {
+            printk("\n");
+        }
+    }
+#else
+    printk("[oem][diag][%s]: %d bytes\n",
+        epout ? "request" : "response", len);
+    cmd_code = buf[0];
+    subsys_id = buf[1];
+    printk("    cmd_code: 0x%02x\n", cmd_code);
+    printk("    subsys_id: 0x%02x\n", subsys_id);
+
+    if (len >= 4) {
+        subsys_cmd_code = get_unaligned_le16(&buf[2]);
+        printk("    subsys_cmd_code: 0x%04x\n", subsys_cmd_code);
+        if (len > 255) {
+            printk("    Too long data, don't print");
+            goto out;
+        }
+        printk("    ");
+        for (i = 4; i < len; i++) {
+            printk("%02x ", buf[i]);
+        }
+    } else {
+        if (len > 255) {
+            printk("    Too long data, don't print");
+            goto out;
+        }
+        printk("    ");
+        for (i = 2; i < len; i++) {
+            printk("%02x ", buf[i]);
+        }
+    }
+out:
+    printk("\n");
+    if (!epout) {
+        printk("\n");
+    }
+#endif
+}
+// oem-end
+
 static void diag_write_complete(struct usb_ep *ep,
         struct usb_request *req)
 {
@@ -216,6 +309,9 @@ static void diag_write_complete(struct usb_ep *ep,
     struct diag_request *d_req = req->context;
     unsigned long flags;
 
+    // oem-start
+    oem_dump_diag_packet(false, req);
+    // oem-end
     ctxt->dpkts_tolaptop_pending--;
 
     if (!req->status) {
@@ -250,6 +346,9 @@ static void diag_read_complete(struct usb_ep *ep,
     struct diag_request *d_req = req->context;
     unsigned long flags;
 
+    // oem-start
+    oem_dump_diag_packet(true, req);
+    // oem-end
     d_req->actual = req->actual;
     d_req->status = req->status;

2 MBIM

diff --git a/drivers/usb/gadget/f_mbim.c b/drivers/usb/gadget/f_mbim.c
index c7dbacf..5803ce4 100644
--- a/drivers/usb/gadget/f_mbim.c
+++ b/drivers/usb/gadget/f_mbim.c
@@ -983,6 +983,95 @@ invalid:
     return;
 }
 
+// oem-start
+/************************************************
+ * 80-NF403-1_PRESENTATION_MBIM OVERVIEW.pdf
+ * MBIM v1 0 - errata-1.pdf
+ ***********************************************/
+// Data format:
+// 12 bytes MessageHeader[0-11] (= MessageType[0-3] + ...) +
+// payload[12-N] (= FragmentHeader[12-19] + UUID[20-35] + CID[36-39] + ...)
+
+// MBIM_OPEN_MSG 1
+// MBIM_CLOSE_MSG 2
+// MBIM_COMMAND_MSG 3
+// MBIM_HOST_ERROR_MSG 4
+// MBIM_OPEN_DONE 80000001h
+// MBIM_CLOSE_DONE 80000002h
+// MBIM_COMMAND_DONE 80000003h
+// MBIM_FUNCTION_ERROR_MSG 80000004h
+// MBIM_INDICATE_STATUS_MSG 80000007h
+
+static void oem_dump_mbim_cmd(bool epout, struct usb_request *req,
+                            int epin_len)
+{
+    unsigned char *buf = req->buf;
+    unsigned len = epout ? req->actual : epin_len;
+    unsigned int cmd;
+    unsigned int transaction_id;
+    unsigned int status;
+    unsigned int curr_frag;
+    unsigned int cid;
+    unsigned int i = 0;
+
+    if (!buf) {
+        return;
+    }
+
+    if (buf[0] <= 4) {
+        // 1) MessageHeader, 12 bytes
+        cmd = (unsigned int)buf[0];
+        cmd |= ((unsigned int)buf[1]) << 8;
+        cmd |= ((unsigned int)buf[2]) << 16;
+        cmd |= ((unsigned int)buf[3]) << 24;
+        transaction_id = (unsigned int)buf[8];
+        transaction_id |= ((unsigned int)buf[9]) << 8;
+        transaction_id |= ((unsigned int)buf[10]) << 16;
+        transaction_id |= ((unsigned int)buf[11]) << 24;
+        printk("[oem][mbim][%s]\n",
+                epout? "request" : "response");
+        printk("  cmd:        0x%08x\n", cmd);
+        printk("  transaction_id:    %d\n", transaction_id);
+
+        // MBIM_OPEN_DONE
+        if ((buf[0] == 1) && !epout) {
+            // 2) Status, 4 bytes
+            status = (unsigned int)buf[12];
+            status |= ((unsigned int)buf[13]) << 8;
+            status |= ((unsigned int)buf[14]) << 16;
+            status |= ((unsigned int)buf[15]) << 24;
+            printk("  status: %d\n", status);
+        }
+        // MBIM_COMMAND
+        if ((buf[0] == 3) && (len >= 40)) {
+            // 2) FragmentHeader, 8 bytes
+            curr_frag = (unsigned int)buf[16];
+            curr_frag |= ((unsigned int)buf[17]) << 8;
+            curr_frag |= ((unsigned int)buf[18]) << 16;
+            curr_frag |= ((unsigned int)buf[19]) << 24;
+
+            if (curr_frag == 0) {
+                // 3) UUID, 16 bytes
+                printk("  uuid: ");
+                for (i = 20; i < 36; i++) {
+                    printk("%02x ", buf[i]);
+                }
+                printk("\n");
+                // 4) CID, 4 bytes
+                cid = (unsigned int)buf[36];
+                cid |= ((unsigned int)buf[37]) << 8;
+                cid |= ((unsigned int)buf[38]) << 16;
+                cid |= ((unsigned int)buf[39]) << 24;
+                printk("  cid:    %d\n", cid);
+            }
+        }
+    }
+    if (!epout) {
+        printk("\n");
+    }
+}
+// oem-end
+
 static void
 fmbim_cmd_complete(struct usb_ep *ep, struct usb_request *req)
 {
@@ -1016,6 +1105,10 @@ fmbim_cmd_complete(struct usb_ep *ep, struct usb_request *req)
     list_add_tail(&cpkt->list, &dev->cpkt_req_q);
     spin_unlock(&dev->lock);
 
+    // oem-start
+    oem_dump_mbim_cmd(true, req, 0);
+    // oem-end
+
     /* wakeup read thread */
     pr_debug("Wake up read queue\n");
     wake_up(&dev->read_wq);
@@ -1102,6 +1195,9 @@ mbim_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
         pr_debug("copied encapsulated_response %d bytes\n",
             value);
 
+        // oem-start
+        oem_dump_mbim_cmd(false, req, value);
+        // oem-end
         break;
 
     case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)

3 MTP

diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index 5a06296..cf0665d 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -431,6 +431,120 @@ static struct usb_request
     return req;
 }
 
+// oem-start
+// @mtp.h
+// COMMAND/DATA/RESPONSE -> MTP_CONTAINER_HEADER_SIZE(12)
+// Data format:
+// 12 bytes header[0-11] + payload[12-N]
+
+#define oem_dbg(fmt, args...) do { \
+    printk(fmt, ##args);    \
+} while(0)
+
+static void oem_dump_mtp_packet(bool epout, struct usb_request *req)
+{
+    unsigned char *buf = req->buf;
+    unsigned int msg_len;
+    unsigned short type;
+    unsigned short cmd;
+    unsigned int arg0 = 0;
+    unsigned int ii = 0;
+
+    if (!buf) {
+        return;
+    }
+
+    msg_len = get_unaligned_le32(&buf[0]);
+    type = get_unaligned_le16(&buf[4]);
+    cmd = get_unaligned_le16(&buf[6]);
+
+    switch (type) {
+        // COMMAND
+        case 1:
+            oem_dbg(KERN_DEBUG "------------------------\n");
+            if (msg_len >= 16) {
+                arg0 = get_unaligned_le32(&buf[12]);
+                oem_dbg(KERN_DEBUG
+                    "[oem][mtp][request]\n");
+                oem_dbg(KERN_DEBUG "  code: 0x%04x\n",
+                    cmd);
+                oem_dbg(KERN_DEBUG "  ID_or_handle=0x%x\n",
+                    arg0);
+            } else {
+                oem_dbg(KERN_DEBUG "[oem][mtp][request]\n");
+                oem_dbg(KERN_DEBUG "  code: 0x%04x\n", cmd);
+                oem_dbg(KERN_DEBUG
+                    "  payload: %d bytes\n",
+                    msg_len - 12);
+            }
+            break;
+        // RESPONSE, 0x2001 means OK, see mtp.h
+        case 3:
+            if (msg_len >= 16) {
+                arg0 = get_unaligned_le32(&buf[12]);
+                oem_dbg(KERN_DEBUG
+                    "[oem][mtp][response]\n");
+                oem_dbg(KERN_DEBUG "  code: 0x%04x\n",
+                    cmd);
+                oem_dbg(KERN_DEBUG
+                    "  ID_or_handle=0x%x\n",
+                    arg0);
+            } else {
+                oem_dbg(KERN_DEBUG
+                    "[oem][mtp][response]\n");
+                if (cmd != 0x2001) {
+                    oem_dbg(KERN_DEBUG
+                        "  #####????\n");
+                }
+                oem_dbg(KERN_DEBUG
+                    "  code: 0x%04x\n", cmd);
+                oem_dbg(KERN_DEBUG
+                    "  payload: %d bytes\n",
+                    msg_len - 12);
+            }
+            oem_dbg(KERN_DEBUG "------------------------\n\n");
+            break;
+        // EVENT
+        case 4:
+            // MTP_EVENT_OBJECT_ADDED   0x4002
+            // MTP_EVENT_OBJECT_REMOVED  0x4003
+            if ((cmd == 0x4002 || cmd == 0x4003) &&
+                (msg_len >= 16)) {
+                arg0 = get_unaligned_le32(&buf[12]);
+                oem_dbg(KERN_DEBUG "[oem][mtp][event]\n");
+                oem_dbg(KERN_DEBUG "  code: 0x%04x\n",
+                    cmd);
+                oem_dbg(KERN_DEBUG "  handle=%d\n\n",
+                    arg0);
+            }
+            break;
+        // DATA
+        case 2:
+            if (cmd == 0x1004 && !epout &&
+                (msg_len >= 16)) {
+                arg0 = get_unaligned_le32(&buf[12]);
+                oem_dbg(KERN_DEBUG "[oem][mtp][data]\n");
+                oem_dbg(KERN_DEBUG
+                    "  %d storages\n",
+                    arg0);
+                for (ii = 0; ii < arg0; ii++) {
+                    oem_dbg(KERN_DEBUG
+                    "[oem][mtp][data] "
+                    "storageID: 0x%0x\n",
+                    get_unaligned_le32(&buf[16+ii*4]));
+                }
+            } else if (cmd == 0x1007 && !epout &&
+                (msg_len >= 16)) {
+                arg0 = get_unaligned_le32(&buf[12]);
+                oem_dbg(KERN_DEBUG "[oem][mtp][data]\n");
+                oem_dbg(KERN_DEBUG "  %d items\n",
+                    arg0);
+            }
+            break;
+    }
+}
+// oem-end
+
 static void mtp_complete_in(struct usb_ep *ep, struct usb_request *req)
 {
     struct mtp_dev *dev = _mtp_dev;
@@ -438,6 +552,10 @@ static void mtp_complete_in(struct usb_ep *ep, struct usb_request *req)
     if (req->status != 0)
         dev->state = STATE_ERROR;
 
+    // oem-start
+    oem_dump_mtp_packet(false, req);
+    // oem-end
+
     mtp_req_put(dev, &dev->tx_idle, req);
 
     wake_up(&dev->write_wq);
@@ -451,6 +569,10 @@ static void mtp_complete_out(struct usb_ep *ep, struct usb_request *req)
     if (req->status != 0)
         dev->state = STATE_ERROR;
 
+    // oem-start
+    oem_dump_mtp_packet(true, req);
+    // oem-end
+
     wake_up(&dev->read_wq);
 }
 
@@ -461,6 +583,10 @@ static void mtp_complete_intr(struct usb_ep *ep, struct usb_request *req)
     if (req->status != 0)
         dev->state = STATE_ERROR;
 
+    // oem-start
+    oem_dump_mtp_packet(false, req);
+    // oem-end
+
     mtp_req_put(dev, &dev->intr_idle, req);
 
     wake_up(&dev->intr_wq);

4 RMNET

diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index a92570f0..b000f13 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -991,6 +991,219 @@ frmnet_send_cpkt_response(void *gr, void *buf, size_t len)
     return 0;
 }
 
+// oem-start
+/************************************************
+ *80-VB816-1_A_QMI_Architecture.pdf
+ *80-NV304-6 QMI NAS 1.156 for MPSS.JO.1.2
+ ***********************************************/
+#undef HOOK_MSG
+#if defined(HOOK_MSG)
+#define qmi_dbg(fmt, args...)
+
+////////////////////////////////////////////////
+#define QMINAS_SERVING_SYSTEM_IND           0x0024
+////////////////////////////////////////////////
+
+static bool is_hooked = false;
+
+#else
+#define qmi_dbg(fmt, args...) do { \
+    printk(fmt, ##args);    \
+} while(0)
+#endif
+
+#define qmi_dbg2(fmt, args...) do { \
+    printk(fmt, ##args); \
+} while(0)
+
+#define OEM_DUMP_FORMAT_SDU
+#if defined(OEM_DUMP_FORMAT_SDU)
+static void oem_dump_format_sdu(bool epout,
+                unsigned int msg_type,
+                char *sdu,
+                unsigned int sdu_len)
+{
+    unsigned char *p = (unsigned char *)sdu;
+    unsigned short msg_id;
+    unsigned short length;
+    unsigned int i = 0, j = 0, count = 0;
+    int _sdu_len = sdu_len;
+    // TLV variable
+    unsigned char tlv_type;
+    unsigned short tlv_length;
+
+    if (!p) {
+        return;
+    }
+
+    for (; (_sdu_len > 0) && p;) {
+        msg_id = get_unaligned_le16(&p[0]);
+        length = get_unaligned_le16(&p[2]);
+
+#if defined(HOOK_MSG)
+        is_hooked = false;
+        if (msg_id == QMINAS_SERVING_SYSTEM_IND) {
+            qmi_dbg2(">>>>>> [oem][rmnet][%s]\n",
+                msg_type == 0 ? "request" :
+                (msg_type == 1 ? "response" :
+                "indication"));
+            qmi_dbg2("TLV header[9-12]:\n");
+            qmi_dbg2("  QMI_MsgId    = 0x%04x\n", msg_id);
+            qmi_dbg2("  tlv_length    = %d\n", length);
+            is_hooked = true;
+        }
+#else
+        qmi_dbg2("TLV header[9-12]:\n");
+        qmi_dbg2("  QMI_MsgId        = 0x%04x\n", msg_id);
+        qmi_dbg2("  tlv_length        = %d\n", length);
+#endif
+        p += 4;
+        _sdu_len -= 4;
+        if (length > _sdu_len) {
+            qmi_dbg2("  Invalid message, "
+                "goto next QMI_MsgId\n\n");
+            break;
+        }
+
+        // 3) TLV(Argument)
+        for (i = 0; i < length;) {
+            tlv_type = p[0];
+            tlv_length = get_unaligned_le16(&p[1]);
+#if defined(HOOK_MSG)
+            if (is_hooked) {
+                qmi_dbg2("Arg%d:\n", count++);
+                qmi_dbg2("  type    = 0x%02x\n",
+                    tlv_type);
+                qmi_dbg2("  length    = %d\n",
+                    tlv_length);
+                qmi_dbg2("  value    = ");
+            }
+#else
+            qmi_dbg2("Arg%d:\n", count++);
+            qmi_dbg2("  type    = 0x%02x\n", tlv_type);
+            qmi_dbg2("  length    = %d\n", tlv_length);
+            qmi_dbg2("  value    = ");
+#endif
+            p += 3;
+            _sdu_len -= 3;
+#if defined(HOOK_MSG)
+            if (is_hooked) {
+                for (j = 0; j < tlv_length; j++) {
+                    qmi_dbg2("%02x ", p[j]);
+                }
+                qmi_dbg2("\n\n");
+            }
+#else
+            for (j = 0; j < tlv_length; j++) {
+                qmi_dbg2("%02x ", p[j]);
+            }
+            qmi_dbg2("\n");
+#endif
+
+            p += tlv_length;
+            _sdu_len -= tlv_length;
+            i += (3 + tlv_length);
+        }
+
+#if !defined(HOOK_MSG)
+        qmi_dbg2(">>>>>> Residue %d bytes\n\n", _sdu_len);
+#endif
+        if (_sdu_len <= 0) {
+            return;
+        }
+    }
+}
+#endif
+
+static void oem_dump_qmi_packet(bool epout, unsigned char *buff,
+                int buf_len)
+{
+    unsigned char *buf = buff;
+#if defined(OEM_DUMP_FORMAT_SDU)
+    unsigned char *p;
+#else
+    unsigned int i = 0;
+#endif
+    unsigned len = buf_len;
+    unsigned int if_type;
+    unsigned short msg_len;
+    unsigned char svc_type;
+    unsigned char client_id;
+    unsigned char control_flags;
+    unsigned short transaction_id;
+    unsigned int msg_type = 0;
+
+    if (!buf || len < 6) {
+        return;
+    }
+
+    if_type = buf[0];
+    msg_len = get_unaligned_le16(&buf[1]);
+    svc_type = buf[4];
+    client_id = buf[5];
+
+    if ((msg_len - 5/*QMUX header*/ - 3/*QMI header*/)
+        >= 4/*TLV header(msg_id + length)*/) {
+        control_flags = buf[6];
+        transaction_id = get_unaligned_le16(&buf[7]);
+
+        msg_type = (control_flags >> 1) & 0x3;
+
+        // 1) QMUX
+        qmi_dbg(">>>>>> [oem][rmnet][%s]\n",
+            msg_type == 0 ? "request" :
+            (msg_type == 1 ? "response" : "indication"));
+        qmi_dbg("QMUX header[0-5]:\n");
+        qmi_dbg("  if_type    = 0x%02x\n", if_type);
+        qmi_dbg("  sdu_len    = %d\n", msg_len - 5);
+        qmi_dbg("  svc_type    = 0x%02x\n", svc_type);
+        qmi_dbg("  client_id    = 0x%02x\n", client_id);
+
+        // 2) QMI
+        qmi_dbg("QMI header[6-8]:\n");
+        qmi_dbg("  control_flags    = 0x%02x\n",
+            control_flags);
+        qmi_dbg("  transaction_id    = 0x%04x\n",
+            transaction_id);
+
+#if defined(OEM_DUMP_FORMAT_SDU)
+        p = buf;
+        p += (6 + 3);
+        oem_dump_format_sdu(epout, msg_type, p, msg_len - 8);
+#else
+        printk(">>>>>> ");
+        for (i = 0; i < msg_len - 8; i++) {
+            printk("%02x ", buf[9+i]);
+        }
+        printk("\n\n");
+#endif
+    }
+}
+
+// Data format:
+// 1 bytes if_type[0] +
+// 5 bytes QMUX header[1-5] +
+// 3 bytes QMI header[6-8] +
+// 4 bytes TLV header(msg_id + length)[9-12] +
+// payload[13-N] = response-result(13-19) + tlv,
+// response-result[13-19] start 0x02,4,x,x,x,x, refer to "ndis/MPQMI.h"
+static void oem_dump_qmi(bool epout, struct usb_request *req,
+                int epin_len)
+{
+    unsigned int msg_len = 0;
+    unsigned char *buf = req->buf;
+    int len = epout ? req->actual : epin_len;
+
+    while(len > 0) {
+        msg_len = get_unaligned_le16(&buf[1]);
+        msg_len++; // including if_type
+        oem_dump_qmi_packet(epout, buf, msg_len);
+        buf += msg_len;
+        len -= msg_len;
+    }
+}
+// oem-end
+
 static void
 frmnet_cmd_complete(struct usb_ep *ep, struct usb_request *req)
 {
@@ -1007,6 +1220,10 @@ frmnet_cmd_complete(struct usb_ep *ep, struct usb_request *req)
 
     cdev = dev->cdev;
 
+    // oem-start
+    oem_dump_qmi(true, req, 0);
+    // oem-end
+
     if (dev->port.send_encap_cmd) {
         port_num = rmnet_ports[dev->port_num].ctrl_xport_num;
         dev->port.send_encap_cmd(port_num, req->buf, req->actual);
@@ -1073,6 +1290,9 @@ static void frmnet_notify_complete(struct usb_ep *ep, struct usb_request *req)
             spin_unlock_irqrestore(&dev->lock, flags);
             pr_debug("ep enqueue error %d\n", status);
         }
+        // oem-start
+        //oem_dump_qmi(false, req, req->length);
+        // oem-end
         break;
     }
 }
@@ -1138,6 +1358,10 @@ frmnet_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
             memcpy(req->buf, cpkt->buf, len);
             ret = len;
 
+            // oem-start
+            oem_dump_qmi(false, req, len);
+            // oem-end
+
             rmnet_free_ctrl_pkt(cpkt);
         }
         break;

原创粉丝点击