Пример #1
0
// The main USB dump routine
static void usb_dump (int num_packets)
{
    // Packets will be saved during the collapse process
    PacketQueue pkt_q;

    // Points to the current packet
    PacketInfo * cur_pkt;

    // Collapsing counts and time collapsing started
    CollapseInfo collapse_info;

    // Collapsing of packets is handled through a state machine.
    // Sometimes the machine will need to be re-run to properly
    // handle the sequence of packets.
    enum CollapseStates {
        IDLE = 0,
        IN, PING, SPLIT, SPLIT_IN, SPLIT_OUT, SPLIT_SETUP
    } state = IDLE;

    u08 re_run = FALSE;

    u08  pid           = 0;
    int  signal_errors = 0;
    int  packetnum     = 0;

    // Initialize structures
    memset(&pkt_q, 0, sizeof(PacketQueue));
    memset(&collapse_info, 0, sizeof(CollapseInfo));

    samplerate_khz = bg_samplerate(beagle, 0);

    // Configure Beagle 480 for realtime capture
    bg_usb480_capture_configure(beagle,
                        BG_USB480_CAPTURE_REALTIME,
                        BG_USB2_AUTO_SPEED_DETECT);

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

    if (bg_enable(beagle, BG_PROTOCOL_USB) != BG_OK) {
        printf("error: could not enable USB capture; exiting...\n");
        exit(1);
    }

    // Output the header...
    printf("index,time(ns),USB,status,pid,data0 ... dataN(*)\n");
    fflush(stdout);

    // ...then start decoding packets
    while (packetnum < num_packets || !num_packets) {
        cur_pkt = &pkt_q.pkt[pkt_q.tail];

        cur_pkt->length = bg_usb480_read(beagle,
                                         &cur_pkt->status,
                                         &cur_pkt->events,
                                         &cur_pkt->time_sop,
                                         &cur_pkt->time_duration,
                                         &cur_pkt->time_dataoffset,
                                         1024,
                                         cur_pkt->data);

        cur_pkt->time_sop_ns =
            TIMESTAMP_TO_NS(cur_pkt->time_sop, samplerate_khz);

        // Exit if observed end of capture
        if (cur_pkt->status & BG_READ_USB_END_OF_CAPTURE) {
            usb_print_summary_packet(&packetnum, &collapse_info,
                                     &signal_errors);
            break;
        }

        // Check for invalid packet or Beagle error
        if (cur_pkt->length < 0) {
            char error_status[32];
            sprintf(error_status, "error=%d", cur_pkt->length);
            usb_print_packet(packetnum, cur_pkt, error_status);
            break;
        }

        // Check for USB error
        if (cur_pkt->status == BG_READ_USB_ERR_BAD_SIGNALS)
            ++signal_errors;

        // Set the PID for collapsing state machine below.  Treat
        // KEEP_ALIVEs as packets.
        if (cur_pkt->length > 0)
            pid = cur_pkt->data[0];
        else if ((cur_pkt->events & BG_EVENT_USB_KEEP_ALIVE) &&
                 !(cur_pkt->status & BG_READ_USB_ERR_BAD_PID))
        {
            pid = 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 ((int)(cur_pkt->time_sop - collapse_info.time_sop) >= IDLE_SAMPLES)
            usb_print_summary_packet(&packetnum, &collapse_info,
                                     &signal_errors);

        while(1) {
            re_run = 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 IDLE:
                switch (pid) {
                  case KEEP_ALIVE:
                    COLLAPSE(KEEP_ALIVE);
                    break;
                  case BG_USB_PID_SOF:
                    COLLAPSE(SOF);
                    break;
                  case BG_USB_PID_IN:
                    SAVE_PACKET();
                    state = IN;
                    break;
                  case BG_USB_PID_PING:
                    SAVE_PACKET();
                    state = PING;
                    break;
                  case BG_USB_PID_SPLIT:
                    SAVE_PACKET();
                    state = SPLIT;
                    break;
                  default:
                    usb_print_summary_packet(&packetnum, &collapse_info,
                                             &signal_errors);

                    if (cur_pkt->length > 0 || cur_pkt->events ||
                        (cur_pkt->status != 0 &&
                         cur_pkt->status != BG_READ_TIMEOUT))
                    {
                        usb_print_packet(packetnum, cur_pkt, 0);
                        packetnum++;
                    }
                }
                break;

                // Collapsing IN+ACK or IN+NAK.  Otherwise, output any
                // saved packets and rerun the collapsing state machine
                // on the current packet.
              case IN:
                state = IDLE;
                switch (pid) {
                  case BG_USB_PID_ACK:
                    COLLAPSE(IN_ACK);
                    break;
                  case BG_USB_PID_NAK:
                    COLLAPSE(IN_NAK);
                    break;
                  default:
                    re_run = TRUE;
                }
                break;

                // Collapsing PING+NAK
              case PING:
                state = IDLE;
                switch (pid) {
                  case BG_USB_PID_NAK:
                    COLLAPSE(PING_NAK);
                    break;
                  default:
                    re_run = TRUE;
                }
                break;

                // Expecting an IN, OUT, or SETUP
              case SPLIT:
                switch (pid) {
                  case BG_USB_PID_IN:
                    SAVE_PACKET();
                    state = SPLIT_IN;
                    break;
                  case BG_USB_PID_OUT:
                    SAVE_PACKET();
                    state = SPLIT_OUT;
                    break;
                  case BG_USB_PID_SETUP:
                    SAVE_PACKET();
                    state = SPLIT_SETUP;
                    break;
                  default:
                    state = IDLE;
                    re_run = TRUE;
                }
                break;

                // Collapsing SPLIT+IN+NYET, SPLIT+IN+NAK, SPLIT+IN+ACK
              case SPLIT_IN:
                state = IDLE;
                switch (pid) {
                  case BG_USB_PID_NYET:
                    COLLAPSE(SPLIT_IN_NYET);
                    break;
                  case BG_USB_PID_NAK:
                    COLLAPSE(SPLIT_IN_NAK);
                    break;
                  case BG_USB_PID_ACK:
                    COLLAPSE(SPLIT_IN_ACK);
                    break;
                  default:
                    re_run = TRUE;
                }
                break;

                // Collapsing SPLIT+OUT+NYET
              case SPLIT_OUT:
                state = IDLE;
                switch (pid) {
                  case BG_USB_PID_NYET:
                    COLLAPSE(SPLIT_OUT_NYET);
                    break;
                  default:
                    re_run = TRUE;
                }
                break;

                // Collapsing SPLIT+SETUP+NYET
              case SPLIT_SETUP:
                state = IDLE;
                switch (pid) {
                  case BG_USB_PID_NYET:
                    COLLAPSE(SPLIT_SETUP_NYET);
                    break;
                  default:
                    re_run = TRUE;
                }
                break;
            }

            if (re_run == 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.
            OUTPUT_SAVED();
        }
    }

    // Stop the capture
    bg_disable(beagle);
}
Пример #2
0
void collapseDuplexGroup(string sorted_duplex_group_file, string collapsed_dg_file, string logFile, string errorFile, int maxGap, int maxTotal)
{
    ofstream LOG(logFile, ios_base::app);
    ofstream ERR(errorFile, ios_base::app);
    
    LOG << "Start to collapseDuplexGroup " << sorted_duplex_group_file << "  ===>  " << collapsed_dg_file << endl;
    
    int merged_dgCount = 0;
    int firstPossible=0;
    
    PointerArray<DuplexGroup *> dgArray;
    long long fileLines = countFileLines(sorted_duplex_group_file);
    ProcessAlert alert(fileLines, 100000, 10);
    
    ifstream DUPLEXGROUP(sorted_duplex_group_file);
    char strand1, strand2;
    string chr1, chr2, supportReads;
    int start1, end1, start2, end2, support;
    
    while(DUPLEXGROUP>>chr1>>start1>>end1>>strand1>>chr2>>start2>>end2>>strand2>>supportReads>>support)
    {
        char buffer[200];
        sprintf(buffer, "firstPossible: %d, merged_dgCount: %d", firstPossible, merged_dgCount);
        LOG << alert.alert(string(buffer));
        
        DuplexGroup *dg = new DuplexGroup(chr1, start1, end1, strand1, chr2, start2,end2, strand2, support, supportReads);
        //dgArray.append(dg);
        
        //if(supportReads == "23198;10015265;10015267;10015268")
        //  cout << dgArray[dgArray.arrayLen()-1]->supportRead << endl;
        
        int lastDGovarlapped = 0; bool merged = false;
        for(int idx=firstPossible; idx<dgArray.arrayLen();idx++)
        {
            
            int overlapped = dgArray[idx]->overlapDG(dg, maxGap, maxTotal);
            /*
             if(supportReads == "23198;10015265;10015267;10015268" and idx==dgArray.arrayLen()-1)
             {
             cout << dgArray[dgArray.arrayLen()-1]->supportRead << endl;
             cout <<overlapped << endl;
             }
             */
            if (overlapped == -1){
                if(not lastDGovarlapped)
                    firstPossible = idx + 1;
            }
            else if(overlapped > 0){
                lastDGovarlapped = 1;
                dgArray[idx]->mergeDuplexGroup(dg);
                //dgArray.del(dgArray.arrayLen()-1);
                merged = true;
                delete dg;
                merged_dgCount++;
                break;
            }
            else{
                lastDGovarlapped = 1;
            }
        }
        if(not merged)
            dgArray.append(dg);
        //cout << merged_dgCount << endl;
    }
    LOG << alert.finish();
    DUPLEXGROUP.close();
    
    ofstream COLLAPSE(collapsed_dg_file);
    for(int i=0; i<dgArray.arrayLen(); i++)
        COLLAPSE << dgArray[i]->chr1 << "\t" << dgArray[i]->start1 << "\t" << dgArray[i]->end1 << "\t" << dgArray[i]->strand1 << "\t" << dgArray[i]->chr2 << "\t" << dgArray[i]->start2 << "\t" << dgArray[i]->end2 << "\t" << dgArray[i]->strand2 << "\t" << dgArray[i]->supportRead << "\t" << dgArray[i]->support << "\n";
    COLLAPSE.close();
    
    LOG.close();
    ERR.close();
}