int read_dcraw(const char *filename, uint8_t **memptr, size_t *memsize, int *n_axis, int *w, int *h, int *bitsperpixel) { struct dcraw_header header; FILE *handle = NULL; char *cmd; if (dcraw_parse_header_info(filename, &header) || ! header.width || ! header.height) { DEBUGDEVICE(device, INDI::Logger::DBG_DEBUG, "read_file_from_dcraw: failed to parse header"); return -1; } DEBUGFDEVICE(device, INDI::Logger::DBG_DEBUG, "Reading exposure %d x %d", header.width, header.height); asprintf(&cmd, "%s -c -t 0 -4 -D %s", dcraw_cmd, filename); DEBUGFDEVICE(device, INDI::Logger::DBG_DEBUG, "%s", cmd); handle = popen(cmd, "r"); free(cmd); if (handle == NULL) { DEBUGDEVICE(device, INDI::Logger::DBG_DEBUG, "read_file_from_dcraw: failed to run dcraw"); return -1; } int rc= read_ppm(handle, &header, memptr, memsize, n_axis, w, h, bitsperpixel); pclose(handle); return rc; }
bool EQModSimulator::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { // first check if it's for our device if(strcmp(dev,telescope->getDeviceName())==0) { ITextVectorProperty *tvp =telescope->getText(name); if (tvp) { if ((tvp != SimMCVersionTP)) return false; if (telescope->isConnected()) { DEBUGDEVICE(telescope->getDeviceName(), INDI::Logger::DBG_WARNING,"Can not change simulation settings when mount is already connected"); return false; } tvp->s=IPS_OK; IUUpdateText(tvp,texts,names,n); IDSetText(tvp,NULL); return true; } } return false; }
bool FocuserInterface::AbortFocuser() { // This should be a virtual function, because the low level hardware class // must override this DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_ERROR, "Focuser does not support abort motion."); return false; }
void INDI::LightBoxInterface::addFilterDuration(const char *filterName, uint16_t filterDuration) { if (FilterIntensityN == nullptr) { FilterIntensityN = (INumber *)malloc(sizeof(INumber)); DEBUGDEVICE(device->getDeviceName(), INDI::Logger::DBG_SESSION, "Filter intensity preset created."); } else { // Ensure no duplicates for (int i = 0; i < FilterIntensityNP.nnp + 1; i++) { if (!strcmp(filterName, FilterIntensityN[i].name)) return; } FilterIntensityN = (INumber *)realloc(FilterIntensityN, (FilterIntensityNP.nnp + 1) * sizeof(INumber)); } IUFillNumber(&FilterIntensityN[FilterIntensityNP.nnp], filterName, filterName, "%0.f", 0, LightIntensityN[0].max, LightIntensityN[0].step, filterDuration); FilterIntensityNP.nnp++; FilterIntensityNP.np = FilterIntensityN; }
bool Driver::checkConnection(int fd) { char res[IOP_BUFFER]={0}; DEBUGDEVICE(m_DeviceName, INDI::Logger::DBG_DEBUG, "Initializing IOptron using :MountInfo# CMD..."); // Set FD for use PortFD = fd; if (m_Simulation) return true; for (int i = 0; i < 2; i++) { if (sendCommand(":MountInfo#", 4, res, 3) == false) { usleep(50000); continue; } return true; } return false; }
bool FocuserInterface::SetFocuserSpeed(int speed) { INDI_UNUSED(speed); // This should be a virtual function, because the low level hardware class // must override this DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_ERROR, "Focuser does not support variable speed."); return false; }
bool slew_ieqpro(int fd) { char cmd[] = ":MS#"; int errcode = 0; char errmsg[MAXRBUF]; char response[8]; int nbytes_read=0; int nbytes_written=0; DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD (%s)", cmd); if (ieqpro_simulation) { simInfo.systemStatus = ST_SLEWING; strcpy(response, "1"); nbytes_read = strlen(response); } else { if ( (errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK) { tty_error_msg(errcode, errmsg, MAXRBUF); DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg); return false; } if ( (errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read))) { tty_error_msg(errcode, errmsg, MAXRBUF); DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg); return false; } } if (nbytes_read > 0) { response[nbytes_read] = '\0'; DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES (%s)", response); if (!strcmp(response, "1")) { tcflush(fd, TCIFLUSH); return true; } else { DEBUGDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Requested object is below horizon."); tcflush(fd, TCIFLUSH); return false; } } DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read); return false; }
bool check_ieqpro_connection(int fd) { char initCMD[] = ":V#"; int errcode = 0; char errmsg[MAXRBUF]; char response[8]; int nbytes_read=0; int nbytes_written=0; DEBUGDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "Initializing IOptron using :V# CMD..."); for (int i=0; i < 2; i++) { if (ieqpro_simulation) { strcpy(response, "V1.00#"); nbytes_read= strlen(response); } else { if ( (errcode = tty_write(fd, initCMD, 3, &nbytes_written)) != TTY_OK) { tty_error_msg(errcode, errmsg, MAXRBUF); DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg); usleep(50000); continue; } if ( (errcode = tty_read_section(fd, response, '#', IEQPRO_TIMEOUT, &nbytes_read))) { tty_error_msg(errcode, errmsg, MAXRBUF); DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg); usleep(50000); continue; } } if (nbytes_read > 0) { response[nbytes_read] = '\0'; DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES (%s)", response); if (!strcmp(response, "V1.00#")) return true; } usleep(50000); } return false; }
bool EQModSimulator::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { // first check if it's for our device if(strcmp(dev,telescope->getDeviceName())==0) { INumberVectorProperty *nvp =telescope->getNumber(name); if ((nvp != SimWormNP) && (nvp != SimRatioNP) & (nvp != SimMotorNP)) return false; if (telescope->isConnected()) { DEBUGDEVICE(telescope->getDeviceName(), INDI::Logger::DBG_WARNING,"Can not change simulation settings when mount is already connected"); return false; } nvp->s=IPS_OK; IUUpdateNumber(nvp,values,names,n); IDSetNumber(nvp,NULL); return true; } return false; }
bool EQModSimulator::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { // first check if it's for our device if(strcmp(dev,telescope->getDeviceName())==0) { ISwitchVectorProperty *svp =telescope->getSwitch(name); if ((svp != SimModeSP) && (svp != SimHighSpeedSP)) return false; if (telescope->isConnected()) { DEBUGDEVICE(telescope->getDeviceName(), INDI::Logger::DBG_WARNING,"Can not change simulation settings when mount is already connected"); return false; } svp->s=IPS_OK; IUUpdateSwitch(svp,states,names,n); IDSetSwitch(svp,NULL); return true; } return false; }
IPState RotatorInterface::HomeRotator() { DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_ERROR, "Rotator does not support homing."); return IPS_ALERT; }
bool RotatorInterface::SyncRotator(double angle) { INDI_UNUSED(angle); DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_ERROR, "Rotator does not support syncing."); return false; }
bool RotatorInterface::processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) { INDI_UNUSED(states); INDI_UNUSED(names); INDI_UNUSED(n); if (dev != nullptr && strcmp(dev, m_defaultDevice->getDeviceName()) == 0) { //////////////////////////////////////////// // Abort //////////////////////////////////////////// if (strcmp(name, AbortRotatorSP.name) == 0) { AbortRotatorSP.s = AbortRotator() ? IPS_OK : IPS_ALERT; IDSetSwitch(&AbortRotatorSP, nullptr); if (AbortRotatorSP.s == IPS_OK) { if (GotoRotatorNP.s != IPS_OK) { GotoRotatorNP.s = IPS_OK; IDSetNumber(&GotoRotatorNP, nullptr); } } return true; } //////////////////////////////////////////// // Home //////////////////////////////////////////// else if (strcmp(name, HomeRotatorSP.name) == 0) { HomeRotatorSP.s = HomeRotator(); IUResetSwitch(&HomeRotatorSP); if (HomeRotatorSP.s == IPS_BUSY) HomeRotatorS[0].s = ISS_ON; IDSetSwitch(&HomeRotatorSP, nullptr); return true; } //////////////////////////////////////////// // Reverse Rotator //////////////////////////////////////////// else if (strcmp(name, ReverseRotatorSP.name) == 0) { bool rc = false; bool enabled = (!strcmp(IUFindOnSwitchName(states, names, n), "ENABLED")); rc = ReverseRotator(enabled); if (rc) { IUUpdateSwitch(&ReverseRotatorSP, states, names, n); ReverseRotatorSP.s = IPS_OK; DEBUGFDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_SESSION, "Rotator direction is %s.", (enabled ? "reversed" : "normal")); } else { ReverseRotatorSP.s = IPS_ALERT; DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_SESSION, "Rotator reverse direction failed."); } IDSetSwitch(&ReverseRotatorSP, nullptr); return true; } } return false; }
int read_ppm(FILE *handle, struct dcraw_header *header, uint8_t **memptr, size_t *memsize, int *n_axis, int *w, int *h, int *bitsperpixel) { char prefix[] = {0, 0}; int bpp, maxcolor, row, i; uint8_t *ppm = NULL; uint8_t *r_data = NULL, *g_data, *b_data; int width, height; int naxis = 2; prefix[0] = fgetc(handle); prefix[1] = fgetc(handle); if (prefix[0] != 'P' || (prefix[1] != '6' && prefix[1] != '5')) { DEBUGFDEVICE(device, INDI::Logger::DBG_DEBUG, "read_ppm: got unexpected prefix %x %x", prefix[0], prefix[1]); return -1; } if (prefix[1] == '6') naxis = 3; *n_axis = naxis; width = read_uint(handle); height = read_uint(handle); if (width != header->width || height != header->height) { DEBUGFDEVICE(device, INDI::Logger::DBG_DEBUG, "read_ppm: Expected (%d x %d) but image is actually (%d x %d)", header->width, header->height, width, height); //return -1; } *w = width; *h = height; maxcolor = read_uint(handle); fgetc(handle); if (maxcolor > 65535) { DEBUGDEVICE(device, INDI::Logger::DBG_DEBUG, "read_ppm: 32bit PPM isn't supported"); return -1; } else if (maxcolor > 255) { bpp = 2; *bitsperpixel = 16; } else { bpp = 1; *bitsperpixel = 8; } *memsize = width * height * bpp * (naxis == 2 ? 1 : 3); *memptr = (uint8_t *) realloc(*memptr, *memsize); uint8_t *oldmem = *memptr; // if you do some ugly pointer math, remember to restore the original pointer or some random crashes will happen. This is why I do not like pointers!! ppm = (uint8_t*) malloc(width * bpp); if (naxis == 3) { r_data = (uint8_t *) *memptr; g_data = r_data + width * height * bpp; b_data = r_data + 2 * width * height * bpp; } for (row = 0; row < height; row++) { int len; len = fread(ppm, 1, width * bpp, handle); if (len != width * bpp) { DEBUGFDEVICE(device, INDI::Logger::DBG_DEBUG, "read_ppm: aborted during PPM reading at row: %d, read %d bytes", row, len); free(ppm); return -1; } if (bpp == 2) { uint16_t *ppm16 = (uint16_t *)ppm; if (htons(0x55aa) != 0x55aa) { swab(ppm, ppm, width * bpp); } if (naxis == 3) { for (i = 0; i < width; i++) { *(uint16_t *)r_data++ = *ppm16++; *(uint16_t *)g_data++ = *ppm16++; *(uint16_t *)b_data++ = *ppm16++; } } else { memcpy(*memptr, ppm16, width*bpp); *memptr += width*bpp; } } else { uint8_t *ppm8 = ppm; if (naxis == 3) { for (i = 0; i < width; i++) { *r_data++ = *ppm8++; *g_data++ = *ppm8++; *b_data++ = *ppm8++; } } else { memcpy(*memptr, ppm8, width*bpp); *memptr += width*bpp; } } } free(ppm); *memptr = oldmem; return 0; }
bool FocuserInterface::processNumber(const char *dev, const char *name, double values[], char *names[], int n) { // This is for our device // Now lets see if it's something we process here if (strcmp(name, "FOCUS_TIMER") == 0) { FocusDirection dir; int speed; int t; // first we get all the numbers just sent to us IUUpdateNumber(&FocusTimerNP, values, names, n); // Now lets find what we need for this move speed = FocusSpeedN[0].value; if (FocusMotionS[0].s == ISS_ON) dir = FOCUS_INWARD; else dir = FOCUS_OUTWARD; t = FocusTimerN[0].value; lastTimerValue = t; FocusTimerNP.s = MoveFocuser(dir, speed, t); IDSetNumber(&FocusTimerNP, nullptr); return true; } if (strcmp(name, "FOCUS_SPEED") == 0) { FocusSpeedNP.s = IPS_OK; int current_speed = FocusSpeedN[0].value; IUUpdateNumber(&FocusSpeedNP, values, names, n); if (SetFocuserSpeed(FocusSpeedN[0].value) == false) { FocusSpeedN[0].value = current_speed; FocusSpeedNP.s = IPS_ALERT; } // Update client display IDSetNumber(&FocusSpeedNP, nullptr); return true; } if (strcmp(name, "ABS_FOCUS_POSITION") == 0) { int newPos = (int)values[0]; if (newPos < FocusAbsPosN[0].min) { FocusAbsPosNP.s = IPS_ALERT; IDSetNumber(&FocusAbsPosNP, nullptr); DEBUGFDEVICE(dev, Logger::DBG_ERROR, "Requested position out of bound. Focus minimum position is %g", FocusAbsPosN[0].min); return false; } else if (newPos > FocusAbsPosN[0].max) { FocusAbsPosNP.s = IPS_ALERT; IDSetNumber(&FocusAbsPosNP, nullptr); DEBUGFDEVICE(dev, Logger::DBG_ERROR, "Requested position out of bound. Focus maximum position is %g", FocusAbsPosN[0].max); return false; } IPState ret; if ((ret = MoveAbsFocuser(newPos)) == IPS_OK) { FocusAbsPosNP.s = IPS_OK; IUUpdateNumber(&FocusAbsPosNP, values, names, n); DEBUGFDEVICE(dev, Logger::DBG_SESSION, "Focuser moved to position %d", newPos); IDSetNumber(&FocusAbsPosNP, nullptr); return true; } else if (ret == IPS_BUSY) { FocusAbsPosNP.s = IPS_BUSY; DEBUGFDEVICE(dev, Logger::DBG_SESSION, "Focuser is moving to position %d", newPos); IDSetNumber(&FocusAbsPosNP, nullptr); return true; } FocusAbsPosNP.s = IPS_ALERT; DEBUGDEVICE(dev, Logger::DBG_ERROR, "Focuser failed to move to new requested position."); IDSetNumber(&FocusAbsPosNP, nullptr); return false; } if (strcmp(name, "REL_FOCUS_POSITION") == 0) { int newPos = (int)values[0]; if (newPos <= 0) { DEBUGDEVICE(dev, Logger::DBG_ERROR, "Relative ticks value must be greater than zero."); FocusRelPosNP.s = IPS_ALERT; IDSetNumber(&FocusRelPosNP, nullptr); return false; } IPState ret; if (CanAbsMove()) { if (FocusMotionS[0].s == ISS_ON) { if (FocusAbsPosN[0].value - newPos < FocusAbsPosN[0].min) { FocusRelPosNP.s = IPS_ALERT; IDSetNumber(&FocusRelPosNP, nullptr); DEBUGFDEVICE(dev, Logger::DBG_ERROR, "Requested position out of bound. Focus minimum position is %g", FocusAbsPosN[0].min); return false; } } else { if (FocusAbsPosN[0].value + newPos > FocusAbsPosN[0].max) { FocusRelPosNP.s = IPS_ALERT; IDSetNumber(&FocusRelPosNP, nullptr); DEBUGFDEVICE(dev, Logger::DBG_ERROR, "Requested position out of bound. Focus maximum position is %g", FocusAbsPosN[0].max); return false; } } } if ((ret = MoveRelFocuser((FocusMotionS[0].s == ISS_ON ? FOCUS_INWARD : FOCUS_OUTWARD), newPos)) == IPS_OK) { FocusRelPosNP.s = FocusAbsPosNP.s = IPS_OK; IUUpdateNumber(&FocusRelPosNP, values, names, n); IDSetNumber(&FocusRelPosNP, "Focuser moved %d steps %s", newPos, FocusMotionS[0].s == ISS_ON ? "inward" : "outward"); IDSetNumber(&FocusAbsPosNP, nullptr); return true; } else if (ret == IPS_BUSY) { IUUpdateNumber(&FocusRelPosNP, values, names, n); FocusRelPosNP.s = FocusAbsPosNP.s = IPS_BUSY; IDSetNumber(&FocusAbsPosNP, "Focuser is moving %d steps %s...", newPos, FocusMotionS[0].s == ISS_ON ? "inward" : "outward"); IDSetNumber(&FocusAbsPosNP, nullptr); return true; } FocusRelPosNP.s = IPS_ALERT; DEBUGDEVICE(dev, Logger::DBG_ERROR, "Focuser failed to move to new requested position."); IDSetNumber(&FocusRelPosNP, nullptr); return false; } return false; }
bool RotatorInterface::AbortRotator() { DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_ERROR, "Rotator does not support abort."); return false; }
bool FocuserInterface::SyncFocuser(uint32_t ticks) { INDI_UNUSED(ticks); DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_ERROR, "Focuser does not support syncing."); return false; }
bool FocuserInterface::ReverseFocuser(bool enabled) { INDI_UNUSED(enabled); DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_ERROR, "Focuser does not support reverse motion."); return false; }
bool FocuserInterface::processNumber(const char * dev, const char * name, double values[], char * names[], int n) { // Move focuser based on requested timeout if (!strcmp(name, FocusTimerNP.name)) { FocusDirection dir; int speed; int t; // first we get all the numbers just sent to us IUUpdateNumber(&FocusTimerNP, values, names, n); // Now lets find what we need for this move speed = FocusSpeedN[0].value; if (FocusMotionS[0].s == ISS_ON) dir = FOCUS_INWARD; else dir = FOCUS_OUTWARD; t = FocusTimerN[0].value; lastTimerValue = t; FocusTimerNP.s = MoveFocuser(dir, speed, t); IDSetNumber(&FocusTimerNP, nullptr); return true; } // Set variable focus speed if (!strcmp(name, FocusSpeedNP.name)) { FocusSpeedNP.s = IPS_OK; int current_speed = FocusSpeedN[0].value; IUUpdateNumber(&FocusSpeedNP, values, names, n); if (SetFocuserSpeed(FocusSpeedN[0].value) == false) { FocusSpeedN[0].value = current_speed; FocusSpeedNP.s = IPS_ALERT; } // Update client display IDSetNumber(&FocusSpeedNP, nullptr); return true; } // Update Maximum Position allowed if (!strcmp(name, FocusMaxPosNP.name)) { uint32_t maxTravel = rint(values[0]); if (SetFocuserMaxPosition(maxTravel)) { IUUpdateNumber(&FocusMaxPosNP, values, names, n); FocusAbsPosN[0].max = FocusSyncN[0].max = FocusMaxPosN[0].value; FocusAbsPosN[0].step = FocusSyncN[0].step = FocusMaxPosN[0].value / 50.0; FocusAbsPosN[0].min = FocusSyncN[0].min = 0; FocusRelPosN[0].max = FocusMaxPosN[0].value / 2; FocusRelPosN[0].step = FocusMaxPosN[0].value / 100.0; FocusRelPosN[0].min = 0; IUUpdateMinMax(&FocusAbsPosNP); IUUpdateMinMax(&FocusRelPosNP); IUUpdateMinMax(&FocusSyncNP); FocusMaxPosNP.s = IPS_OK; } else FocusMaxPosNP.s = IPS_ALERT; IDSetNumber(&FocusMaxPosNP, nullptr); return true; } // Sync if (!strcmp(name, FocusSyncNP.name)) { if (SyncFocuser(rint(values[0]))) { FocusSyncN[0].value = FocusAbsPosN[0].value = rint(values[0]); FocusSyncNP.s = IPS_OK; IDSetNumber(&FocusSyncNP, nullptr); IDSetNumber(&FocusAbsPosNP, nullptr); } else { FocusSyncNP.s = IPS_ALERT; IDSetNumber(&FocusSyncNP, nullptr); } return true; } // Update Absolute Focuser Position if (!strcmp(name, FocusAbsPosNP.name)) { int newPos = rint(values[0]); if (newPos < FocusAbsPosN[0].min) { FocusAbsPosNP.s = IPS_ALERT; IDSetNumber(&FocusAbsPosNP, nullptr); DEBUGFDEVICE(dev, Logger::DBG_ERROR, "Requested position out of bound. Focus minimum position is %g", FocusAbsPosN[0].min); return false; } else if (newPos > FocusAbsPosN[0].max) { FocusAbsPosNP.s = IPS_ALERT; IDSetNumber(&FocusAbsPosNP, nullptr); DEBUGFDEVICE(dev, Logger::DBG_ERROR, "Requested position out of bound. Focus maximum position is %g", FocusAbsPosN[0].max); return false; } IPState ret; if ((ret = MoveAbsFocuser(newPos)) == IPS_OK) { FocusAbsPosNP.s = IPS_OK; IUUpdateNumber(&FocusAbsPosNP, values, names, n); DEBUGFDEVICE(dev, Logger::DBG_SESSION, "Focuser moved to position %d", newPos); IDSetNumber(&FocusAbsPosNP, nullptr); return true; } else if (ret == IPS_BUSY) { FocusAbsPosNP.s = IPS_BUSY; DEBUGFDEVICE(dev, Logger::DBG_SESSION, "Focuser is moving to position %d", newPos); IDSetNumber(&FocusAbsPosNP, nullptr); return true; } FocusAbsPosNP.s = IPS_ALERT; DEBUGDEVICE(dev, Logger::DBG_ERROR, "Focuser failed to move to new requested position."); IDSetNumber(&FocusAbsPosNP, nullptr); return false; } // Update Relative focuser steps. This moves the focuser CW/CCW by this number of steps. if (!strcmp(name, FocusRelPosNP.name)) { int newPos = rint(values[0]); if (newPos <= 0) { DEBUGDEVICE(dev, Logger::DBG_ERROR, "Relative ticks value must be greater than zero."); FocusRelPosNP.s = IPS_ALERT; IDSetNumber(&FocusRelPosNP, nullptr); return false; } IPState ret; if (CanAbsMove()) { if (FocusMotionS[0].s == ISS_ON) { if (FocusAbsPosN[0].value - newPos < FocusAbsPosN[0].min) { FocusRelPosNP.s = IPS_ALERT; IDSetNumber(&FocusRelPosNP, nullptr); DEBUGFDEVICE(dev, Logger::DBG_ERROR, "Requested position out of bound. Focus minimum position is %g", FocusAbsPosN[0].min); return false; } } else { if (FocusAbsPosN[0].value + newPos > FocusAbsPosN[0].max) { FocusRelPosNP.s = IPS_ALERT; IDSetNumber(&FocusRelPosNP, nullptr); DEBUGFDEVICE(dev, Logger::DBG_ERROR, "Requested position out of bound. Focus maximum position is %g", FocusAbsPosN[0].max); return false; } } } if ((ret = MoveRelFocuser((FocusMotionS[0].s == ISS_ON ? FOCUS_INWARD : FOCUS_OUTWARD), newPos)) == IPS_OK) { FocusRelPosNP.s = FocusAbsPosNP.s = IPS_OK; IUUpdateNumber(&FocusRelPosNP, values, names, n); IDSetNumber(&FocusRelPosNP, "Focuser moved %d steps %s", newPos, FocusMotionS[0].s == ISS_ON ? "inward" : "outward"); IDSetNumber(&FocusAbsPosNP, nullptr); return true; } else if (ret == IPS_BUSY) { IUUpdateNumber(&FocusRelPosNP, values, names, n); FocusRelPosNP.s = FocusAbsPosNP.s = IPS_BUSY; IDSetNumber(&FocusAbsPosNP, "Focuser is moving %d steps %s...", newPos, FocusMotionS[0].s == ISS_ON ? "inward" : "outward"); IDSetNumber(&FocusAbsPosNP, nullptr); return true; } FocusRelPosNP.s = IPS_ALERT; DEBUGDEVICE(dev, Logger::DBG_ERROR, "Focuser failed to move to new requested position."); IDSetNumber(&FocusRelPosNP, nullptr); return false; } return false; }
bool RotatorInterface::ReverseRotator(bool enabled) { INDI_UNUSED(enabled); DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_ERROR, "Rotator does not support reverse."); return false; }
TTYBase::TTY_RESPONSE TTYBase::connect(const char *device, uint32_t bit_rate, uint8_t word_size, uint8_t parity, uint8_t stop_bits) { #ifdef _WIN32 return TTY_PORT_FAILURE; #else int t_fd = -1; int bps; struct termios tty_setting; if ((t_fd = open(device, O_RDWR | O_NOCTTY)) == -1) { m_PortFD = -1; return TTY_PORT_FAILURE; } // Get the current options and save them so we can restore the default settings later. if (tcgetattr(t_fd, &tty_setting) == -1) { DEBUGDEVICE(m_DriverName, m_DebugChannel, "connect: failed getting tty attributes."); return TTY_PORT_FAILURE; } /* Control Modes Set bps rate */ switch (bit_rate) { case 0: bps = B0; break; case 50: bps = B50; break; case 75: bps = B75; break; case 110: bps = B110; break; case 134: bps = B134; break; case 150: bps = B150; break; case 200: bps = B200; break; case 300: bps = B300; break; case 600: bps = B600; break; case 1200: bps = B1200; break; case 1800: bps = B1800; break; case 2400: bps = B2400; break; case 4800: bps = B4800; break; case 9600: bps = B9600; break; case 19200: bps = B19200; break; case 38400: bps = B38400; break; case 57600: bps = B57600; break; case 115200: bps = B115200; break; case 230400: bps = B230400; break; default: DEBUGFDEVICE(m_DriverName, m_DebugChannel, "connect: %d is not a valid bit rate.", bit_rate); return TTY_PARAM_ERROR; } if ((cfsetispeed(&tty_setting, bps) < 0) || (cfsetospeed(&tty_setting, bps) < 0)) { perror("connect: failed setting bit rate."); return TTY_PORT_FAILURE; } /* Control Modes set no flow control word size, parity and stop bits. Also don't hangup automatically and ignore modem status. Finally enable receiving characters. */ tty_setting.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | HUPCL | CRTSCTS); tty_setting.c_cflag |= (CLOCAL | CREAD); /* word size */ switch (word_size) { case 5: tty_setting.c_cflag |= CS5; break; case 6: tty_setting.c_cflag |= CS6; break; case 7: tty_setting.c_cflag |= CS7; break; case 8: tty_setting.c_cflag |= CS8; break; default: DEBUGFDEVICE(m_DriverName, m_DebugChannel, "connect: %d is not a valid data bit count.", word_size); return TTY_PARAM_ERROR; } /* parity */ switch (parity) { case PARITY_NONE: break; case PARITY_EVEN: tty_setting.c_cflag |= PARENB; break; case PARITY_ODD: tty_setting.c_cflag |= PARENB | PARODD; break; default: DEBUGFDEVICE(m_DriverName, m_DebugChannel, "connect: %d is not a valid parity selection value.", parity); return TTY_PARAM_ERROR; } /* stop_bits */ switch (stop_bits) { case 1: break; case 2: tty_setting.c_cflag |= CSTOPB; break; default: DEBUGFDEVICE(m_DriverName, m_DebugChannel, "connect: %d is not a valid stop bit count.", stop_bits); return TTY_PARAM_ERROR; } /* Control Modes complete */ /* Ignore bytes with parity errors and make terminal raw and dumb.*/ tty_setting.c_iflag &= ~(PARMRK | ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON | IXANY); tty_setting.c_iflag |= INPCK | IGNPAR | IGNBRK; /* Raw output.*/ tty_setting.c_oflag &= ~(OPOST | ONLCR); /* Local Modes Don't echo characters. Don't generate signals. Don't process any characters.*/ tty_setting.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IEXTEN | NOFLSH | TOSTOP); tty_setting.c_lflag |= NOFLSH; /* blocking read until 1 char arrives */ tty_setting.c_cc[VMIN] = 1; tty_setting.c_cc[VTIME] = 0; /* now clear input and output buffers and activate the new terminal settings */ tcflush(t_fd, TCIOFLUSH); if (tcsetattr(t_fd, TCSANOW, &tty_setting)) { DEBUGDEVICE(m_DriverName, m_DebugChannel, "connect: failed setting attributes on serial port."); close(t_fd); return TTY_PORT_FAILURE; } m_PortFD = t_fd; /* return success */ return TTY_OK; #endif }