From 0b624384cd52be20e61284551d832b499d7b7707 Mon Sep 17 00:00:00 2001 From: Jonathan McCrohan Date: Sat, 14 Apr 2012 12:56:48 +0100 Subject: Imported Upstream version 2.1.8.20120216 --- csocketevents.c | 2201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2201 insertions(+) create mode 100644 csocketevents.c (limited to 'csocketevents.c') diff --git a/csocketevents.c b/csocketevents.c new file mode 100644 index 0000000..9291994 --- /dev/null +++ b/csocketevents.c @@ -0,0 +1,2201 @@ +#include "stdafx.h" +#include "csocket.h" +#include "csocketevents.h" +#include "utils/utils.h" +#include "math.h" + +#include "cphidget.h" +#include "cphidgetdictionary.h" +#include "csocket.h" +#include "clog.h" +#include "cphidgetaccelerometer.h" +#include "cphidgetadvancedservo.h" +#include "cphidgetanalog.h" +#include "cphidgetbridge.h" +#include "cphidgetencoder.h" +#include "cphidgetfrequencycounter.h" +#include "cphidgetgps.h" +#include "cphidgetinterfacekit.h" +#include "cphidgetir.h" +#include "cphidgetmanager.h" +#include "cphidgetled.h" +#include "cphidgetmotorcontrol.h" +#include "cphidgetphsensor.h" +#include "cphidgetrfid.h" +#include "cphidgetservo.h" +#include "cphidgetspatial.h" +#include "cphidgetstepper.h" +#include "cphidgettemperaturesensor.h" +#include "cphidgettextlcd.h" +#include "cphidgettextled.h" +#include "cphidgetweightsensor.h" +#include "cphidgetgeneric.h" + +regex_t phidgetsetex; +regex_t managerex; +regex_t managervalex; + +PWC_SETKEYS(Accelerometer) + if(KEYNAME("NumberOfAxes")) + { + GET_INT_VAL; + phid->phid.attr.accelerometer.numAxis = value; + phid->phid.keyCount++; + } + else if(KEYNAME("Acceleration")) + { + if(CHKINDEX(accelerometer.numAxis,ACCEL_MAXAXES)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(axis[index], PUNI_DBL) + phid->axis[index] = value; + if(value != PUNK_DBL) + FIRE(AccelerationChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("AccelerationMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(accelerationMin, PUNI_DBL) + phid->accelerationMin = value; + } + else if(KEYNAME("AccelerationMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(accelerationMax, PUNI_DBL) + phid->accelerationMax = value; + } + else if(KEYNAME("Trigger")) + { + if(CHKINDEX(accelerometer.numAxis,ACCEL_MAXAXES)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(axisChangeTrigger[index], PUNI_DBL) + phid->axisChangeTrigger[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else{ + PWC_BAD_SETTYPE(Accelerometer); + } + return ret; +} + +PWC_SETKEYS(AdvancedServo) + if(KEYNAME("NumberOfMotors")) + { + GET_INT_VAL; + phid->phid.attr.advancedservo.numMotors = value; + phid->phid.keyCount++; + } + else if(KEYNAME("Position")) + { + if(index < phid->phid.attr.advancedservo.numMotors?phid->phid.attr.advancedservo.numMotors:ADVSERVO_MAXSERVOS) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorPositionEcho[index], PUNI_DBL) + phid->motorPositionEcho[index] = value; + if(value != PUNK_DBL) + FIRE(PositionChange, index, servo_us_to_degrees(phid->servoParams[index], value, PTRUE)); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("PositionMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorPositionMin[index], PUNI_DBL) + phid->motorPositionMin[index] = value; + } + else if(KEYNAME("PositionMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorPositionMax[index], PUNI_DBL) + phid->motorPositionMax[index] = value; + } + else if(KEYNAME("PositionMinLimit")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorPositionMinLimit, PUNI_DBL) + phid->motorPositionMinLimit = value; + } + else if(KEYNAME("PositionMaxLimit")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorPositionMaxLimit, PUNI_DBL) + phid->motorPositionMaxLimit = value; + } + // initial acceleration limit always unknown so don't keyCount++ + else if(KEYNAME("Acceleration")) + { + if(CHKINDEX(advancedservo.numMotors, ADVSERVO_MAXSERVOS)) + { + GET_DOUBLE_VAL; + phid->motorAcceleration[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("AccelerationMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(accelerationMax, PUNI_DBL) + phid->accelerationMax = value; + } + else if(KEYNAME("AccelerationMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(accelerationMin, PUNI_DBL) + phid->accelerationMin = value; + } + else if(KEYNAME("Current")) + { + if(CHKINDEX(advancedservo.numMotors, ADVSERVO_MAXSERVOS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorSensedCurrent[index], PUNI_DBL) + phid->motorSensedCurrent[index] = value; + if(value != PUNK_DBL) + FIRE(CurrentChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + // initial velocity limit always unknown so don't keyCount++ + else if(KEYNAME("VelocityLimit")) + { + if(CHKINDEX(advancedservo.numMotors, ADVSERVO_MAXSERVOS)) + { + GET_DOUBLE_VAL; + phid->motorVelocity[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Velocity")) + { + if(CHKINDEX(advancedservo.numMotors, ADVSERVO_MAXSERVOS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorVelocityEcho[index], PUNI_DBL) + phid->motorVelocityEcho[index] = value; + if(value != PUNK_DBL) + FIRE(VelocityChange, index, servo_us_to_degrees_vel(phid->servoParams[index], value, PTRUE)); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("VelocityMax")) + { + if(CHKINDEX(advancedservo.numMotors, ADVSERVO_MAXSERVOS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(velocityMax[index], PUNI_DBL) + phid->velocityMax[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("VelocityMaxLimit")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(velocityMaxLimit, PUNI_DBL) + phid->velocityMaxLimit = value; + } + else if(KEYNAME("VelocityMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(velocityMin, PUNI_DBL) + phid->velocityMin = value; + } + else if(KEYNAME("Engaged")) + { + if(CHKINDEX(advancedservo.numMotors, ADVSERVO_MAXSERVOS)) + { + GET_INT_VAL; + INC_KEYCOUNT(motorEngagedStateEcho[index], PUNI_BOOL) + phid->motorEngagedStateEcho[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("SpeedRampingOn")) + { + if(CHKINDEX(advancedservo.numMotors, ADVSERVO_MAXSERVOS)) + { + GET_INT_VAL; + INC_KEYCOUNT(motorSpeedRampingStateEcho[index], PUNI_BOOL) + phid->motorSpeedRampingStateEcho[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Stopped")) + { + if(CHKINDEX(advancedservo.numMotors, ADVSERVO_MAXSERVOS)) + { + GET_INT_VAL; + unsigned char lastStoppedState = phid->motorStoppedState[index]; + INC_KEYCOUNT(motorStoppedState[index], PUNI_BOOL) + phid->motorStoppedState[index] = value; + //If changed, re-run position/velocity events, so the stopped change will be noticed + if(lastStoppedState != value) + { + if(phid->motorVelocityEcho[index] != PUNK_DBL) + FIRE(VelocityChange, index, servo_us_to_degrees_vel(phid->servoParams[index], phid->motorVelocityEcho[index], PTRUE)); + if(phid->motorPositionEcho[index] != PUNK_DBL) + FIRE(PositionChange, index, servo_us_to_degrees(phid->servoParams[index], phid->motorPositionEcho[index], PTRUE)); + } + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("ServoParameters")) + { + if(CHKINDEX(advancedservo.numMotors, ADVSERVO_MAXSERVOS)) + { + CPhidgetServoParameters params; + char *endptr; + params.servoType = strtol(state, &endptr, 10); + params.min_us = strtod(endptr+1, &endptr); + params.max_us = strtod(endptr+1, &endptr); + params.us_per_degree = strtod(endptr+1, &endptr); + params.max_us_per_s = strtod(endptr+1, NULL); + params.state = PTRUE; + + INC_KEYCOUNT(servoParams[index].state, PUNI_BOOL) + + phid->servoParams[index] = params; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else{ + PWC_BAD_SETTYPE(AdvancedServo); + } + return ret; +} + +PWC_SETKEYS(Analog) + if(KEYNAME("NumberOfOutputs")) + { + GET_INT_VAL; + phid->phid.attr.analog.numAnalogOutputs = value; + phid->phid.keyCount++; + } + else if(KEYNAME("Voltage")) + { + if(CHKINDEX(analog.numAnalogOutputs, ANALOG_MAXOUTPUTS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(voltageEcho[index], PUNI_DBL) + phid->voltageEcho[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("VoltageMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(voltageMin, PUNI_DBL) + phid->voltageMin = value; + } + else if(KEYNAME("VoltageMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(voltageMax, PUNI_DBL) + phid->voltageMax = value; + } + else if(KEYNAME("Enabled")) + { + if(CHKINDEX(analog.numAnalogOutputs, ANALOG_MAXOUTPUTS)) + { + GET_INT_VAL; + INC_KEYCOUNT(enabledEcho[index], PUNI_BOOL) + phid->enabledEcho[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else{ + PWC_BAD_SETTYPE(Analog); + } + return ret; +} + +PWC_SETKEYS(Bridge) + if(KEYNAME("NumberOfInputs")) + { + GET_INT_VAL; + phid->phid.attr.bridge.numBridgeInputs = value; + phid->phid.keyCount++; + } + else if(KEYNAME("DataRate")) + { + GET_INT_VAL; + INC_KEYCOUNT(dataRateEcho, PUNI_INT) + phid->dataRateEcho = value; + } + else if(KEYNAME("DataRateMin")) + { + GET_INT_VAL; + INC_KEYCOUNT(dataRateMin, PUNI_INT) + phid->dataRateMin = value; + } + else if(KEYNAME("DataRateMax")) + { + GET_INT_VAL; + INC_KEYCOUNT(dataRateMax, PUNI_INT) + phid->dataRateMax = value; + } + else if(KEYNAME("Enabled")) + { + if(CHKINDEX(bridge.numBridgeInputs, BRIDGE_MAXINPUTS)) + { + GET_INT_VAL; + INC_KEYCOUNT(enabledEcho[index], PUNI_BOOL) + phid->enabledEcho[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("BridgeMax")) + { + if(CHKINDEX(bridge.numBridgeInputs, BRIDGE_MAXINPUTS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(bridgeMax[index], PUNI_DBL) + phid->bridgeMax[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("BridgeMin")) + { + if(CHKINDEX(bridge.numBridgeInputs, BRIDGE_MAXINPUTS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(bridgeMin[index], PUNI_DBL) + phid->bridgeMin[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Gain")) + { + if(CHKINDEX(bridge.numBridgeInputs, BRIDGE_MAXINPUTS)) + { + GET_INT_VAL; + INC_KEYCOUNT(gainEcho[index], PHIDGET_BRIDGE_GAIN_UNKNOWN) + phid->gainEcho[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("BridgeValue")) + { + if(CHKINDEX(bridge.numBridgeInputs, BRIDGE_MAXINPUTS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(bridgeValue[index], PUNI_DBL) + phid->bridgeValue[index] = value; + if(value != PUNK_DBL) + FIRE(BridgeData, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else{ + PWC_BAD_SETTYPE(Bridge); + } + return ret; +} + +PWC_SETKEYS(Encoder) + if(KEYNAME("NumberOfEncoders")) + { + GET_INT_VAL; + phid->phid.attr.encoder.numEncoders = value; + phid->phid.keyCount++; + } + else if(KEYNAME("NumberOfInputs")) + { + GET_INT_VAL; + phid->phid.attr.encoder.numInputs = value; + phid->phid.keyCount++; + } + // initial Input is unknown so don't keyCount++ + else if(KEYNAME("Input")) + { + if(CHKINDEX(encoder.numInputs, ENCODER_MAXINPUTS)) + { + GET_INT_VAL; + phid->inputState[index] = value; + if(value != PUNK_BOOL) + FIRE(InputChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + // initial Position is unknown so don't keyCount++ + else if(KEYNAME("ResetPosition")) + { + if(CHKINDEX(encoder.numEncoders, ENCODER_MAXENCODERS)) + { + GET_INT_VAL; + phid->encoderPosition[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Position")) + { + if(CHKINDEX(encoder.numEncoders, ENCODER_MAXENCODERS)) + { + char *endPtr; + int value = strtol(state, &endPtr, 10); + int posnchange = strtol(endPtr+1, &endPtr, 10); + int posn = strtol(endPtr+1, &endPtr, 10); + + phid->encoderPosition[index] = posn; + + FIRE(PositionChange, index, (unsigned short)value, posnchange); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("IndexPosition")) + { + if(CHKINDEX(encoder.numEncoders, ENCODER_MAXENCODERS)) + { + GET_INT_VAL; + phid->indexPosition[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Enabled")) + { + if(CHKINDEX(encoder.numEncoders, ENCODER_MAXENCODERS)) + { + GET_INT_VAL; + INC_KEYCOUNT(enableStateEcho[index], PUNI_BOOL) + phid->enableStateEcho[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else{ + PWC_BAD_SETTYPE(Encoder); + } + return ret; +} + +PWC_SETKEYS(FrequencyCounter) + if(KEYNAME("NumberOfInputs")) + { + GET_INT_VAL; + phid->phid.attr.frequencycounter.numFreqInputs = value; + phid->phid.keyCount++; + } + else if(KEYNAME("Count") || KEYNAME("CountReset")) + { + if(CHKINDEX(frequencycounter.numFreqInputs, FREQCOUNTER_MAXINPUTS)) + { + char *endPtr; + __int64 totTime = strtoll(state, &endPtr, 10); + __int64 totCount = strtoll(endPtr+1, &endPtr, 10); + double freq = strtod(endPtr+1, NULL); + + int timeChange = (int)(totTime - phid->totalTime[index]); + int cntChange = (int)(totCount - phid->totalCount[index]); + + INC_KEYCOUNT(frequency[index], PUNI_INT); + + phid->totalTime[index] = totTime; + phid->totalCount[index] = totCount; + phid->frequency[index] = freq; + + //no event on first time or reset + if(phid->countsGood[index] == PTRUE && KEYNAME("Count")) + { + FIRE(Count, index, timeChange, cntChange); + } + + phid->countsGood[index] = PTRUE; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Enabled")) + { + if(CHKINDEX(frequencycounter.numFreqInputs, FREQCOUNTER_MAXINPUTS)) + { + GET_INT_VAL; + INC_KEYCOUNT(enabledEcho[index], PUNI_BOOL) + phid->enabledEcho[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Timeout")) + { + if(CHKINDEX(frequencycounter.numFreqInputs, FREQCOUNTER_MAXINPUTS)) + { + GET_INT_VAL; + INC_KEYCOUNT(timeout[index], PUNI_INT) + phid->timeout[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Filter")) + { + if(CHKINDEX(frequencycounter.numFreqInputs, FREQCOUNTER_MAXINPUTS)) + { + GET_INT_VAL; + INC_KEYCOUNT(filterEcho[index], PHIDGET_FREQUENCYCOUNTER_FILTERTYPE_UNKNOWN) + phid->filterEcho[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else{ + PWC_BAD_SETTYPE(FrequencyCounter); + } + return ret; +} + +PWC_SETKEYS(Generic) + phid = 0; + return ret; +} + +PWC_SETKEYS(GPS) + if(KEYNAME("Position")) + { + char *endPtr; + double lat = strtod(state, &endPtr); + double lon = strtod(endPtr+1, &endPtr); + double alt = strtod(endPtr+1, NULL); + phid->latitude = lat; + phid->longitude = lon; + phid->altitude = alt; + FIRE(PositionChange, lat, lon, alt); + } + else if(KEYNAME("PositionFix")) + { + GET_INT_VAL; + INC_KEYCOUNT(fix, PUNI_BOOL) + phid->fix = value; + FIRE(PositionFixStatusChange, value); + } + else if(KEYNAME("Velocity")) + { + GET_DOUBLE_VAL; + phid->velocity = value; + } + else if(KEYNAME("Heading")) + { + GET_DOUBLE_VAL; + phid->heading = value; + } + else if(KEYNAME("DateTime")) + { + GPSTime time; + GPSDate date; + char *endPtr; + date.tm_year = (short)strtol(state, &endPtr, 10); + date.tm_mon = (short)strtol(endPtr+1, &endPtr, 10); + date.tm_mday = (short)strtol(endPtr+1, &endPtr, 10); + time.tm_hour = (short)strtol(endPtr+1, &endPtr, 10); + time.tm_min = (short)strtol(endPtr+1, &endPtr, 10); + time.tm_sec = (short)strtol(endPtr+1, &endPtr, 10); + time.tm_ms = (short)strtol(endPtr+1, NULL, 10); + + phid->GPSData.GGA.time = time; + phid->haveTime = PTRUE; + phid->GPSData.RMC.date = date; + phid->haveDate = PTRUE; + } + else{ + PWC_BAD_SETTYPE(GPS); + } + return ret; +} + +PWC_SETKEYS(InterfaceKit) + if(KEYNAME("NumberOfSensors")) + { + GET_INT_VAL; + phid->phid.attr.ifkit.numSensors = value; + phid->phid.keyCount++; + } + else if(KEYNAME("NumberOfInputs")) + { + GET_INT_VAL; + phid->phid.attr.ifkit.numInputs = value; + phid->phid.keyCount++; + } + else if(KEYNAME("NumberOfOutputs")) + { + GET_INT_VAL; + phid->phid.attr.ifkit.numOutputs = value; + phid->phid.keyCount++; + } + else if(KEYNAME("Input")) + { + if(CHKINDEX(ifkit.numInputs, IFKIT_MAXINPUTS)) + { + GET_INT_VAL; + INC_KEYCOUNT(physicalState[index], PUNI_BOOL) + phid->physicalState[index] = value; + if(value != PUNK_BOOL) + FIRE(InputChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Sensor")) + { + if(CHKINDEX(ifkit.numSensors, IFKIT_MAXSENSORS)) + { + GET_INT_VAL; + INC_KEYCOUNT(sensorValue[index], PUNI_INT) + phid->sensorValue[index] = value; + if(value != PUNK_INT) + FIRE(SensorChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("RawSensor")) + { + if(CHKINDEX(ifkit.numSensors, IFKIT_MAXSENSORS)) + { + GET_INT_VAL; + INC_KEYCOUNT(sensorRawValue[index], PUNI_INT) + phid->sensorRawValue[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Output")) + { + if(CHKINDEX(ifkit.numOutputs, IFKIT_MAXOUTPUTS)) + { + GET_INT_VAL; + INC_KEYCOUNT(outputEchoStates[index], PUNI_BOOL) + phid->outputEchoStates[index] = value; + if(value != PUNK_BOOL) + FIRE(OutputChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Trigger")) + { + if(CHKINDEX(ifkit.numSensors, IFKIT_MAXSENSORS)) + { + GET_INT_VAL; + INC_KEYCOUNT(sensorChangeTrigger[index], PUNI_INT) + phid->sensorChangeTrigger[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("DataRate")) + { + if(CHKINDEX(ifkit.numSensors, IFKIT_MAXSENSORS)) + { + GET_INT_VAL; + INC_KEYCOUNT(dataRate[index], PUNI_INT) + phid->dataRate[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("DataRateMin")) + { + GET_INT_VAL; + INC_KEYCOUNT(dataRateMin, PUNI_INT) + phid->dataRateMin = value; + } + else if(KEYNAME("DataRateMax")) + { + GET_INT_VAL; + INC_KEYCOUNT(dataRateMax, PUNI_INT) + phid->dataRateMax = value; + } + else if(KEYNAME("InterruptRate")) + { + GET_INT_VAL; + INC_KEYCOUNT(interruptRate, PUNI_INT) + phid->interruptRate = value; + phid->maxDataPerPacket = phid->phid.attr.ifkit.numSensors?phid->phid.attr.ifkit.numSensors:IFKIT_MAXSENSORS; + } + else if(KEYNAME("Ratiometric")) + { + GET_INT_VAL; + INC_KEYCOUNT(ratiometric, PUNI_BOOL) + phid->ratiometric = value; + phid->ratiometricEcho = value; + } + else{ + PWC_BAD_SETTYPE(InterfaceKit); + } + return ret; +} + +PWC_SETKEYS(IR) + if(KEYNAME("Code")) + { + unsigned char data[IR_MAX_CODE_DATA_LENGTH]; + int bitCount, repeat, length = IR_MAX_CODE_DATA_LENGTH; + char *endPtr; + + //this will stop at the first ',' + stringToByteArray((char *)state, data, &length); + bitCount = strtol(state+length*2+1, &endPtr, 10); + repeat = strtol(endPtr+1, &endPtr, 10); + + //send out the code event! + FIRE(Code, data, length, bitCount, repeat); + + //store to last code + ZEROMEM(phid->lastCode, sizeof(phid->lastCode)); + memcpy(phid->lastCode, data, length); + phid->lastCodeInfo.bitCount = bitCount; + phid->lastRepeat = repeat; + phid->lastCodeKnown = PTRUE; + } + else if(KEYNAME("Learn")) + { + unsigned char data[IR_MAX_CODE_DATA_LENGTH]; + CPhidgetIR_CodeInfo codeInfo; + int length=IR_MAX_CODE_DATA_LENGTH; + + stringToCodeInfo((char *)state, &codeInfo); + stringToByteArray((char *)(state+sizeof(CPhidgetIR_CodeInfo)*2), data, &length); + + //send the event + FIRE(Learn, data, length, &codeInfo); + + //store to last code + ZEROMEM(phid->lastLearnedCode, sizeof(phid->lastLearnedCode)); + memcpy(phid->lastLearnedCode, data, length); + phid->lastLearnedCodeInfo = codeInfo; + phid->lastLearnedCodeKnown = PTRUE; + } + else if(KEYNAME("RawData")) + { + //TODO: + //what about multiple clients? + // -if a faster client is getting all the data and acking it, then the slower client will end up missing chunks... + // -we are assuming that data comes in in the same order as it is sent, so we don't deal with out of order keys + + //only respond to new raw data + if(reason != PDR_CURRENT_VALUE) + { + int i; + int data[IR_MAX_CODE_DATA_LENGTH]; + char key[1024], val[1024]; + int rawDataSendCnt, length = IR_MAX_CODE_DATA_LENGTH; + char *endPtr; + + //this will stop at the first ',' + stringToWordArray((char *)state, data, &length); + rawDataSendCnt = strtol(state+length*5+1, &endPtr, 10); + + //send an ACK for this count + CThread_mutex_lock(&phid->phid.lock); + snprintf(key, sizeof(key), "/PCK/%s/%d/RawDataAck/%d", phid->phid.deviceType, phid->phid.serialNumber, index); + snprintf(val, sizeof(val), "%d", rawDataSendCnt); + pdc_async_set(phid->phid.networkInfo->server->pdcs, key, val, (int)strlen(val), PFALSE, internal_async_network_error_handler, &phid->phid); + CThread_mutex_unlock(&phid->phid.lock); + + //see if we lost a packet + if(phid->rawDataSendWSCounter != PUNK_INT && phid->rawDataSendWSCounter + 1 != rawDataSendCnt) + { + char error_buffer[127]; + FIRE_ERROR_NOQUEUE(EEPHIDGET_PACKETLOST, "A piece on PhidgetIR Raw Data was lost. Be careful if decoding RawData manually."); + + //reset data pointers + phid->dataWritePtr = 0; + phid->userReadPtr = 0; + } + phid->rawDataSendWSCounter = rawDataSendCnt; + + //send the event + FIRE(RawData, data, length); + + //TODO: store the raw data array + for(i=0;idataBuffer[phid->dataWritePtr] = data[i]; + + phid->dataWritePtr++; + phid->dataWritePtr &= IR_DATA_ARRAY_MASK; + //if we run into data that hasn't been read... too bad, we overwrite it and adjust the read pointer + if(phid->dataWritePtr == phid->userReadPtr) + { + phid->userReadPtr++; + phid->userReadPtr &= IR_DATA_ARRAY_MASK; + } + } + + } + } + else{ + PWC_BAD_SETTYPE(IR); + } + return ret; +} + +PWC_SETKEYS(LED) + if(KEYNAME("NumberOfLEDs")) + { + GET_INT_VAL; + phid->phid.attr.led.numLEDs = value; + phid->phid.keyCount++; + } + // initial brightness is unknown so don't keyCount++ + else if(KEYNAME("Brightness")) + { + if(CHKINDEX(led.numLEDs, LED_MAXLEDS)) + { + GET_INT_VAL; + INC_KEYCOUNT(LED_Power[index], PUNI_INT) + phid->LED_Power[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Voltage")) + { + GET_INT_VAL; + INC_KEYCOUNT(voltageEcho, -1) + phid->voltageEcho = value; + } + else if(KEYNAME("CurrentLimit")) + { + GET_INT_VAL; + INC_KEYCOUNT(currentLimitEcho, -1) + phid->currentLimitEcho = value; + } + else{ + PWC_BAD_SETTYPE(LED); + } + return ret; +} + +PWC_SETKEYS(MotorControl) + if(KEYNAME("NumberOfMotors")) + { + GET_INT_VAL; + phid->phid.attr.motorcontrol.numMotors = value; + phid->phid.keyCount++; + } + else if(KEYNAME("NumberOfInputs")) + { + GET_INT_VAL; + phid->phid.attr.motorcontrol.numInputs = value; + phid->phid.keyCount++; + } + else if(KEYNAME("NumberOfEncoders")) + { + GET_INT_VAL; + phid->phid.attr.motorcontrol.numEncoders = value; + phid->phid.keyCount++; + } + else if(KEYNAME("NumberOfSensors")) + { + GET_INT_VAL; + phid->phid.attr.motorcontrol.numSensors = value; + phid->phid.keyCount++; + } + else if(KEYNAME("Input")) + { + if(CHKINDEX(motorcontrol.numInputs, MOTORCONTROL_MAXINPUTS)) + { + GET_INT_VAL; + INC_KEYCOUNT(inputState[index], PUNI_BOOL) + phid->inputState[index] = value; + if(value != PUNK_BOOL) + FIRE(InputChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Sensor")) + { + if(CHKINDEX(motorcontrol.numSensors, MOTORCONTROL_MAXSENSORS)) + { + GET_INT_VAL; + INC_KEYCOUNT(sensorValue[index], PUNI_INT) + phid->sensorValue[index] = value; + if(value != PUNK_INT) + FIRE(SensorUpdate, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("RawSensor")) + { + if(CHKINDEX(motorcontrol.numSensors, MOTORCONTROL_MAXSENSORS)) + { + GET_INT_VAL; + INC_KEYCOUNT(sensorRawValue[index], PUNI_INT) + phid->sensorRawValue[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Ratiometric")) + { + GET_INT_VAL; + INC_KEYCOUNT(ratiometricEcho, PUNI_BOOL) + phid->ratiometricEcho = value; + } + else if(KEYNAME("Braking")) + { + if(CHKINDEX(motorcontrol.numMotors, MOTORCONTROL_MAXMOTORS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorBrakingEcho[index], PUNI_DBL) + phid->motorBrakingEcho[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("BackEMF")) + { + if(CHKINDEX(motorcontrol.numMotors, MOTORCONTROL_MAXMOTORS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorSensedBackEMF[index], PUNI_DBL) + phid->motorSensedBackEMF[index] = value; + if(value != PUNK_DBL) + FIRE(BackEMFUpdate, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("BackEMFState")) + { + if(CHKINDEX(motorcontrol.numMotors, MOTORCONTROL_MAXMOTORS)) + { + GET_INT_VAL; + INC_KEYCOUNT(backEMFSensingStateEcho[index], PUNI_BOOL) + phid->backEMFSensingStateEcho[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("SupplyVoltage")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(supplyVoltage, PUNI_DBL) + phid->supplyVoltage = value; + } + else if(KEYNAME("Velocity")) + { + if(CHKINDEX(motorcontrol.numMotors, MOTORCONTROL_MAXMOTORS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorSpeedEcho[index], PUNI_DBL) + phid->motorSpeedEcho[index] = value; + if(value != PUNK_DBL) + FIRE(VelocityChange, index, value); + //Deprecated + if(value != PUNK_DBL) + FIRE(MotorChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Current")) + { + if(CHKINDEX(motorcontrol.numMotors, MOTORCONTROL_MAXMOTORS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorSensedCurrent[index], PUNI_DBL) + phid->motorSensedCurrent[index] = value; + if(value != PUNK_DBL) + FIRE(CurrentChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("CurrentUpdate")) + { + if(CHKINDEX(motorcontrol.numMotors, MOTORCONTROL_MAXMOTORS)) + { + GET_DOUBLE_VAL; + phid->motorSensedCurrent[index] = value; + if(value != PUNK_DBL) + FIRE(CurrentUpdate, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + // initial acceleration is unknown so don't keyCount++ + else if(KEYNAME("Acceleration")) + { + if(CHKINDEX(motorcontrol.numMotors, MOTORCONTROL_MAXMOTORS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorAccelerationEcho[index], PUNI_DBL) + phid->motorAccelerationEcho[index] = value; + phid->motorAcceleration[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("AccelerationMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(accelerationMin, PUNI_DBL) + phid->accelerationMin = value; + } + else if(KEYNAME("AccelerationMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(accelerationMax, PUNI_DBL) + phid->accelerationMax = value; + } + // initial Position is unknown so don't keyCount++ + else if(KEYNAME("ResetEncoderPosition")) + { + if(CHKINDEX(motorcontrol.numEncoders, MOTORCONTROL_MAXENCODERS)) + { + GET_INT_VAL; + phid->encoderPositionDelta[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("EncoderPosition")) + { + if(CHKINDEX(motorcontrol.numEncoders, MOTORCONTROL_MAXENCODERS)) + { + char *endPtr; + int time = strtol(state, &endPtr, 10); + int posn = strtol(endPtr+1, NULL, 10); + int posnChange = posn - phid->encoderPositionEcho[index]; + int encoderTimeChange = time - phid->encoderTimeStamp[index]; + + //timeout is 20 seconds + if (encoderTimeChange > 60000) + encoderTimeChange = PUNK_INT; + + phid->encoderPositionEcho[index] = posn; + phid->encoderTimeStamp[index] = time; + + FIRE(EncoderPositionChange, index, encoderTimeChange, posnChange); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("EncoderPositionUpdate")) + { + if(CHKINDEX(motorcontrol.numEncoders, MOTORCONTROL_MAXENCODERS)) + { + int posn = strtol(state, NULL, 10); + int posnChange = posn - phid->encoderPositionUpdates[index]; + + phid->encoderPositionUpdates[index] = posn; + + FIRE(EncoderPositionUpdate, index, posnChange); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else{ + PWC_BAD_SETTYPE(MotorControl); + } + return ret; +} + +PWC_SETKEYS(PHSensor) + if(KEYNAME("PH")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(PH, PUNI_DBL) + phid->PH = value; + if(value != PUNK_DBL) + FIRE(PHChange, value); + } + else if(KEYNAME("PHMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(phMin, PUNI_DBL) + phid->phMin = value; + } + else if(KEYNAME("PHMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(phMax, PUNI_DBL) + phid->phMax = value; + } + else if(KEYNAME("Trigger")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(PHChangeTrigger, PUNI_DBL) + phid->PHChangeTrigger = value; + } + else if(KEYNAME("Potential")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(Potential, PUNI_DBL) + phid->Potential = value; + } + else if(KEYNAME("PotentialMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(potentialMin, PUNI_DBL) + phid->potentialMin = value; + } + else if(KEYNAME("PotentialMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(potentialMax, PUNI_DBL) + phid->potentialMax = value; + } + else{ + PWC_BAD_SETTYPE(PHSensor); + } + return ret; +} + +PWC_SETKEYS(RFID) + if(KEYNAME("NumberOfOutputs")) + { + GET_INT_VAL; + phid->phid.attr.rfid.numOutputs = value; + phid->phid.keyCount++; + } + else if(KEYNAME("LastTag")) + { + unsigned char tagData[5]; + INC_KEYCOUNT(lastTagValid, PUNI_BOOL) + phid->lastTagValid = PTRUE; + + tagData[0] = (hexval(state[0])<<4)|hexval(state[1]); + tagData[1] = (hexval(state[2])<<4)|hexval(state[3]); + tagData[2] = (hexval(state[4])<<4)|hexval(state[5]); + tagData[3] = (hexval(state[6])<<4)|hexval(state[7]); + tagData[4] = (hexval(state[8])<<4)|hexval(state[9]); + + memcpy(phid->lastTag, tagData, 5); + } + else if(KEYNAME("Tag")) + { + unsigned char tagData[5]; + //always increment on tagPresent==PUNI_BOOL before setting it! + INC_KEYCOUNT(tagPresent, PUNI_BOOL) + phid->tagPresent = 1; + + tagData[0] = (hexval(state[0])<<4)|hexval(state[1]); + tagData[1] = (hexval(state[2])<<4)|hexval(state[3]); + tagData[2] = (hexval(state[4])<<4)|hexval(state[5]); + tagData[3] = (hexval(state[6])<<4)|hexval(state[7]); + tagData[4] = (hexval(state[8])<<4)|hexval(state[9]); + + FIRE(Tag, tagData); + + memcpy(phid->lastTag, tagData, 5); + } + else if(KEYNAME("TagLoss")) + { + //always increment on tagPresent==PUNI_BOOL before setting it! + INC_KEYCOUNT(tagPresent, PUNI_BOOL) + phid->tagPresent = 0; + FIRE(TagLost, phid->lastTag); + } + else if(KEYNAME("TagState")) + { + GET_INT_VAL; + //always increment on tagPresent==PUNI_BOOL before setting it! + INC_KEYCOUNT(tagPresent, PUNI_BOOL) + phid->tagPresent = value; + } + else if(KEYNAME("Output")) + { + if(CHKINDEX(rfid.numOutputs, RFID_MAXOUTPUTS)) + { + GET_INT_VAL; + INC_KEYCOUNT(outputEchoState[index], PUNI_BOOL) + phid->outputEchoState[index] = value; + if(value != PUNK_BOOL) + FIRE(OutputChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("AntennaOn")) + { + GET_INT_VAL; + INC_KEYCOUNT(antennaEchoState, PUNI_BOOL) + phid->antennaEchoState = value; + } + else if(KEYNAME("LEDOn")) + { + GET_INT_VAL; + INC_KEYCOUNT(ledEchoState, PUNI_BOOL) + phid->ledEchoState = value; + } + else{ + PWC_BAD_SETTYPE(RFID); + } + return ret; +} + +PWC_SETKEYS(Servo) + if(KEYNAME("NumberOfMotors")) + { + GET_INT_VAL; + phid->phid.attr.led.numLEDs = value; + phid->phid.keyCount++; + } + else if(KEYNAME("Position")) + { + if(CHKINDEX(servo.numMotors, SERVO_MAXSERVOS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorPositionEcho[index], PUNI_DBL) + phid->motorPositionEcho[index]= value; + if(value != PUNK_DBL) + FIRE(PositionChange, index, servo_us_to_degrees(phid->servoParams[index], value, PTRUE)); + //Deprecated + if(value != PUNK_DBL) + FIRE(MotorPositionChange, index, servo_us_to_degrees(phid->servoParams[index], value, PTRUE)); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Engaged")) + { + if(CHKINDEX(servo.numMotors, SERVO_MAXSERVOS)) + { + GET_INT_VAL; + INC_KEYCOUNT(motorEngagedStateEcho[index], PUNI_BOOL) + phid->motorEngagedStateEcho[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("PositionMinLimit")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorPositionMinLimit, PUNI_DBL) + phid->motorPositionMinLimit = value; + } + else if(KEYNAME("PositionMaxLimit")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorPositionMaxLimit, PUNI_DBL) + phid->motorPositionMaxLimit = value; + } + else if(KEYNAME("ServoParameters")) + { + if(CHKINDEX(servo.numMotors, SERVO_MAXSERVOS)) + { + CPhidgetServoParameters params; + char *endptr; + params.servoType = strtol(state, &endptr, 10); + params.min_us = strtod(endptr+1, &endptr); + params.max_us = strtod(endptr+1, &endptr); + params.us_per_degree = strtod(endptr+1, NULL); + params.state = PTRUE; + + INC_KEYCOUNT(servoParams[index].state, PUNI_BOOL) + + phid->servoParams[index] = params; + + //Set the max/min + //make sure we don't set max higher then the limit + if(params.max_us > phid->motorPositionMaxLimit) + phid->motorPositionMax[index] = phid->motorPositionMaxLimit; + else + phid->motorPositionMax[index] = params.max_us; + + phid->motorPositionMin[index] = params.min_us; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else{ + PWC_BAD_SETTYPE(Servo); + } + return ret; +} + +PWC_SETKEYS(Spatial) + if(KEYNAME("AccelerationAxisCount")) + { + GET_INT_VAL; + phid->phid.attr.spatial.numAccelAxes = value; + phid->phid.keyCount++; + } + else if(KEYNAME("GyroAxisCount")) + { + GET_INT_VAL; + phid->phid.attr.spatial.numGyroAxes = value; + phid->phid.keyCount++; + } + else if(KEYNAME("CompassAxisCount")) + { + GET_INT_VAL; + phid->phid.attr.spatial.numCompassAxes = value; + phid->phid.keyCount++; + } + else if(KEYNAME("DataRate")) + { + GET_INT_VAL; + INC_KEYCOUNT(dataRate, PUNI_INT) + phid->dataRate = value; + } + else if(KEYNAME("DataRateMin")) + { + GET_INT_VAL; + INC_KEYCOUNT(dataRateMin, PUNI_INT) + phid->dataRateMin = value; + } + else if(KEYNAME("DataRateMax")) + { + GET_INT_VAL; + INC_KEYCOUNT(dataRateMax, PUNI_INT) + phid->dataRateMax = value; + } + else if(KEYNAME("InterruptRate")) + { + GET_INT_VAL; + INC_KEYCOUNT(interruptRate, PUNI_INT) + phid->interruptRate = value; + } + else if(KEYNAME("AccelerationMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(accelerationMin, PUNI_DBL) + phid->accelerationMin = value; + } + else if(KEYNAME("AccelerationMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(accelerationMax, PUNI_DBL) + phid->accelerationMax = value; + } + else if(KEYNAME("AngularRateMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(angularRateMin, PUNI_DBL) + phid->angularRateMin = value; + } + else if(KEYNAME("AngularRateMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(angularRateMax, PUNI_DBL) + phid->angularRateMax = value; + } + else if(KEYNAME("MagneticFieldMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(magneticFieldMin, PUNI_DBL) + phid->magneticFieldMin = value; + } + else if(KEYNAME("MagneticFieldMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(magneticFieldMax, PUNI_DBL) + phid->magneticFieldMax = value; + } + else if(KEYNAME("SpatialData")) + { + CPhidgetSpatial_SpatialEventDataHandle eventData[1]; + CPhidgetSpatial_SpatialEventData spatialData; + int i; + char *endptr = (char *)state-1; + + INC_KEYCOUNT(spatialDataNetwork, PUNI_BOOL) + phid->spatialDataNetwork = PTRUE; + + for(i=0;iaccelAxis[i] = spatialData.acceleration[i] = strtod(endptr+1, &endptr); + } + for(i=0;igyroAxis[i] = spatialData.angularRate[i] = strtod(endptr+1, &endptr); + } + for(i=0;icompassAxis[i] = spatialData.magneticField[i] = strtod(endptr+1, &endptr); + } + + spatialData.timestamp.seconds = strtol(endptr+1, &endptr, 10); + spatialData.timestamp.microseconds = strtol(endptr+1, NULL, 10); + + eventData[0] = &spatialData; + FIRE(SpatialData, eventData, 1); + } + else{ + PWC_BAD_SETTYPE(Spatial); + } + return ret; +} + +PWC_SETKEYS(Stepper) + if(KEYNAME("NumberOfMotors")) + { + GET_INT_VAL; + phid->phid.attr.stepper.numMotors = value; + phid->phid.keyCount++; + } + else if(KEYNAME("NumberOfInputs")) + { + GET_INT_VAL; + phid->phid.attr.stepper.numInputs = value; + phid->phid.keyCount++; + } + else if(KEYNAME("Input")) + { + if(CHKINDEX(stepper.numInputs, STEPPER_MAXINPUTS)) + { + GET_INT_VAL; + INC_KEYCOUNT(inputState[index], PUNI_BOOL) + phid->inputState[index] = value; + if(value != PUNK_BOOL) + FIRE(InputChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("CurrentPosition")) + { + if(CHKINDEX(stepper.numMotors, STEPPER_MAXSTEPPERS)) + { + GET_INT64_VAL; + INC_KEYCOUNT(motorPositionEcho[index], PUNI_INT64) + phid->motorPositionEcho[index] = value; + if(value != PUNK_INT64) + FIRE(PositionChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + // initial target position isn't a keyCount++ sort of thing + else if(KEYNAME("TargetPosition")) + { + if(CHKINDEX(stepper.numMotors, STEPPER_MAXSTEPPERS)) + { + GET_INT64_VAL; + INC_KEYCOUNT(motorPosition[index], PUNI_INT64) + phid->motorPosition[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("PositionMin")) + { + GET_INT64_VAL; + INC_KEYCOUNT(motorPositionMin, PUNI_INT64) + phid->motorPositionMin = value; + } + else if(KEYNAME("PositionMax")) + { + GET_INT64_VAL; + INC_KEYCOUNT(motorPositionMax, PUNI_INT64) + phid->motorPositionMax = value; + } + // initial acceleration is unknown so dont' keyCount++ + else if(KEYNAME("Acceleration")) + { + if(CHKINDEX(stepper.numMotors, STEPPER_MAXSTEPPERS)) + { + GET_DOUBLE_VAL; + phid->motorAcceleration[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("AccelerationMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(accelerationMin, PUNI_DBL) + phid->accelerationMin = value; + } + else if(KEYNAME("AccelerationMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(accelerationMax, PUNI_DBL) + phid->accelerationMax = value; + } + // initial current limit is unknown so dont' keyCount++ + else if(KEYNAME("CurrentLimit")) + { + if(CHKINDEX(stepper.numMotors, STEPPER_MAXSTEPPERS)) + { + GET_DOUBLE_VAL; + phid->motorCurrentLimit[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Current")) + { + if(CHKINDEX(stepper.numMotors, STEPPER_MAXSTEPPERS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorSensedCurrent[index], PUNI_DBL) + phid->motorSensedCurrent[index] = value; + if(value != PUNK_DBL) + FIRE(CurrentChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("CurrentMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(currentMin, PUNI_DBL) + phid->currentMin = value; + } + else if(KEYNAME("CurrentMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(currentMax, PUNI_DBL) + phid->currentMax = value; + } + // initial velocity limit is unknown so dont' keyCount++ + else if(KEYNAME("VelocityLimit")) + { + GET_DOUBLE_VAL; + phid->motorSpeed[index] = value; + } + else if(KEYNAME("Velocity")) + { + if(CHKINDEX(stepper.numMotors, STEPPER_MAXSTEPPERS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorSpeedEcho[index], PUNI_DBL) + phid->motorSpeedEcho[index] = value; + if(value != PUNK_DBL) + FIRE(VelocityChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("VelocityMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorSpeedMin, PUNI_DBL) + phid->motorSpeedMin = value; + } + else if(KEYNAME("VelocityMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(motorSpeedMax, PUNI_DBL) + phid->motorSpeedMax = value; + } + else if(KEYNAME("Engaged")) + { + if(CHKINDEX(stepper.numMotors, STEPPER_MAXSTEPPERS)) + { + GET_INT_VAL; + INC_KEYCOUNT(motorEngagedStateEcho[index], PUNI_BOOL) + phid->motorEngagedStateEcho[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("Stopped")) + { + if(CHKINDEX(stepper.numMotors, STEPPER_MAXSTEPPERS)) + { + GET_INT_VAL; + unsigned char lastStoppedState = phid->motorStoppedState[index]; + INC_KEYCOUNT(motorStoppedState[index], PUNI_BOOL) + phid->motorStoppedState[index] = value; + //If changed, re-run position/velocity events, so the stopped change will be noticed + if(lastStoppedState != value) + { + if(phid->motorSpeedEcho[index] != PUNK_DBL) + FIRE(VelocityChange, index, phid->motorSpeedEcho[index]); + if(phid->motorPositionEcho[index] != PUNK_INT64) + FIRE(PositionChange, index, phid->motorPositionEcho[index]); + } + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else{ + PWC_BAD_SETTYPE(Stepper); + } + return ret; +} + +PWC_SETKEYS(TemperatureSensor) + if(KEYNAME("NumberOfSensors")) + { + GET_INT_VAL; + phid->phid.attr.temperaturesensor.numTempInputs = value; + phid->phid.keyCount++; + } + else if(KEYNAME("Potential")) + { + if(CHKINDEX(temperaturesensor.numTempInputs, TEMPSENSOR_MAXSENSORS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(Potential[index], PUNI_DBL) + phid->Potential[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("PotentialMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(potentialMin, PUNI_DBL) + phid->potentialMin = value; + } + else if(KEYNAME("PotentialMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(potentialMax, PUNI_DBL) + phid->potentialMax = value; + } + else if(KEYNAME("Temperature")) + { + if(CHKINDEX(temperaturesensor.numTempInputs, TEMPSENSOR_MAXSENSORS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(Temperature[index], PUNI_DBL) + phid->Temperature[index] = value; + if(value != PUNK_DBL) + FIRE(TemperatureChange, index, value); + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else if(KEYNAME("TemperatureMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(temperatureMin[index], PUNI_DBL) + phid->temperatureMin[index] = value; + } + else if(KEYNAME("TemperatureMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(temperatureMax[index], PUNI_DBL) + phid->temperatureMax[index] = value; + } + else if(KEYNAME("AmbientTemperature")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(AmbientTemperature, PUNI_DBL) + phid->AmbientTemperature = value; + } + else if(KEYNAME("AmbientTemperatureMin")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(ambientTemperatureMin, PUNI_DBL) + phid->ambientTemperatureMin = value; + } + else if(KEYNAME("AmbientTemperatureMax")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(ambientTemperatureMax, PUNI_DBL) + phid->ambientTemperatureMax = value; + } + else if(KEYNAME("ThermocoupleType")) + { + GET_INT_VAL; + INC_KEYCOUNT(ThermocoupleType[index], -1) + phid->ThermocoupleType[index] = value; + } + else if(KEYNAME("Trigger")) + { + if(CHKINDEX(temperaturesensor.numTempInputs, TEMPSENSOR_MAXSENSORS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(TempChangeTrigger[index], PUNI_DBL) + phid->TempChangeTrigger[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } + else{ + PWC_BAD_SETTYPE(TemperatureSensor); + } + return ret; +} + +PWC_SETKEYS(TextLCD) + GET_INT_VAL; + + if(KEYNAME("NumberOfRows")) + { + INC_KEYCOUNT(rowCount[index], PUNI_INT) + phid->rowCount[index] = value; + } + else if(KEYNAME("NumberOfColumns")) + { + INC_KEYCOUNT(columnCount[index], PUNI_INT) + phid->columnCount[index] = value; + } + else if(KEYNAME("NumberOfScreens")) + { + phid->phid.attr.textlcd.numScreens = value; + phid->phid.keyCount++; + } + else if(KEYNAME("Backlight")) + { + INC_KEYCOUNT(backlightEcho[index], PUNI_BOOL) + phid->backlightEcho[index] = (unsigned char)value; + } + else if(KEYNAME("CursorOn")) + { + phid->cursorOn[index] = (unsigned char)value; + } + else if(KEYNAME("CursorBlink")) + { + phid->cursorBlink[index] = (unsigned char)value; + } + else if(KEYNAME("Contrast")) + { + INC_KEYCOUNT(contrastEcho[index], PUNI_INT) + phid->contrastEcho[index] = (unsigned char)value; + } + else if(KEYNAME("Brightness")) + { + INC_KEYCOUNT(brightnessEcho[index], PUNI_INT) + phid->brightnessEcho[index] = (unsigned char)value; + } + else if(KEYNAME("ScreenSize")) + { + INC_KEYCOUNT(screenSize[index], -1) + phid->screenSize[index] = value; + } + else{ + PWC_BAD_SETTYPE(TextLCD); + } + return ret; +} + +PWC_SETKEYS(TextLED) + GET_INT_VAL; + if(KEYNAME("NumberOfRows")) + { + phid->phid.attr.textled.numRows = value; + phid->phid.keyCount++; + } + else if(KEYNAME("NumberOfColumns")) + { + phid->phid.attr.textled.numColumns = value; + phid->phid.keyCount++; + } + // this is unknown at attach, so no keyCount++ + else if(KEYNAME("Brightness")) + { + phid->brightness = value; + } + else{ + PWC_BAD_SETTYPE(TextLED); + } + return ret; +} + +PWC_SETKEYS(WeightSensor) + if(KEYNAME("Weight")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(Weight, PUNI_DBL) + phid->Weight = value; + if(value != PUNK_DBL) + FIRE(WeightChange, value); + } + else if(KEYNAME("Trigger")) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(WeightChangeTrigger, PUNI_DBL) + phid->WeightChangeTrigger = value; + } + else{ + PWC_BAD_SETTYPE(WeightSensor); + } + return ret; +} + +int(*fptrSet[PHIDGET_DEVICE_CLASS_COUNT])(CPhidgetHandle generic_phid, const char *setThing, int index, const char *state, pdict_reason_t reason) = { +NULL, +NULL, +phidgetAccelerometer_set, +phidgetAdvancedServo_set, +phidgetEncoder_set, +phidgetGPS_set, +NULL,//old gyro, +phidgetInterfaceKit_set, +phidgetLED_set, +phidgetMotorControl_set, +phidgetPHSensor_set, +phidgetRFID_set, +phidgetServo_set, +phidgetStepper_set, +phidgetTemperatureSensor_set, +phidgetTextLCD_set, +phidgetTextLED_set, +phidgetWeightSensor_set, +phidgetGeneric_set, +phidgetIR_set, +phidgetSpatial_set, +phidgetFrequencyCounter_set, +phidgetAnalog_set, +phidgetBridge_set}; +void network_phidget_event_handler(const char *key, const char *val, unsigned int len, pdict_reason_t reason, void *ptr) +{ + CPhidgetHandle phid = (CPhidgetHandle)ptr; + regmatch_t pmatch[7]; + char *setThing = NULL; + char *index = NULL; + char *serial = NULL; + char *label = NULL, *l = NULL; + char errbuf[1024]; + + int serialNumber; + + int res, ind = PUNK_INT, i, ret = EPHIDGET_OK; + + if(!strncmp(val, "\001", 1) && len == 1) + { + memset((char *)val,0,1); + } + + + if(!CPhidget_statusFlagIsSet(phid->status, PHIDGET_SERVER_CONNECTED_FLAG)) + { + LOG(PHIDGET_LOG_VERBOSE, "network_phidget_event_handler: key ignored: %s Value: %s",key,val); + } + else if(reason!=PDR_ENTRY_REMOVING || !strncmp(val, "Detached", sizeof("Detached"))) + { + LOG(PHIDGET_LOG_VERBOSE, "network_phidget_event_handler: key: %s Value: %s",key,val); + if ((res = regexec(&phidgetsetex, key, 7, pmatch, 0)) != 0) { + LOG(PHIDGET_LOG_DEBUG,"Error in network_phidget_event_handler - pattern not met for key: \"%s\"",key); + return; + } + getmatchsub(key, &label, pmatch, 2); + getmatchsub(key, &serial, pmatch, 3); + getmatchsub(key, &setThing, pmatch, 4); + getmatchsub(key, &index, pmatch, 5); + + if(l) + { + if (!unescape(l, &label, NULL)) + { + LOG(PHIDGET_LOG_ERROR, "Error in unescape"); + return; + } + } + + serialNumber = strtol(serial, NULL, 10); + + if(phid->specificDevice == PHIDGETOPEN_ANY && strncmp(val, "Detached", sizeof("Detached"))) + { + phid->specificDevice = PHIDGETOPEN_ANY_ATTACHED; + phid->serialNumber = serialNumber; + } + + if(phid->specificDevice == PHIDGETOPEN_LABEL && strncmp(val, "Detached", sizeof("Detached"))) + { + phid->serialNumber = serialNumber; + } + + if(serialNumber == phid->serialNumber && setThing) + { + if(KEYNAME("Label")) + { + strncpy(phid->label, val, MAX_LABEL_STORAGE); + phid->keyCount++; + } + else if(KEYNAME("InitKeys")) + { + phid->initKeys = strtol(val, NULL, 10); + phid->keyCount++; + } + else if(KEYNAME("Version")) + { + phid->deviceVersion = strtol(val, NULL, 10); + phid->keyCount++; + } + else if(KEYNAME("ID")) + { + phid->deviceIDSpec = strtol(val, NULL, 10); + phid->deviceType = Phid_DeviceName[phid->deviceID]; + phid->keyCount++; + + for(i = 1;ideviceIDSpec) + { + phid->deviceDef = &Phid_Device_Def[i]; + phid->attr = Phid_Device_Def[i].pdd_attr; + break; + } + } + } + else if(KEYNAME("Name")) + { + phid->keyCount++; + } + else if(KEYNAME("Error")) + { + char *endptr; + int errcode = strtol(val, &endptr, 10); + char *errstr = endptr+1; + FIRE_ERROR_BUF(errcode, errstr); + } + else if(KEYNAME("Status")) + { + if(!strncmp(val, "Attached", sizeof("Attached"))) + { + phid->keyCount++; + } + else if(!strncmp(val, "Detached", sizeof("Detached"))) + { + CThread_mutex_lock(&phid->lock); + phid->keyCount = 0; + if(phid->specificDevice == PHIDGETOPEN_ANY_ATTACHED) + { + phid->specificDevice = PHIDGETOPEN_ANY; + } + CPhidget_clearStatusFlag(&phid->status, PHIDGET_ATTACHED_FLAG, NULL); + CPhidget_setStatusFlag(&phid->status, PHIDGET_DETACHING_FLAG, NULL); + CThread_mutex_unlock(&phid->lock); + + if (phid->fptrDetach) + { + SET_RUNNING_EVENT(phid) + phid->fptrDetach((CPhidgetHandle)phid, phid->fptrDetachptr); + CLEAR_RUNNING_EVENT(phid) + } + + //clear all variables + phid->fptrClear((CPhidgetHandle)phid); + + //if mDNS & any server, disconnect +#ifdef USE_ZEROCONF + CThread_mutex_lock(&phid->lock); + if(phid->networkInfo && !phid->networkInfo->requested_address && !phid->networkInfo->requested_serverID) + { + CThread DisconnectPhidgetThread; + CThread_mutex_unlock(&phid->lock); + CThread_mutex_lock(&zeroconfPhidgetsLock); + CList_removeFromList((CListHandle *)&zeroconfPhidgets, phid, CPhidget_areExtraEqual, TRUE, CPhidget_free); + CThread_mutex_unlock(&zeroconfPhidgetsLock); + CThread_create_detached(&DisconnectPhidgetThread, DisconnectPhidgetThreadFunction, phid); + } + CThread_mutex_unlock(&phid->lock); +#endif + + CPhidget_clearStatusFlag(&phid->status, PHIDGET_DETACHING_FLAG, NULL); + + phid->deviceIDSpec = 0; + ZEROMEM(&phid->attr, sizeof(CPhidgetAttr)); + if(phid->specificDevice != PHIDGETOPEN_LABEL) + ZEROMEM(phid->label, MAX_LABEL_STORAGE); + phid->deviceVersion = 0; + phid->initKeys = PUNK_INT; + + } + else + { + throw_error_event(phid, "Bad Message type for Status set", EEPHIDGET_NETWORK); + } + } + else if(fptrSet[phid->deviceID] && setThing) + { + if(index) + ind = strtol(index, NULL, 10); + + SET_RUNNING_EVENT(phid) + ret = fptrSet[phid->deviceID](phid, setThing, ind, val, reason); + CLEAR_RUNNING_EVENT(phid) + } + + if((phid->initKeys != PUNK_INT) + && (phid->keyCount >= phid->initKeys) + && !CPhidget_statusFlagIsSet(phid->status, PHIDGET_ATTACHED_FLAG) + && CPhidget_statusFlagIsSet(phid->status, PHIDGET_OPENED_FLAG)) + { + LOG(PHIDGET_LOG_VERBOSE, "Got all initkeys, run attach - %d/%d", phid->keyCount, phid->initKeys); + + CPhidget_setStatusFlag(&phid->status, PHIDGET_ATTACHED_FLAG, &phid->lock); + + SET_RUNNING_EVENT(phid) + if (phid->fptrAttach) + phid->fptrAttach(phid, phid->fptrAttachptr); + phid->fptrEvents((CPhidgetHandle)phid); + CLEAR_RUNNING_EVENT(phid) + } + else + LOG(PHIDGET_LOG_VERBOSE, "Accumulating initkeys for attach - %d/%d", phid->keyCount, phid->initKeys == PUNK_INT ? 0 : phid->initKeys); + + //LOG(PHIDGET_LOG_DEBUG, "Message: %s(%s)=%s (%d of %d)", setThing, index, val, phid->keyCount, phid->initKeys); + } + + free(setThing); setThing = NULL; + free(index); index = NULL; + free(serial); serial = NULL; + } + + if(ret) + { + snprintf(errbuf, 1024, "Problem during Network set (Phidget): %s\n (Key:\"%s\", Val:\"%s\"", CPhidget_strerror(ret), key, val); + throw_error_event(phid, errbuf, EEPHIDGET_NETWORK); + } +} + +void network_manager_event_handler(const char *key, const char *val, unsigned int vallen, pdict_reason_t reason, void *ptr) +{ + CPhidgetManagerHandle phidm = (CPhidgetManagerHandle)ptr; + regmatch_t keymatch[6], valmatch[6]; + char *attachDetach = NULL; + char *deviceType = NULL; + char *serial = NULL; + char *version = NULL; + char *deviceIDSpec = NULL; + char *label = NULL; + char errbuf[1024]; + + int serialNumber; + CPhidgetHandle phid; + + //BL:Changed to init Len before use + int len = 0; + + int res, ret = EPHIDGET_OK; + + int i; + + if(!phidm) return; + + if(!strncmp(val, "\001", 1) && (len == 1)) + { + memset((char *)val,0,1); + } + + if(reason!=PDR_ENTRY_REMOVING) + { + if ((res = regexec(&managerex, key, 3, keymatch, 0)) != 0) { + LOG(PHIDGET_LOG_DEBUG,"Error in network_manager_event_handler - key pattern not met"); + return; + } + if ((res = regexec(&managervalex, val, 5, valmatch, 0)) != 0) { + LOG(PHIDGET_LOG_DEBUG,"Error in network_manager_event_handler - val pattern not met"); + return; + } + getmatchsub(key, &deviceType, keymatch, 1); + getmatchsub(key, &serial, keymatch, 2); + + getmatchsub(val, &attachDetach, valmatch, 1); + getmatchsub(val, &version, valmatch, 2); + getmatchsub(val, &deviceIDSpec, valmatch, 3); + getmatchsub(val, &label, valmatch, 4); + + serialNumber = strtol(serial, NULL, 10); + + if((CPhidget_create(&phid))) return; + + phid->deviceID = phidget_type_to_id(deviceType); + phid->deviceType = Phid_DeviceName[phid->deviceID]; + phid->serialNumber = serialNumber; + phid->deviceIDSpec = (unsigned short)strtol(deviceIDSpec, NULL, 10); + phid->deviceVersion = strtol(version, NULL, 10); + phid->specificDevice = PHIDGETOPEN_SERIAL; //so it actually compares the serial + + for(i = 1;ideviceIDSpec == Phid_Device_Def[i].pdd_sdid) break; + phid->deviceDef = &Phid_Device_Def[i]; + phid->attr = Phid_Device_Def[i].pdd_attr; + + //so se can get address, etc. from devices. + phid->networkInfo = phidm->networkInfo; + CPhidget_setStatusFlag(&phid->status, PHIDGET_REMOTE_FLAG, &phid->lock); + CPhidget_setStatusFlag(&phid->status, PHIDGET_SERVER_CONNECTED_FLAG, &phid->lock); + + if(label) + { + strncpy(phid->label, label, MAX_LABEL_STORAGE); + } + + if(!strncmp(attachDetach, "Attached", sizeof("Attached"))) + { + CPhidget_setStatusFlag(&phid->status, PHIDGET_ATTACHED_FLAG, &phid->lock); + + CList_addToList((CListHandle *)&phidm->AttachedPhidgets, phid, CPhidget_areEqual); + + if (phidm->fptrAttachChange && phidm->state == PHIDGETMANAGER_ACTIVE) + { + SET_RUNNING_EVENT(phidm) + phidm->fptrAttachChange((CPhidgetHandle)phid, phidm->fptrAttachChangeptr); + CLEAR_RUNNING_EVENT(phidm) + } + } + + if(!strncmp(attachDetach, "Detached", sizeof("Detached"))) + { + CPhidget_clearStatusFlag(&phid->status, PHIDGET_ATTACHED_FLAG, &phid->lock); + CPhidget_setStatusFlag(&phid->status, PHIDGET_DETACHING_FLAG, &phid->lock); + if(CList_findInList((CListHandle)phidm->AttachedPhidgets, phid, CPhidget_areEqual, NULL) == EPHIDGET_OK) + { + if (phidm->fptrDetachChange && phidm->state == PHIDGETMANAGER_ACTIVE) + { + SET_RUNNING_EVENT(phidm) + phidm->fptrDetachChange((CPhidgetHandle)phid, phidm->fptrDetachChangeptr); + CLEAR_RUNNING_EVENT(phid) + } + + CList_removeFromList((CListHandle *)&phidm->AttachedPhidgets, phid, CPhidget_areEqual, PTRUE, CPhidget_free); + } + CPhidget_clearStatusFlag(&phid->status, PHIDGET_DETACHING_FLAG, &phid->lock); + CPhidget_free(phid); phid = NULL; + } + + free(deviceType); deviceType = NULL; + free(label); label = NULL; + free(attachDetach); attachDetach = NULL; + free(serial); serial = NULL; + free(version); version = NULL; + free(deviceIDSpec); deviceIDSpec = NULL; + } + + if(ret) + { + snprintf(errbuf, 1024, "Problem during Network set (Manager): %s\n (Key:\"%s\", Val:\"%s\"", CPhidget_strerror(ret), key, val); + throw_error_event((CPhidgetHandle)phidm, errbuf, EEPHIDGET_NETWORK); + } +} + +void network_heartbeat_event_handler(const char *key, const char *val, unsigned int len, pdict_reason_t reason, void *ptr) +{ + CPhidgetSocketClientHandle server = (CPhidgetSocketClientHandle)ptr; + double duration = timeSince(&server->lastHeartbeatTime); + + //Keeps a rolling average of the last 5 times + if(server->avgHeartbeatTimeCount > 5) + { + double avg = server->avgHeartbeatTime / server->avgHeartbeatTimeCount; + server->avgHeartbeatTime -= avg; + server->avgHeartbeatTimeCount--; + } + server->avgHeartbeatTime += duration; + server->avgHeartbeatTimeCount++; + + server->heartbeatCount++; + + setTimeNow(&server->lastHeartbeatTime); + server->waitingForHeartbeat = PFALSE; +} -- cgit v1.2.3