+ my $i0 = ZOOM::event(\@conn);
+ $this->log("irspy_event", "ZOOM_event(", scalar(@conn), " connections) = $i0");
+ last if $i0 == 0 || $i0 == -3; # no events or no connections
+ my $conn = $conn[$i0-1];
+ my $ev = $conn->last_event();
+ my $evstr = ZOOM::event_str($ev);
+ $conn->log("irspy_event", "event $ev ($evstr)");
+
+ my $task = $conn->current_task();
+ die "$conn has no current task for event $ev ($evstr)" if !$task;
+ eval { $conn->_check() };
+ if ($@ &&
+ ($ev == ZOOM::Event::RECV_DATA ||
+ $ev == ZOOM::Event::RECV_APDU ||
+ $ev == ZOOM::Event::ZEND)) {
+ # An error in, say, a search response, becomes visible to
+ # ZOOM before the Receive Data event is sent and persists
+ # until after the End, which means that successive events
+ # each report the same error. So we just ignore errors on
+ # "unimportant" events. ### But this doesn't work for,
+ # say, a Connection Refused, as the only event that shows
+ # us this error is the End.
+ $conn->log("irspy_event", "ignoring error ",
+ "on event $ev ($evstr): $@");
+ next;
+ }
+
+ my $res;
+ if ($@) {
+ my $sub = $task->{cb}->{exception};
+ die $@ if !defined $sub;
+ $res = &$sub($conn, $task, $@);
+ } else {
+ my $sub = $task->{cb}->{$ev};
+ if (!defined $sub) {
+ $conn->log("irspy_unhandled", "event $ev ($evstr)");
+ next;
+ }
+
+ $res = &$sub($conn, $task, $ev);
+ }
+
+ if ($res == ZOOM::IRSpy::Status::OK) {
+ # Nothing to do -- life continues
+
+ } elsif ($res == ZOOM::IRSpy::Status::TASK_DONE) {
+ my $task = $conn->current_task();
+ die "no task for TASK_DONE on $conn" if !$task;
+ die "next task already defined for $conn" if $conn->next_task();
+ $conn->log("irspy", "completed task $task");
+ $conn->next_task($task->{next});
+ $conn->current_task(0);
+
+ } elsif ($res == ZOOM::IRSpy::Status::TEST_GOOD ||
+ $res == ZOOM::IRSpy::Status::TEST_BAD) {
+ my $x = ($res == ZOOM::IRSpy::Status::TEST_GOOD) ? "good" : "bad";
+ $conn->log("irspy", "test completed ($x)");
+ $conn->current_task(0);
+ $conn->next_task(0);
+ ### Should also skip over remaining sibling tests if TEST_BAD
+ $nskipped += 1; # should count number of skipped siblings
+ }
+ }
+
+ $this->log("irspy_event", "no more events: finishing");
+
+ #$this->_rewrite_records();
+ return $nskipped;