/** * Notify the collection task that data collection is complete. */ void WorkerTask::completeDataCollection() { // done with data collection; report completion to collection task // and any packet reception problems to SSE. ChannelStatistics stats; channel->getStats(stats); Debug(DEBUG_ALWAYS, (int32_t) stats.netStats.total, "total packets"); Debug(DEBUG_ALWAYS, (int32_t) stats.netStats.missed, "missed packets"); Debug(DEBUG_ALWAYS, (int32_t) stats.netStats.late, "late packets"); if ((stats.netStats.missed + stats.netStats.late) > 0 && activity) { LogWarning(ERR_LMP, activity->getActivityId(), "channel %d, total packets = %d, missed = %d, late = %d", channel->getChannelNum(), stats.netStats.total, stats.netStats.missed, stats.netStats.late); } Msg *cMsg = msgList->alloc(DATA_COLLECTION_COMPLETE, activityId, reinterpret_cast<void *> (channel->getChannelNum()), 0, 0, IMMEDIATE); cMsg->setUnit((sonata_lib::Unit) unit); collectionQ->send(cMsg); stopActivity(activity); }
/** * Notify the collection task that baselining has started. * * Notes:\n * If there is no baselining, then we go straight to data collection, but * send the appropriate messages. */ void WorkerTask::startBaseline() { Msg *cMsg = msgList->alloc(BASELINE_INIT_ACCUM_STARTED, activity->getActivityId()); cMsg->setUnit((sonata_lib::Unit) unit); collectionQ->send(cMsg); }
/** * Notify the collection task that data collection has started. */ void WorkerTask::startDataCollection() { // register the end of baseline accumulation Msg *cMsg = msgList->alloc(BASELINE_INIT_ACCUM_COMPLETE, activity->getActivityId()); cMsg->setUnit((sonata_lib::Unit) unit); collectionQ->send(cMsg); // go straight into data collection. [NOTE: if we want to restart // buffering when we start data collection, we should flush the // channel input buffers and set the state to PEND_DC. activity->setState(DX_ACT_RUN_DC); // send start of data collection cMsg = msgList->alloc(DATA_COLLECTION_STARTED, activity->getActivityId()); cMsg->setUnit((sonata_lib::Unit) unit); collectionQ->send(cMsg); }
// // stopActivity: stop an activity // // Synopsis: // void stopActivity(msg, stopAll); // Msg *msg; ptr to message // bool stopAll; stop all activities // Returns: // Nothing. // Description: // Stops either the specified activity or any activity // which is currently active. // Notes: // Sends messages to the collection tasks. // Note that this task never kills a collecting // activity directly; instead, it sends // messages to the individual collection subtasks // instructing them to kill the task and report back // that it has been completed. // void DetectionTask::stopActivity(Msg *msg, bool stopAll) { // if no activity is detecting, ignore the message if (!activity || (!stopAll && activity->getActivityId() != msg->getActivityId())) { Msg *cMsg = msgList->alloc((DxMessageCode) ActivityStopped, msg->getActivityId()); cMsg->setUnit((sonata_lib::Unit) UnitDetect); controlQ->send(cMsg); return; } // stop both of the detectors (only one can be running, // but we don't know which one) stopDetection(); }
// // sendDetectionComplete: send a detection complete message // // Notes: // The actual message sent depends upon the current state // of the activity. If its state is DX_ACT_RUN_SD, then // a message is sent to the control task indicating that // basic signal detection is done. void DetectionTask::sendDetectionComplete() { if (!activity) return; Debug(DEBUG_DETECT, activity->getActivityId(), "activityId"); Debug(DEBUG_DETECT, (int32_t) activity->getState(), "state"); Msg *cMsg; if (activity->getState() == DX_ACT_STOPPING) { cMsg = msgList->alloc((DxMessageCode) ActivityStopped, activity->getActivityId()); cMsg->setUnit((sonata_lib::Unit) UnitDetect); } else { cMsg = msgList->alloc((DxMessageCode) DetectionComplete, activity->getActivityId()); } controlQ->send(cMsg); activity = 0; }
// // routine: receive and send on incoming messages // // Notes: // No analysis of the message is performed - that is left // to the command processor task. Instead, the local copy // of the header // is demarshalled to determined whether or not there // is associated data; if there is, space is allocated to // contain it. void * SseInputTask::routine() { extractArgs(); Timer timer; if (cmdArgs->noSSE()) { processIpFromFile(); while (1) timer.sleep(3000); }; // run forever, waiting for messages from the SSE bool stopIssued = false; bool done = false; uint32_t lastCode = MESSAGE_CODE_UNINIT; int32_t lastLen = 0; uint32_t lastTime = 0; while (!done) { // if there's no connection, request that it be // established, then wait for that to happen if (!sse->isConnected()) { requestConnection(); while (!sse->isConnected()) timer.sleep(3000); } stopIssued = false; // got a connection - wait for data to come in SseInterfaceHeader hdr; Error err = sse->recv((void *) &hdr, sizeof(hdr)); if (err) { switch (err) { case EAGAIN: case EINTR: case ENOTCONN: case ECONNRESET: stopAllActivities(stopIssued); continue; default: Fatal(err); break; } } // demarshall the header hdr.demarshall(); if (cmdArgs->logSseMessages()) { LogWarning(ERR_NE, hdr.activityId, "bad msg from Sse, code = %d, len = %d", hdr.code, hdr.dataLength); } // allocate a message to hold the incoming message Msg *msg = msgList->alloc(); msg->setHeader(hdr); msg->setUnit((sonata_lib::Unit) UnitSse); // if there's data associated with the message, // allocate space and retrieve it, demarshall it // based on the message type, // then send it on to the command processor void *data = 0; int32_t len = hdr.dataLength; timeval tv; gettimeofday(&tv, NULL); if (len > 10000) { LogWarning(ERR_NE, hdr.activityId, "msg code = %d, len = %d, t = %u, last msg = %d, last len = %d, last t = %u", hdr.code, len, tv.tv_sec, lastCode, lastLen, lastTime); Timer t; t.sleep(100); } else { lastCode = hdr.code; lastLen = len; lastTime = tv.tv_sec; } if (len) { MemBlk *blk = partitionSet->alloc(len); Assert(blk); if (!blk) Fatal(ERR_MAF); data = blk->getData(); err = sse->recv(data, len); if (err) { switch (err) { case EAGAIN: case EINTR: case ENOTCONN: case ECONNRESET: blk->free(); Assert(msgList->free(msg)); stopAllActivities(stopIssued); continue; default: Fatal(err); break; } } msg->setData(data, len, blk); } // demarshall the data of the message depending on // the message type switch (hdr.code) { case REQUEST_INTRINSICS: break; case CONFIGURE_DX: (static_cast<DxConfiguration *> (data))->demarshall(); break; case PERM_RFI_MASK: case BIRDIE_MASK: case RCVR_BIRDIE_MASK: case TEST_SIGNAL_MASK: demarshallFrequencyMask(data); break; case RECENT_RFI_MASK: demarshallRecentRFIMask(data); break; case REQUEST_DX_STATUS: break; case SEND_DX_ACTIVITY_PARAMETERS: (static_cast<DxActivityParameters *> (data))->demarshall(); break; case DX_SCIENCE_DATA_REQUEST: (static_cast<DxScienceDataRequest *> (data))->demarshall(); break; #ifdef notdef case SEND_DOPPLER_PARAMETERS: (static_cast<DopplerParameters *> (data))->demarshall(); break; #endif case BEGIN_SENDING_FOLLOW_UP_SIGNALS: (static_cast<Count *> (data))->demarshall(); break; case SEND_FOLLOW_UP_CW_SIGNAL: (static_cast<FollowUpCwSignal *> (data))->demarshall(); break; case SEND_FOLLOW_UP_PULSE_SIGNAL: (static_cast<FollowUpPulseSignal *> (data))->demarshall(); break; case DONE_SENDING_FOLLOW_UP_SIGNALS: break; case START_TIME: (static_cast<StartActivity *> (data))->demarshall(); break; case BEGIN_SENDING_CANDIDATES: (static_cast<Count *> (data))->demarshall(); break; case SEND_CANDIDATE_CW_POWER_SIGNAL: (static_cast<CwPowerSignal *> (data))->demarshall(); break; case SEND_CANDIDATE_PULSE_SIGNAL: demarshallPulseSignal(data); break; case DONE_SENDING_CANDIDATES: break; case BEGIN_SENDING_CW_COHERENT_SIGNALS: break; case SEND_CW_COHERENT_SIGNAL: (static_cast<CwCoherentSignal *> (data))->demarshall(); break; case DONE_SENDING_CW_COHERENT_SIGNALS: break; case REQUEST_ARCHIVE_DATA: (static_cast<ArchiveRequest *> (data))->demarshall(); break; case DISCARD_ARCHIVE_DATA: (static_cast<ArchiveRequest *> (data))->demarshall(); break; // the following commands arrive with no data case STOP_DX_ACTIVITY: case SHUTDOWN_DX: case RESTART_DX: Debug(DEBUG_CONTROL, hdr.activityId, "STOP_DX_ACTIVITY, act"); break; default: LogError(ERR_IMT, hdr.activityId, "activity %d, type %d", hdr.activityId, hdr.code); Err(ERR_IMT); ErrStr(hdr.code, "msg code"); Assert(msgList->free(msg)); continue; } // at this point, the entire marshalled message is in // a generic Msg; send the message on for processing, // then go back to waiting cmdQ->send(msg); } return (0); }