Beispiel #1
0
Msg *
MsgList::alloc(DxMessageCode code_, int32_t activityId_, void *data_,
		int32_t len_, MemBlk *blk_, MsgDataType dataType_)
{
	Msg *msg;
	SseInterfaceHeader hdr;

	lock();
	if (msgList.empty()) {
		Debug(DEBUG_MSGLIST, allocs, "allocs");
		Debug(DEBUG_MSGLIST, frees, "frees");
		unlock();
		Fatal(ERR_NMA);
	}

	msg = msgList.front();
	msgList.pop_front();

	Assert(!msg->allocated());
	msg->setAllocated();

	hdr.code = code_;
	hdr.activityId = activityId_;
	GetNssDate(hdr.timestamp);
	hdr.messageNumber = GetNextMsg();
	msg->setHeader(hdr);
	msg->setData(data_, len_, blk_, dataType_);

	++allocs;
	unlock();
	return (msg);
}
Beispiel #2
0
// Stand alone test file format:
//
//	command=value
//  #optional commands
//
//	Sample format:
//
//		# Start with a header.code of CONFIGURE_DX (40003)
//		Command=40003
//		# This activityId is not used, but it is read outside the switch
//		activityId=0
//		Command=40010
//		# The activityId for this command is a random number.
//		#  Must match the activityId for the START_TIME command.
//		activityId=100
//		ObsLen=16
//		ifcSkyFreq=4
//		dxSkyFreq=4
//		channelNumber=0
//		baselineDelay=0
//		operationsFlag=11
//		daddResolution=0
//		pulseThreshold=.5
//		maxPulsesPerHalfFrame=5000
//		maxPulsesPerSubchannelPerHalfFrame=10
//		daddThreshold=7
//
//		#	operations flag
// 		#			For CD_ONLY use a value of 1
//		#			For Baseline only use a value of 2
// 		#			For CD and CWD use a value of 17
//		#			For Baseline, CD & CWD use a value of 19
//		#			Any mode can be used with -s (simulated data)
//		#			Only CD_ONLY mode can be used with -z (DDC)
//		#				 operations flag is a bitmask, where the bit numbers
//		#				 are defined by the OperationsMask enum in
// 		#				 sseInterface.h.  To check the mask for a
//		#				 particular value, you need to mask it with
//		#				 (1 << enum_value).
//		#				 For some (but not all) useful masks, there are a
//		#				 separate set of #defines in SseInputTask.h with
//		#				 the conversion from bit numbers to masks already done.
//		#				Anything except "Baseline only" requires CD.
//		#				Pulses require Baselines to work properly, so...
//		#			For PULSE_DETECTION use a value of 11 (CD & Baseline needed)
//		#			For PULSE, CW, and CD use a value of 27
//
//		# header.code of START_TIME (40013)
//		Command=40013
//		# activityId for this command must be the same as for the
//		# SEND_DX_ACTIVITY_PARAMETERS command
//		activityId=100
//
//
void
SseInputTask::processIpFromFile()
{
	SseInterfaceHeader hdr;
	Msg *msg = 0;
	MemBlk *blk;
	void *data;
	int i;
	int counter = 0;
	static int lastMsg = 0;
	Timer timer;
	int obsLength = 0;
	int baseLineDelay = 0;
	int additionalAlarmDelay = 30;

		// Wait a bit...
	timer.sleep(1000);

	passThruCfg *pt = new passThruCfg();

	/*
	** Kludge --
	** Originally all standalone files started with the
	** CONFIGURE_DX command (40003) and had 13 fixed
	** entries. The config file should be changed to be
	** parameter based... but in the mean time (which
	** might be a long time)... An integer version number
	** has been added to the top of the file.
	**
	** Thus, if the first entry is 40003 this code looks
	** for the original 13 fixed entries and uses a
	** resolution of 1HZ.  If the first entry is a
	** version number than the version number is checked
	** as needed and new entries can be read from the file.
	*/
	/*
	** Remove ALL the version code. Configuration
	** file is now parameterized.
	*/

	int cmd = pt->getNxtCmd();
	while (cmd)
	{
		timer.sleep(3000);
		if (++counter == 10)
			Fatal(ERR_IPIV); 	// Something is wrong!

		hdr.activityId = pt->getActivityId();
		hdr.code = cmd;

		LogInfo(0, -1, "Reading standalone Config File cmd %d actId %d",
				hdr.code, hdr.activityId);

		hdr.messageNumber = lastMsg++;
		switch (hdr.code) {
			case CONFIGURE_DX:
			{
				hdr.dataLength = sizeof(DxConfiguration);
				msg = msgList->alloc();
				msg->setHeader(hdr);

					/* Allocate space for the cmd specific data */
				blk = partitionSet->alloc((size_t) hdr.dataLength);
				Assert(blk);
				if (!blk)
					Fatal(ERR_MAF);

				data = blk->getData();

				/* Initialize data.... */
				DxConfiguration *config = (DxConfiguration *)data;
				config->a2dClockrate = 104.16;

				msg->setData(data, hdr.dataLength, blk);
				break;
			}
			case SEND_DX_ACTIVITY_PARAMETERS:
			{
				hdr.dataLength = sizeof(DxActivityParameters);
				msg = msgList->alloc();
				msg->setHeader(hdr);

					/* Allocate space for the cmd specific data */
				blk = partitionSet->alloc((size_t) hdr.dataLength);
				Assert(blk);
				if (!blk)
					Fatal(ERR_MAF);

				data = blk->getData();

				/* Initialize data.... */
				DxActivityParameters *params = (DxActivityParameters *)data;
				params->activityId = hdr.activityId;
				obsLength = pt->getInt("ObsLen",cmd);;
				params->dataCollectionLength = obsLength; // seconds
					// RF Freq/MHz of IF band center
				params->ifcSkyFreq = pt->getInt("ifcSkyFreq",cmd);
				; 	// RF Freq/MHz of DX band center
				params->dxSkyFreq = pt->getInt("dxSkyFreq",cmd);
					// Number of subchannels. bins
				params->channelNumber = pt->getInt("channelNumber",cmd);
				baseLineDelay = pt->getInt("baselineDelay",cmd);
				cmdArgs->setBaselineDelay(baseLineDelay);
				int optParams = pt->getInt("operationsFlag",cmd);
					// optParams is a bitmask, where the bit numbers are
					// defined by the OperationsMask enum in
					// sseInterface.h.  To check the mask for a particular
					// value, you need to mask it with (1 << enum_value).
					// For some (but not all) useful masks, there are a
					// separate set of #defines in SseInputTask.h with
					// the conversion from bit numbers to masks already done.
LogInfo(0, -1, "processIpFromFile: optParams = %d ",optParams);
//					Either mode can be used with -s (simulated data)
//					Only CD_ONLY mode can be used with -z (DDC)
					//
					// For CD_ONLY use a value of 1
					// For CD and CWD use a value of 9
					// For CD, CWD & Baseline use a value of 11
					//
				params->operations = optParams;		// bit mask for DX operations
				if ((optParams & (1 << POWER_CWD)))
					additionalAlarmDelay += 30;

				params->sensitivityRatio = 0;       // main/remote rel sensitivity
				params->maxNumberOfCandidates = 0;
				params->clusteringFreqTolerance = 0; // Hz
				params->zeroDriftTolerance = 0;      // Hz/Sec
				params->zeroDriftTolerance = 0;      // Hz/Sec
				params->cwClusteringDeltaFreq = 0;   // bins
				params->badBandCwPathLimit = 12;    // max # paths /kHz (default approx == 256/slice)
					// Add daddResoultion to config file
				int res = pt->getInt("daddResolution",cmd);
				params->daddResolution = (Resolution)res;

				float32_t pulseThresh = pt->getFloat("pulseThreshold", cmd);
				params->maxPulsesPerHalfFrame =
						pt->getInt("maxPulsesPerHalfFrame",cmd);
				params->maxPulsesPerSubchannelPerHalfFrame =
						pt->getInt("maxPulsesPerSubchannelPerHalfFrame",cmd);

				params->daddThreshold =
						pt->getFloat("daddThreshold",cmd);
									// Sigma
									// Sigma 0==115 clusters
									// daddThreshold = 2 1137 clusters power.5
									// daddThreshold = 5 391 clusters power.5
									// daddThreshold = 7 11 clusters power.5
									// daddThreshold = 7  10 clusters power 0
									// daddThreshold = 8  1 clusters power 0
									// daddThreshold = 8.1  1 clusters power 0
									// *** 8.2 is where noise is gone ****
									// daddThreshold = 8.2  0 clusters power 0
									// daddThreshold = 8.5  0 clusters power 0
									// daddThreshold = 10 0 clusters power.5

				params->cwCoherentThreshold = 0;    // Sigma
				params->limitsForCoherentDetection = 0;
				params->badBandPulseTripletLimit = 0;  // # of paths
				params->badBandPulseLimit = 0;
				params->pulseClusteringDeltaFreq = 0;    // bins
				params->pulseTrainSignifThresh = 0;
				for (i = 0; i < MAX_RESOLUTIONS; ++i)
					params->requestPulseResolution[i] = SSE_FALSE;
				params->requestPulseResolution[RES_1HZ] = SSE_TRUE;
				params->alignPad2 = 0;         // alignment padding for marshalling
				for (i=0; i<MAX_RESOLUTIONS; ++i) {
					params->pd[i].pulseThreshold = pulseThresh;
					params->pd[i].tripletThreshold = 0;
					params->pd[i].singletThreshold = 0;
				}
				params->scienceDataRequest.sendBaselines = SSE_FALSE;
				params->scienceDataRequest.baselineReportingHalfFrames = 0;
#if 1
				params->scienceDataRequest.sendComplexAmplitudes = SSE_FALSE;
				params->scienceDataRequest.requestType = REQ_FREQ;
				params->scienceDataRequest.subchannel = 0;
#else
				// for waterfall debug
				params->scienceDataRequest.sendComplexAmplitudes = SSE_TRUE;
				params->scienceDataRequest.requestType = REQ_SUBCHANNEL;
				params->scienceDataRequest.subchannel = 1200;
#endif
				params->scienceDataRequest.rfFreq = 0;
				params->baselineSubchannelAverage = -1;
				params->baselineInitAccumHalfFrames = pt->getInt("baselineHalfFrames",cmd);
				LogInfo(0, -1, "actId: %d, obsLen: %d sendComplexAmplitudes: %d, ifcSkyFreq: %d", hdr.activityId,obsLength,params->scienceDataRequest.sendComplexAmplitudes,params->ifcSkyFreq);
				msg->setData(data, hdr.dataLength, blk);
				break;
				}
			case START_TIME:
			{
					LogInfo(0, -1, "processIpFromFile/START_TIME");
					hdr.dataLength = sizeof(StartActivity);
					msg = msgList->alloc();
					msg->setHeader(hdr);

						/* Allocate space for the cmd specific data */
					blk = partitionSet->alloc((size_t) hdr.dataLength);
					Assert(blk);
				if (!blk)
					Fatal(ERR_MAF);

				data = blk->getData();

				/* Initialize data.... */
				StartActivity *params = (StartActivity *)data;
				params->startTime.tv_sec = 0;
				params->startTime.tv_usec = 0;
				msg->setData(data, hdr.dataLength, blk);
				break;
			}

			default:
				FatalStr(hdr.code, "msg code");
		}
		cmdQ->send(msg);
		cmd = pt->getNxtCmd();
		hdr.code = cmd;
	}
		// Give the dx only so long to show its stuff...
//	double mtt = 2.5*(obsLength+baseLineDelay) + additionalAlarmDelay;
	double mtt = 100*(obsLength+baseLineDelay) + additionalAlarmDelay;
	int max_time_to_run = ((int) mtt);
	alarm(max_time_to_run);
	string n;
	name(n);
	LogInfo(0, -1, "Start Alarm on stand alone version: %d seconds. %d frames %d baseline delay\n",
			max_time_to_run, obsLength, baseLineDelay);

}
//
// 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);
}