Exemplo n.º 1
0
 // Collapses a group of packets.  This involves incrementing the group
 // counter and clearing the savedPackets stack by moving top back to 0.
 // If this is the first group to be collapsed, the collapse time needs
 // to be set, which marks when this collapsing began.
 static void collapse(PacketGroup group,
                      CollapseInfo collapseInfo,
                      PacketQueue pktQ)
 {
     collapseInfo.count[(byte)group]++;
     if (collapseInfo.timeSop == 0)
     {
         if (!pktQ.isEmpty())
         {
             collapseInfo.timeSop = pktQ.headSop();
         }
         else
         {
             collapseInfo.timeSop = pktQ.tailSop();
         }
     }
     pktQ.clear();
 }
Exemplo n.º 2
0
    // Outputs any packets saved during the collapsing process
    static void outputSaved(ref int packetnum,
                            ref int signalErrors,
                            CollapseInfo collapseInfo,
                            PacketQueue pktQ)
    {
        usbPrintSummaryPacket(ref packetnum, collapseInfo,
                              ref signalErrors);

        PacketInfo pkt = pktQ.dequeue();

        while (pkt != null)
        {
            usbPrintPacket(packetnum, pkt, null);
            packetnum += 1;

            // Get the next packet or null if empty
            pkt = pktQ.dequeue();
        }
    }
Exemplo n.º 3
0
    static void usbDump(int numPackets)
    {
        // Packets are saved during the collapsing process
        PacketQueue pktQ = new PacketQueue();

        // Info for the packet that was just read
        PacketInfo curPacket;

        // Collapsing counts and time collapsing started
        CollapseInfo collapseInfo = new CollapseInfo();

        CollapseState state = CollapseState.IDLE;
        bool          reRun = false;

        byte pid          = 0;
        int  signalErrors = 0;
        int  packetnum    = 0;

        samplerateKHz = BeagleApi.bg_samplerate(beagle, 0);

        int idle_samples = IDLE_THRESHOLD * samplerateKHz;

        // Configure Beagle 480 for realtime capture
        BeagleApi.bg_usb480_capture_configure(beagle,
                                              BeagleUsb480CaptureMode.BG_USB480_CAPTURE_REALTIME,
                                              BeagleUsb2TargetSpeed.BG_USB2_AUTO_SPEED_DETECT);

        // Filter packets intended for the Beagle analyzer. This is only
        // relevant when one host controller is being used.
        BeagleApi.bg_usb480_hw_filter_config(beagle,
                                             BeagleApi.BG_USB2_HW_FILTER_SELF);

        // Start the capture
        if (BeagleApi.bg_enable(beagle, BeagleProtocol.BG_PROTOCOL_USB) !=
            (int)BeagleStatus.BG_OK)
        {
            Console.Write("error: could not enable USB capture; exiting...\n");
            Environment.Exit(1);
        }

        // Output the header...
        Console.Write("index,time(ns),USB,status,pid,data0 ... dataN(*)\n");
        Console.Out.Flush();

        // ...then start decoding packets
        while (packetnum < numPackets || (numPackets == 0))
        {
            curPacket = pktQ.getTail();

            curPacket.length = BeagleApi.bg_usb480_read(
                beagle,
                ref curPacket.status,
                ref curPacket.events,
                ref curPacket.timeSop,
                ref curPacket.timeDuration,
                ref curPacket.timeDataOffset,
                1024,
                curPacket.data);

            curPacket.timeSopNS =
                timestampToNS(curPacket.timeSop, samplerateKHz);

            // Exit if observed end of capture
            if ((curPacket.status &
                 BeagleApi.BG_READ_USB_END_OF_CAPTURE) != 0)
            {
                usbPrintSummaryPacket(ref packetnum, collapseInfo,
                                      ref signalErrors);
                break;
            }

            // Check for invalid packet or Beagle error
            if (curPacket.length < 0)
            {
                String errorStatus = "";
                errorStatus += String.Format("error={0:d}", curPacket.length);
                usbPrintPacket(packetnum, curPacket, errorStatus);
                break;
            }

            // Check for USB error
            if (curPacket.status == BeagleApi.BG_READ_USB_ERR_BAD_SIGNALS)
            {
                ++signalErrors;
            }

            // Set the PID for collapsing state machine below.  Treat
            // KEEP_ALIVEs as packets.
            if (curPacket.length > 0)
            {
                pid = curPacket.data[0];
            }
            else if ((curPacket.events &
                      BeagleApi.BG_EVENT_USB_KEEP_ALIVE) != 0 &&
                     (curPacket.status &
                      BeagleApi.BG_READ_USB_ERR_BAD_PID) == 0)
            {
                pid = (byte)PacketGroup.KEEP_ALIVE;
            }
            else
            {
                pid = 0;
            }

            // Collapse these packets approprietly:
            // KEEP_ALIVE* SOF* (IN (ACK|NAK))* (PING NAK)*
            // (SPLIT (OUT|SETUP) NYET)* (SPLIT IN (ACK|NYET|NACK))*

            // If the time elapsed since collapsing began is greater than
            // the threshold, output the counts and zero out the counters.
            if (curPacket.timeSop - collapseInfo.timeSop >=
                (ulong)idle_samples)
            {
                usbPrintSummaryPacket(ref packetnum, collapseInfo,
                                      ref signalErrors);
            }

            while (true)
            {
                reRun = false;
                switch (state)
                {
                // The initial state of the state machine.  Collapse SOFs
                // and KEEP_ALIVEs.  Save IN, PING, or SPLIT packets and
                // move to the next state for the next packet.  Otherwise,
                // print the collapsed packet counts and the current
                // packet.
                case CollapseState.IDLE:
                    switch (pid)
                    {
                    case (byte)PacketGroup.KEEP_ALIVE:
                        collapse(PacketGroup.KEEP_ALIVE, collapseInfo, pktQ);
                        break;

                    case BeagleApi.BG_USB_PID_SOF:
                        collapse(PacketGroup.SOF, collapseInfo, pktQ);
                        break;

                    case BeagleApi.BG_USB_PID_IN:
                        pktQ.savePacket();
                        state = CollapseState.IN;
                        break;

                    case BeagleApi.BG_USB_PID_PING:
                        pktQ.savePacket();
                        state = CollapseState.PING;
                        break;

                    case BeagleApi.BG_USB_PID_SPLIT:
                        pktQ.savePacket();
                        state = CollapseState.SPLIT;
                        break;

                    default:
                        usbPrintSummaryPacket(ref packetnum, collapseInfo,
                                              ref signalErrors);

                        if (curPacket.length > 0 || curPacket.events != 0 ||
                            (curPacket.status != 0 &&
                             curPacket.status != BeagleApi.BG_READ_TIMEOUT))
                        {
                            usbPrintPacket(packetnum, curPacket, null);
                            packetnum++;
                        }
                        break;
                    }
                    break;

                // Collapsing IN+ACK or IN+NAK.  Otherwise, output any
                // saved packets and rerun the collapsing state machine
                // on the current packet.
                case CollapseState.IN:
                    state = CollapseState.IDLE;
                    switch (pid)
                    {
                    case BeagleApi.BG_USB_PID_ACK:
                        collapse(PacketGroup.IN_ACK, collapseInfo, pktQ);
                        break;

                    case BeagleApi.BG_USB_PID_NAK:
                        collapse(PacketGroup.IN_NAK, collapseInfo, pktQ);
                        break;

                    default:
                        reRun = true;
                        break;
                    }
                    break;

                // Collapsing PING+NAK
                case CollapseState.PING:
                    state = CollapseState.IDLE;
                    switch (pid)
                    {
                    case BeagleApi.BG_USB_PID_NAK:
                        collapse(PacketGroup.PING_NAK, collapseInfo, pktQ);
                        break;

                    default:
                        reRun = true;
                        break;
                    }
                    break;

                // Expecting an IN, OUT, or SETUP
                case CollapseState.SPLIT:
                    switch (pid)
                    {
                    case BeagleApi.BG_USB_PID_IN:
                        pktQ.savePacket();
                        state = CollapseState.SPLIT_IN;
                        break;

                    case BeagleApi.BG_USB_PID_OUT:
                        pktQ.savePacket();
                        state = CollapseState.SPLIT_OUT;
                        break;

                    case BeagleApi.BG_USB_PID_SETUP:
                        pktQ.savePacket();
                        state = CollapseState.SPLIT_SETUP;
                        break;

                    default:
                        state = CollapseState.IDLE;
                        reRun = true;
                        break;
                    }
                    break;

                // Collapsing SPLIT+IN+NYET, SPLIT+IN+NAK, SPLIT+IN+ACK
                case CollapseState.SPLIT_IN:
                    state = CollapseState.IDLE;
                    switch (pid)
                    {
                    case BeagleApi.BG_USB_PID_NYET:
                        collapse(PacketGroup.SPLIT_IN_NYET, collapseInfo,
                                 pktQ);
                        break;

                    case BeagleApi.BG_USB_PID_NAK:
                        collapse(PacketGroup.SPLIT_IN_NAK, collapseInfo,
                                 pktQ);
                        break;

                    case BeagleApi.BG_USB_PID_ACK:
                        collapse(PacketGroup.SPLIT_IN_ACK, collapseInfo,
                                 pktQ);
                        break;

                    default:
                        reRun = true;
                        break;
                    }
                    break;

                // Collapsing SPLIT+OUT+NYET
                case CollapseState.SPLIT_OUT:
                    state = CollapseState.IDLE;
                    switch (pid)
                    {
                    case BeagleApi.BG_USB_PID_NYET:
                        collapse(PacketGroup.SPLIT_OUT_NYET, collapseInfo,
                                 pktQ);
                        break;

                    default:
                        reRun = true;
                        break;
                    }
                    break;

                // Collapsing SPLIT+SETUP+NYET
                case CollapseState.SPLIT_SETUP:
                    state = CollapseState.IDLE;
                    switch (pid)
                    {
                    case BeagleApi.BG_USB_PID_NYET:
                        collapse(PacketGroup.SPLIT_SETUP_NYET, collapseInfo,
                                 pktQ);
                        break;

                    default:
                        reRun = true;
                        break;
                    }
                    break;
                }

                if (reRun == false)
                {
                    break;
                }

                // The state machine is about to be re-run.  This
                // means that a complete packet sequence wasn't collapsed
                // and there are packets in the queue that need to be
                // output before we can process the current packet.
                outputSaved(ref packetnum, ref signalErrors,
                            collapseInfo, pktQ);
            }
        }

        // Stop the capture
        BeagleApi.bg_disable(beagle);
    }
Exemplo n.º 4
0
    // Dump saved summary information
    static int usbPrintSummaryPacket(ref int packetNumber,
                                     CollapseInfo collapseInfo,
                                     ref int signalErrors)
    {
        int offset = 0;

        String summary = "";

        if (collapseInfo.count[(byte)PacketGroup.KEEP_ALIVE] > 0 ||
            collapseInfo.count[(byte)PacketGroup.SOF] > 0 ||
            collapseInfo.count[(byte)PacketGroup.PING_NAK] > 0 ||
            collapseInfo.count[(byte)PacketGroup.SPLIT_IN_ACK] > 0 ||
            collapseInfo.count[(byte)PacketGroup.SPLIT_IN_NYET] > 0 ||
            collapseInfo.count[(byte)PacketGroup.SPLIT_IN_NAK] > 0 ||
            collapseInfo.count[(byte)PacketGroup.SPLIT_OUT_NYET] > 0 ||
            collapseInfo.count[(byte)PacketGroup.SPLIT_SETUP_NYET] > 0)
        {
            summary += "COLLAPSED ";

            if (collapseInfo.count[(byte)PacketGroup.KEEP_ALIVE] > 0)
            {
                summary +=
                    String.Format("[{0:d} KEEP-ALIVE] ",
                                  collapseInfo.count[(byte)PacketGroup.KEEP_ALIVE]);
            }

            if (collapseInfo.count[(byte)PacketGroup.SOF] > 0)
            {
                summary +=
                    String.Format("[{0:d} SOF] ",
                                  collapseInfo.count[(byte)PacketGroup.SOF]);
            }

            if (collapseInfo.count[(byte)PacketGroup.IN_ACK] > 0)
            {
                summary +=
                    String.Format("[{0:d} IN/ACK] ",
                                  collapseInfo.count[(byte)PacketGroup.IN_ACK]);
            }

            if (collapseInfo.count[(byte)PacketGroup.IN_NAK] > 0)
            {
                summary +=
                    String.Format("[{0:d} IN/NAK] ",
                                  collapseInfo.count[(byte)PacketGroup.IN_NAK]);
            }

            if (collapseInfo.count[(byte)PacketGroup.PING_NAK] > 0)
            {
                summary +=
                    String.Format("[{0:d} PING/NAK] ",
                                  collapseInfo.count[(byte)PacketGroup.PING_NAK]);
            }

            #if COMBINE_SPLITS
            int split_count =
                collapseInfo.count[(byte)PacketGroup.SPLIT_IN_ACK] +
                collapseInfo.count[(byte)PacketGroup.SPLIT_IN_NYET] +
                collapseInfo.count[(byte)PacketGroup.SPLIT_IN_NAK] +
                collapseInfo.count[(byte)PacketGroup.SPLIT_OUT_NYET] +
                collapseInfo.count[(byte)PacketGroup.SPLIT_SETUP_NYET];

            if (split_count > 0)
            {
                summary += String.Format("[{0:d} SPLITS] ", split_count);
            }
            #else
            if (collapseInfo.count[(byte)PacketGroup.SPLIT_IN_ACK] > 0)
            {
                summary +=
                    String.Format("[{0:d} SPLIT/IN/ACK] ",
                                  collapseInfo.count[(byte)PacketGroup.SPLIT_IN_NAK]);
            }

            if (collapseInfo.count[(byte)PacketGroup.SPLIT_IN_NYET] > 0)
            {
                summary +=
                    String.Format("[{0:d} SPLIT/IN/NYET] ",
                                  collapseInfo.count[(byte)PacketGroup.SPLIT_IN_NYET]);
            }

            if (collapseInfo.count[(byte)PacketGroup.SPLIT_IN_NAK] > 0)
            {
                summary +=
                    String.Format("[{0:d} SPLIT/IN/NAK] ",
                                  collapseInfo.count[(byte)PacketGroup.SPLIT_IN_NAK]);
            }

            if (collapseInfo.count[(byte)PacketGroup.SPLIT_OUT_NYET] > 0)
            {
                summary +=
                    String.Format("[{0:d} SPLIT/OUT/NYET] ",
                                  collapseInfo.count[(byte)PacketGroup.SPLIT_OUT_NYET]);
            }

            if (collapseInfo.count[(byte)PacketGroup.SPLIT_SETUP_NYET] > 0)
            {
                summary +=
                    String.Format("[{0:d} SPLIT/SETUP/NYET] ",
                                  collapseInfo.count[(byte)PacketGroup.SPLIT_SETUP_NYET]);
            }
            #endif

            usbPrintSummary(packetNumber + offset, collapseInfo.timeSop,
                            summary);
            offset++;
        }

        // Output any signal errors
        if (signalErrors > 0)
        {
            summary += String.Format("<{0:d} SIGNAL ERRORS>", signalErrors);

            usbPrintSummary(packetNumber + offset, collapseInfo.timeSop,
                            summary);
            ++offset;
        }

        collapseInfo.clear();
        packetNumber += offset;
        return(offset);
    }