/* Reserve space in the buffer for a file. filename: name of the file to open offset: offset at which to start buffering the file, useful when the first (offset-1) bytes of the file aren't needed. type: one of the data types supported (audio, image, cuesheet, others user_data: user data passed possibly passed in subcalls specific to a data_type (only used for image (albumart) buffering so far ) return value: <0 if the file cannot be opened, or one file already queued to be opened, otherwise the handle for the file in the buffer */ int bufopen(const char *file, size_t offset, enum data_type type, void *user_data) { #ifndef HAVE_ALBUMART /* currently only used for aa loading */ (void)user_data; #endif if (type == TYPE_ID3) { /* ID3 case: allocate space, init the handle and return. */ struct memory_handle *h = add_handle(sizeof(struct mp3entry), false, true); if (!h) return ERR_BUFFER_FULL; h->fd = -1; h->filesize = sizeof(struct mp3entry); h->filerem = sizeof(struct mp3entry); h->offset = 0; h->data = buf_widx; h->ridx = buf_widx; h->widx = buf_widx; h->available = 0; h->type = type; strlcpy(h->path, file, MAX_PATH); buf_widx += sizeof(struct mp3entry); /* safe because the handle can't wrap */ /* Inform the buffering thread that we added a handle */ LOGFQUEUE("buffering > Q_HANDLE_ADDED %d", h->id); queue_post(&buffering_queue, Q_HANDLE_ADDED, h->id); return h->id; } /* Other cases: there is a little more work. */ int fd = open(file, O_RDONLY); if (fd < 0) return ERR_FILE_ERROR; size_t size = filesize(fd); bool can_wrap = type==TYPE_PACKET_AUDIO || type==TYPE_CODEC; size_t adjusted_offset = offset; if (adjusted_offset > size) adjusted_offset = 0; /* Reserve extra space because alignment can move data forward */ size_t padded_size = STORAGE_PAD(size-adjusted_offset); struct memory_handle *h = add_handle(padded_size, can_wrap, false); if (!h) { DEBUGF("%s(): failed to add handle\n", __func__); close(fd); return ERR_BUFFER_FULL; } strlcpy(h->path, file, MAX_PATH); h->offset = adjusted_offset; /* Don't bother to storage align bitmaps because they are not * loaded directly into the buffer. */ if (type != TYPE_BITMAP) { size_t alignment_pad; /* Remember where data area starts, for use by reset_handle */ h->start = buf_widx; /* Align to desired storage alignment */ alignment_pad = STORAGE_OVERLAP(adjusted_offset - (size_t)(&buffer[buf_widx])); buf_widx = ringbuf_add(buf_widx, alignment_pad); } h->ridx = buf_widx; h->widx = buf_widx; h->data = buf_widx; h->available = 0; h->filerem = 0; h->type = type; #ifdef HAVE_ALBUMART if (type == TYPE_BITMAP) { /* Bitmap file: we load the data instead of the file */ int rc; mutex_lock(&llist_mod_mutex); /* Lock because load_bitmap yields */ rc = load_image(fd, file, (struct dim*)user_data); mutex_unlock(&llist_mod_mutex); if (rc <= 0) { rm_handle(h); close(fd); return ERR_FILE_ERROR; } h->filerem = 0; h->filesize = rc; h->available = rc; h->widx = buf_widx + rc; /* safe because the data doesn't wrap */ buf_widx += rc; /* safe too */ } else #endif { h->filerem = size - adjusted_offset; h->filesize = size; h->available = 0; h->widx = buf_widx; } if (type == TYPE_CUESHEET) { h->fd = fd; /* Immediately start buffering those */ LOGFQUEUE("buffering >| Q_BUFFER_HANDLE %d", h->id); queue_send(&buffering_queue, Q_BUFFER_HANDLE, h->id); } else { /* Other types will get buffered in the course of normal operations */ h->fd = -1; close(fd); /* Inform the buffering thread that we added a handle */ LOGFQUEUE("buffering > Q_HANDLE_ADDED %d", h->id); queue_post(&buffering_queue, Q_HANDLE_ADDED, h->id); } logf("bufopen: new hdl %d", h->id); return h->id; }
bool QHYCCD::StartExposure(float duration) { int ret = QHYCCD_ERROR; if (streamer->isBusy()) { DEBUG(INDI::Logger::DBG_ERROR, "Cannot take exposure while streaming/recording is active."); return false; } //AbortPrimaryFrame = false; if (duration < MINIMUM_CCD_EXPOSURE) { DEBUGF(INDI::Logger::DBG_WARNING, "Exposure shorter than minimum duration %g s requested. Setting exposure time to %g s.", duration, MINIMUM_CCD_EXPOSURE); duration = MINIMUM_CCD_EXPOSURE; } imageFrameType = PrimaryCCD.getFrameType(); if (imageFrameType == CCDChip::BIAS_FRAME) { duration = MINIMUM_CCD_EXPOSURE; DEBUGF(INDI::Logger::DBG_SESSION, "Bias Frame (s) : %g", duration); } else if(imageFrameType == CCDChip::DARK_FRAME) { ControlQHYCCDShutter(camhandle,MACHANICALSHUTTER_CLOSE); } else { ControlQHYCCDShutter(camhandle,MACHANICALSHUTTER_FREE); } DEBUGF(INDI::Logger::DBG_DEBUG, "Current exposure time is %f us",duration * 1000 * 1000); ExposureRequest = duration; PrimaryCCD.setExposureDuration(duration); if (sim) ret = QHYCCD_SUCCESS; else ret = SetQHYCCDParam(camhandle,CONTROL_EXPOSURE,ExposureRequest * 1000 * 1000); if(ret != QHYCCD_SUCCESS) { DEBUGF(INDI::Logger::DBG_ERROR, "Set expose time failed (%d).", ret); return false; } // lzr: we need to call the following apis every single exposure,the usleep(200000) is important if (sim) ret = QHYCCD_SUCCESS; else ret = SetQHYCCDBinMode(camhandle,camxbin,camybin); if(ret != QHYCCD_SUCCESS) { DEBUGF(INDI::Logger::DBG_SESSION, "Set QHYCCD Bin mode failed (%d)", ret); return false; } DEBUGF(INDI::Logger::DBG_DEBUG, "SetQHYCCDBinMode %dx%d", camxbin, camybin); if (sim) ret = QHYCCD_SUCCESS; else ret = SetQHYCCDResolution(camhandle,camroix,camroiy,camroiwidth,camroiheight); if(ret != QHYCCD_SUCCESS) { DEBUGF(INDI::Logger::DBG_SESSION, "Set QHYCCD ROI resolution failed (%d)", ret); return false; } DEBUGF(INDI::Logger::DBG_DEBUG, "SetQHYCCDResolution camroix %d camroiy %d camroiwidth %d camroiheight %d", camroix,camroiy,camroiwidth,camroiheight); // Jasem: Removed QHY 300ms delay that was added without specifying the reason. It seems any delay less than 100ms results in QHY Frame error. Again no reason. This renders // exposures less than 100ms useless, but there is nothing I can do about that. usleep(100000); if (sim) ret = QHYCCD_SUCCESS; else ret = ExpQHYCCDSingleFrame(camhandle); if(ret != QHYCCD_SUCCESS) { DEBUGF(INDI::Logger::DBG_SESSION, "Begin QHYCCD expose failed (%d)", ret); return false; } gettimeofday(&ExpStart, NULL); DEBUGF(INDI::Logger::DBG_DEBUG, "Taking a %g seconds frame...", ExposureRequest); InExposure = true; // if (ExposureRequest*1000 < POLLMS) // SetTimer(ExposureRequest*1000); // else SetTimer(POLLMS); return true; }
int search_files(const char *path, const char *expr, TranslationFlags flags, const SearchOptions *opts, Callback found_file, Callback err_message, void *user_data) { int ret = -1; assert(path != NULL); assert(expr != NULL); assert(opts != NULL); int outfds[2]; int errfds[2]; memset(outfds, 0, sizeof(outfds)); memset(errfds, 0, sizeof(errfds)); TRACE("search", "Creating pipes."); if(pipe2(outfds, 0) >= 0 && pipe2(errfds, 0) >= 0) { char **argv = NULL; size_t argc = 0; ParserResult *result; TRACE("search", "Pipes created successfully, translating expression."); result = _search_translate_expr(path, expr, flags, opts, &argc, &argv); assert(result != NULL); if(result->success) { DEBUG("search", "Expression parsed successfully, forking and running `find'."); pid_t pid = fork(); if(pid == -1) { FATALF("search", "`fork' failed with result %ld.", pid); perror("fork()"); } else if(pid == 0) { if(_search_close_and_dup_child_fds(outfds, errfds)) { _search_child_process(argv); } else { ERROR("search", "Couldn't initialize child's file descriptors."); } } else { if(_search_close_parent_fds(outfds, errfds)) { ParentCtx ctx; memset(&ctx, 0, sizeof(ParentCtx)); ctx.child_pid = pid; ctx.outfd = outfds[0]; ctx.errfd = errfds[0]; ctx.found_file = found_file; ctx.err_message = err_message; ctx.user_data = user_data; _search_filter_args_init(&ctx.filter_args, result); ret = _search_parent_process(&ctx); _search_filter_args_free(&ctx.filter_args); } else { WARNING("search", "Couldn't close parent's file descriptors."); } } } else if(result->err) { TRACEF("search", "Couldn't parse expression: %s", result->err); } else { TRACE("search", "Couldn't parse expression, no error message set."); } DEBUGF("search", "Search finished with result %d.", ret); if(argv) { for(size_t i = 0; i < argc; i++) { free(argv[i]); } free(argv); } parser_result_free(result); _search_close_all_fds(outfds, errfds); } else { perror("pipe2()"); } return ret; }
bool QHYCCD::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { // first check if it's for our device //IDLog("INDI::CCD::ISNewNumber %s\n",name); if(strcmp(dev,getDeviceName())==0) { if (strcmp(name,FilterSlotNP.name)==0) { processFilterSlot(getDeviceName(), values, names); return true; } if(strcmp(name,GainNP.name) == 0) { IUUpdateNumber(&GainNP, values, names, n); SetQHYCCDParam(camhandle,CONTROL_GAIN,GainN[0].value); DEBUGF(INDI::Logger::DBG_SESSION, "Current %s value %f",GainNP.name,GainN[0].value); GainNP.s = IPS_OK; IDSetNumber(&GainNP, NULL); //saveConfig(); return true; } if(strcmp(name,OffsetNP.name) == 0) { IUUpdateNumber(&OffsetNP, values, names, n); SetQHYCCDParam(camhandle,CONTROL_OFFSET,OffsetN[0].value); DEBUGF(INDI::Logger::DBG_SESSION, "Current %s value %f",OffsetNP.name,OffsetN[0].value); OffsetNP.s = IPS_OK; IDSetNumber(&OffsetNP, NULL); saveConfig(); return true; } if(strcmp(name,SpeedNP.name) == 0) { IUUpdateNumber(&SpeedNP, values, names, n); SetQHYCCDParam(camhandle,CONTROL_SPEED,SpeedN[0].value); DEBUGF(INDI::Logger::DBG_SESSION, "Current %s value %f",SpeedNP.name,SpeedN[0].value); SpeedNP.s = IPS_OK; IDSetNumber(&SpeedNP, NULL); saveConfig(); return true; } if(strcmp(name,USBTrafficNP.name) == 0) { IUUpdateNumber(&USBTrafficNP, values, names, n); SetQHYCCDParam(camhandle,CONTROL_USBTRAFFIC,USBTrafficN[0].value); DEBUGF(INDI::Logger::DBG_SESSION, "Current %s value %f",USBTrafficNP.name,USBTrafficN[0].value); USBTrafficNP.s = IPS_OK; IDSetNumber(&USBTrafficNP, NULL); saveConfig(); return true; } } // if we didn't process it, continue up the chain, let somebody else // give it a shot return INDI::CCD::ISNewNumber(dev,name,values,names,n); }
bool QHYCCD::updateProperties() { INDI::CCD::updateProperties(); double min,max,step; if (isConnected()) { if (HasCooler()) { defineSwitch(&CoolerSP); defineNumber(&CoolerNP); temperatureID = IEAddTimer(POLLMS, QHYCCD::updateTemperatureHelper, this); } if(HasUSBSpeed) { if (sim) { SpeedN[0].min = 1; SpeedN[0].max = 5; SpeedN[0].step = 1; SpeedN[0].value = 1; } else { int ret = GetQHYCCDParamMinMaxStep(camhandle,CONTROL_SPEED,&min,&max,&step); if(ret == QHYCCD_SUCCESS) { SpeedN[0].min = min; SpeedN[0].max = max; SpeedN[0].step = step; } SpeedN[0].value = GetQHYCCDParam(camhandle,CONTROL_SPEED); DEBUGF(INDI::Logger::DBG_DEBUG, "USB Speed. Value: %g Min: %g Max: %g Step %g", SpeedN[0].value, SpeedN[0].min, SpeedN[0].max, SpeedN[0].step); } defineNumber(&SpeedNP); } if(HasGain) { if (sim) { GainN[0].min = 0; GainN[0].max = 100; GainN[0].step = 10; GainN[0].value = 50; } else { int ret = GetQHYCCDParamMinMaxStep(camhandle,CONTROL_GAIN,&min,&max,&step); if(ret == QHYCCD_SUCCESS) { GainN[0].min = min; GainN[0].max = max; GainN[0].step = step; } GainN[0].value = GetQHYCCDParam(camhandle,CONTROL_GAIN); DEBUGF(INDI::Logger::DBG_DEBUG, "Gain. Value: %g Min: %g Max: %g Step %g", GainN[0].value, GainN[0].min, GainN[0].max, GainN[0].step); } defineNumber(&GainNP); } if(HasOffset) { if (sim) { OffsetN[0].min = 1; OffsetN[0].max = 10; OffsetN[0].step = 1; OffsetN[0].value = 1; } else { int ret = GetQHYCCDParamMinMaxStep(camhandle,CONTROL_OFFSET,&min,&max,&step); if(ret == QHYCCD_SUCCESS) { OffsetN[0].min = min; OffsetN[0].max = max; OffsetN[0].step = step; } OffsetN[0].value = GetQHYCCDParam(camhandle,CONTROL_OFFSET); DEBUGF(INDI::Logger::DBG_DEBUG, "Offset. Value: %g Min: %g Max: %g Step %g", OffsetN[0].value, OffsetN[0].min, OffsetN[0].max, OffsetN[0].step); } //Define the Offset defineNumber(&OffsetNP); } if(HasFilters) { //Define the Filter Slot and name properties defineNumber(&FilterSlotNP); GetFilterNames(FILTER_TAB); defineText(FilterNameTP); } if (HasUSBTraffic) { if (sim) { USBTrafficN[0].min = 1; USBTrafficN[0].max = 100; USBTrafficN[0].step = 5; USBTrafficN[0].value = 20; } else { int ret = GetQHYCCDParamMinMaxStep(camhandle,CONTROL_USBTRAFFIC,&min,&max,&step); if(ret == QHYCCD_SUCCESS) { USBTrafficN[0].min = min; USBTrafficN[0].max = max; USBTrafficN[0].step = step; } USBTrafficN[0].value = GetQHYCCDParam(camhandle,CONTROL_USBTRAFFIC); DEBUGF(INDI::Logger::DBG_DEBUG, "USB Traffic. Value: %g Min: %g Max: %g Step %g", USBTrafficN[0].value, USBTrafficN[0].min, USBTrafficN[0].max, USBTrafficN[0].step); } defineNumber(&USBTrafficNP); } // Let's get parameters now from CCD setupParams(); //timerID = SetTimer(POLLMS); } else { if (HasCooler()) { deleteProperty(CoolerSP.name); deleteProperty(CoolerNP.name); } if(HasUSBSpeed) { deleteProperty(SpeedNP.name); } if(HasGain) { deleteProperty(GainNP.name); } if(HasOffset) { deleteProperty(OffsetNP.name); } if(HasFilters) { deleteProperty(FilterSlotNP.name); deleteProperty(FilterNameTP->name); } if (HasUSBTraffic) deleteProperty(USBTrafficNP.name); RemoveTimer(timerID); } return true; }
static void set_pinfo ( lame_global_flags *gfp, gr_info * const cod_info, const III_psy_ratio * const ratio, const III_scalefac_t * const scalefac, const int gr, const int ch ) { lame_internal_flags *gfc=gfp->internal_flags; int sfb; int j,i,l,start,end,bw; FLOAT8 en0,en1; FLOAT ifqstep = ( cod_info->scalefac_scale == 0 ) ? .5 : 1.0; III_psy_xmin l3_xmin; calc_noise_result noise; III_psy_xmin xfsf; calc_xmin (gfp, ratio, cod_info, &l3_xmin); calc_noise (gfc, cod_info->l3_enc, cod_info, &l3_xmin, scalefac, &xfsf, &noise); if (cod_info->block_type == SHORT_TYPE) { for (j=0, sfb = 0; sfb < SBMAX_s; sfb++ ) { start = gfc->scalefac_band.s[ sfb ]; end = gfc->scalefac_band.s[ sfb + 1 ]; bw = end - start; for ( i = 0; i < 3; i++ ) { for ( en0 = 0.0, l = start; l < end; l++ ) { en0 += cod_info->xr[j] * cod_info->xr[j]; ++j; } en0=Max(en0/bw,1e-20); #if 0 { double tot1,tot2; if (sfb<SBMAX_s-1) { if (sfb==0) { tot1=0; tot2=0; } tot1 += en0; tot2 += ratio->en.s[sfb][i]; DEBUGF("%i %i sfb=%i mdct=%f fft=%f fft-mdct=%f db \n", gr,ch,sfb, 10*log10(Max(1e-25,ratio->en.s[sfb][i])), 10*log10(Max(1e-25,en0)), 10*log10((Max(1e-25,en0)/Max(1e-25,ratio->en.s[sfb][i])))); if (sfb==SBMAX_s-2) { DEBUGF("%i %i toti %f %f ratio=%f db \n",gr,ch, 10*log10(Max(1e-25,tot2)), 10*log(Max(1e-25,tot1)), 10*log10(Max(1e-25,tot1)/(Max(1e-25,tot2)))); } } /* masking: multiplied by en0/fft_energy average seems to be about -135db. */ } #endif /* convert to MDCT units */ en1=1e15; /* scaling so it shows up on FFT plot */ gfc->pinfo->xfsf_s[gr][ch][3*sfb+i] = en1*xfsf.s[sfb][i]*l3_xmin.s[sfb][i]/bw; gfc->pinfo->en_s[gr][ch][3*sfb+i] = en1*en0; if (ratio->en.s[sfb][i]>0) en0 = en0/ratio->en.s[sfb][i]; else en0=0; if (gfp->ATHonly || gfp->ATHshort) en0=0; gfc->pinfo->thr_s[gr][ch][3*sfb+i] = en1*Max(en0*ratio->thm.s[sfb][i],gfc->ATH->s[sfb]); /* there is no scalefactor bands >= SBPSY_s */ if (sfb < SBPSY_s) { gfc->pinfo->LAMEsfb_s[gr][ch][3*sfb+i]= -ifqstep*scalefac->s[sfb][i]; } else { gfc->pinfo->LAMEsfb_s[gr][ch][3*sfb+i]=0; } gfc->pinfo->LAMEsfb_s[gr][ch][3*sfb+i] -= 2*cod_info->subblock_gain[i]; } } } else { for ( sfb = 0; sfb < SBMAX_l; sfb++ ) { start = gfc->scalefac_band.l[ sfb ]; end = gfc->scalefac_band.l[ sfb+1 ]; bw = end - start; for ( en0 = 0.0, l = start; l < end; l++ ) en0 += cod_info->xr[l] * cod_info->xr[l]; en0/=bw; /* DEBUGF("diff = %f \n",10*log10(Max(ratio[gr][ch].en.l[sfb],1e-20)) -(10*log10(en0)+150)); */ #if 0 { double tot1,tot2; if (sfb==0) { tot1=0; tot2=0; } tot1 += en0; tot2 += ratio->en.l[sfb]; DEBUGF("%i %i sfb=%i mdct=%f fft=%f fft-mdct=%f db \n", gr,ch,sfb, 10*log10(Max(1e-25,ratio->en.l[sfb])), 10*log10(Max(1e-25,en0)), 10*log10((Max(1e-25,en0)/Max(1e-25,ratio->en.l[sfb])))); if (sfb==SBMAX_l-1) { DEBUGF("%i %i toti %f %f ratio=%f db \n", gr,ch, 10*log10(Max(1e-25,tot2)), 10*log(Max(1e-25,tot1)), 10*log10(Max(1e-25,tot1)/(Max(1e-25,tot2)))); } /* masking: multiplied by en0/fft_energy average seems to be about -147db. */ } #endif /* convert to MDCT units */ en1=1e15; /* scaling so it shows up on FFT plot */ gfc->pinfo->xfsf[gr][ch][sfb] = en1*xfsf.l[sfb]*l3_xmin.l[sfb]/bw; gfc->pinfo->en[gr][ch][sfb] = en1*en0; if (ratio->en.l[sfb]>0) en0 = en0/ratio->en.l[sfb]; else en0=0; if (gfp->ATHonly) en0=0; gfc->pinfo->thr[gr][ch][sfb] = en1*Max(en0*ratio->thm.l[sfb],gfc->ATH->l[sfb]); /* there is no scalefactor bands >= SBPSY_l */ if (sfb<SBPSY_l) { if (scalefac->l[sfb]<0) /* scfsi! */ gfc->pinfo->LAMEsfb[gr][ch][sfb] = gfc->pinfo->LAMEsfb[0][ch][sfb]; else gfc->pinfo->LAMEsfb[gr][ch][sfb] = -ifqstep*scalefac->l[sfb]; }else{ gfc->pinfo->LAMEsfb[gr][ch][sfb] = 0; } if (cod_info->preflag && sfb>=11) gfc->pinfo->LAMEsfb[gr][ch][sfb] -= ifqstep*pretab[sfb]; } /* for sfb */ } /* block type long */ gfc->pinfo->LAMEqss [gr][ch] = cod_info->global_gain; gfc->pinfo->LAMEmainbits[gr][ch] = cod_info->part2_3_length; gfc->pinfo->LAMEsfbits [gr][ch] = cod_info->part2_length; gfc->pinfo->over [gr][ch] = noise.over_count; gfc->pinfo->max_noise [gr][ch] = noise.max_noise; gfc->pinfo->over_noise[gr][ch] = noise.over_noise; gfc->pinfo->tot_noise [gr][ch] = noise.tot_noise; }
void FishCampCCD::TimerHit() { int timerHitID = -1, state = -1, rc = -1; long timeleft; double ccdTemp; if (isConnected() == false) return; // No need to reset timer if we are not connected anymore if (InExposure) { timeleft = CalcTimeLeft(); if (timeleft < 1.0) { if (timeleft > 0.25) { // a quarter of a second or more // just set a tighter timer timerHitID = SetTimer(250); } else { if (timeleft > 0.07) { // use an even tighter timer timerHitID = SetTimer(50); } else { // it's real close now, so spin on it while (!sim && timeleft > 0) { state = fcUsb_cmd_getState(cameraNum); if (state == 0) timeleft = 0; int slv; slv = 100000 * timeleft; usleep(slv); } /* We're done exposing */ DEBUG(INDI::Logger::DBG_DEBUG, "Exposure done, downloading image..."); PrimaryCCD.setExposureLeft(0); InExposure = false; /* grab and save image */ grabImage(); } } } else { DEBUGF(INDI::Logger::DBG_DEBUG, "Image not yet ready. With time left %ld\n", timeleft); } PrimaryCCD.setExposureLeft(timeleft); } switch (TemperatureNP.s) { case IPS_IDLE: case IPS_OK: rc = fcUsb_cmd_getTemperature(cameraNum); DEBUGF(INDI::Logger::DBG_DEBUG, "fcUsb_cmd_getTemperature returns %d", rc); ccdTemp = rc / 100.0; DEBUGF(INDI::Logger::DBG_DEBUG, "Temperature %g", ccdTemp); if (fabs(TemperatureN[0].value - ccdTemp) >= TEMP_THRESHOLD) { TemperatureN[0].value = ccdTemp; IDSetNumber(&TemperatureNP, NULL); } break; case IPS_BUSY: if (sim) { TemperatureN[0].value = TemperatureRequest; } else { rc = fcUsb_cmd_getTemperature(cameraNum); DEBUGF(INDI::Logger::DBG_DEBUG, "fcUsb_cmd_getTemperature returns %d", rc); TemperatureN[0].value = rc / 100.0; } // If we're within threshold, let's make it BUSY ---> OK if (fabs(TemperatureRequest - TemperatureN[0].value) <= TEMP_THRESHOLD) TemperatureNP.s = IPS_OK; IDSetNumber(&TemperatureNP, NULL); break; case IPS_ALERT: break; } switch (CoolerNP.s) { case IPS_OK: CoolerN[0].value = fcUsb_cmd_getTECPowerLevel(cameraNum); IDSetNumber(&CoolerNP, NULL); DEBUGF(INDI::Logger::DBG_DEBUG, "Cooler power level %g %", CoolerN[0].value); break; default: break; } if (timerHitID == -1) SetTimer(POLLMS); return; }
bool QSICCD::setupParams() { string name, model; double temperature; double pixel_size_x, pixel_size_y; long sub_frame_x, sub_frame_y; try { QSICam.get_Name(name); QSICam.get_ModelNumber(model); QSICam.get_PixelSizeX(&pixel_size_x); QSICam.get_PixelSizeY(&pixel_size_y); QSICam.get_NumX(&sub_frame_x); QSICam.get_NumY(&sub_frame_y); QSICam.get_CCDTemperature(&temperature); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_ERROR, "Setup Params failed. %s.", err.what()); return false; } DEBUGF(INDI::Logger::DBG_SESSION, "The CCD Temperature is %f.", temperature); TemperatureN[0].value = temperature; /* CCD chip temperatre (degrees C) */ IDSetNumber(&TemperatureNP, nullptr); SetCCDParams(sub_frame_x, sub_frame_y, 16, pixel_size_x, pixel_size_y); imageWidth = PrimaryCCD.getSubW(); imageHeight = PrimaryCCD.getSubH(); int nbuf; nbuf = PrimaryCCD.getXRes() * PrimaryCCD.getYRes() * PrimaryCCD.getBPP() / 8; // this is pixel count nbuf += 512; // leave a little extra at the end PrimaryCCD.setFrameBufferSize(nbuf); try { QSICam.get_Name(name); } catch (std::runtime_error &err) { DEBUGF(INDI::Logger::DBG_ERROR, "get_Name() failed. %s.", err.what()); return false; } DEBUGF(INDI::Logger::DBG_SESSION, "%s", name.c_str()); try { QSICam.get_FilterCount(filterCount); DEBUGF(INDI::Logger::DBG_SESSION, "The filter count is %d", filterCount); FilterSlotN[0].min = 1; FilterSlotN[0].max = filterCount; FilterSlotNP.s = IPS_OK; } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_SESSION, "get_FilterCount() failed. %s.", err.what()); return false; } // Only generate filter names if there are none initially //if (FilterNameT == nullptr) //GetFilterNames(FILTER_TAB); double minDuration = 0; try { QSICam.get_MinExposureTime(&minDuration); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_ERROR, "get_MinExposureTime() failed. %s.", err.what()); return false; } PrimaryCCD.setMinMaxStep("CCD_EXPOSURE", "CCD_EXPOSURE_VALUE", minDuration, 3600, 1, true); bool coolerOn = false; try { QSICam.get_CoolerOn(&coolerOn); } catch (std::runtime_error err) { CoolerSP.s = IPS_IDLE; CoolerS[0].s = ISS_OFF; CoolerS[1].s = ISS_ON; DEBUGF(INDI::Logger::DBG_ERROR, "Error: CoolerOn() failed. %s.", err.what()); IDSetSwitch(&CoolerSP, nullptr); return false; } CoolerS[0].s = coolerOn ? ISS_ON : ISS_OFF; CoolerS[1].s = coolerOn ? ISS_OFF : ISS_ON; CoolerSP.s = IPS_OK; IDSetSwitch(&CoolerSP, nullptr); QSICamera::CameraGain cGain = QSICamera::CameraGainAuto; canSetGain = false; QSICam.get_CanSetGain(&canSetGain); if (canSetGain) { try { QSICam.get_CameraGain(&cGain); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support gain. %s.", err.what()); canSetGain = false; } if (canSetGain) { IUResetSwitch(&GainSP); GainS[cGain].s = ISS_ON; defineSwitch(&GainSP); } } QSICamera::AntiBloom cAB = QSICamera::AntiBloomNormal; canSetAB = true; try { QSICam.get_AntiBlooming(&cAB); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support AntiBlooming control. %s.", err.what()); canSetAB = false; } if (canSetAB) { DEBUGF(INDI::Logger::DBG_DEBUG, "Antiblooming setting is. %d.", cAB); // cAB returns 3 on some a sample QSI 660 WSG if(cAB == 0 || cAB == 1 ) { IUResetSwitch(&ABSP); ABS[cAB].s = ISS_ON; defineSwitch(&ABSP); } } QSICamera::FanMode fMode = QSICamera::fanOff; canControlFan = true; try { QSICam.get_FanMode(fMode); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support fan control. %s.", err.what()); canControlFan = false; } if (canControlFan) { IUResetSwitch(&FanSP); FanS[fMode].s = ISS_ON; defineSwitch(&FanSP); } canChangeReadoutSpeed = true; QSICamera::ReadoutSpeed cReadoutSpeed; try { QSICam.get_ReadoutSpeed(cReadoutSpeed); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support changing readout speed. %s.", err.what()); canChangeReadoutSpeed = false; } if (canChangeReadoutSpeed) { // get_ReadoutSpeed succeeds even if the camera does not support that, so the only way to make sure is to set it try { QSICam.put_ReadoutSpeed(cReadoutSpeed); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support changing readout speed. %s.", err.what()); canChangeReadoutSpeed = false; } if (canChangeReadoutSpeed) { IUResetSwitch(&ReadOutSP); ReadOutS[cReadoutSpeed].s = ISS_ON; defineSwitch(&ReadOutSP); } } // Can flush canFlush = false; try { QSICam.put_PreExposureFlush(QSICamera::FlushNormal); canFlush = true; } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not pre-exposure flushing %s.", err.what()); canFlush = false; } return true; }
bool QSICCD::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) { if (strcmp(dev, getDeviceName()) == 0) { /* Readout Speed */ if (!strcmp(name, ReadOutSP.name)) { if (IUUpdateSwitch(&ReadOutSP, states, names, n) < 0) return false; if (ReadOutS[0].s == ISS_ON) { try { QSICam.put_ReadoutSpeed(QSICamera::HighImageQuality); } catch (std::runtime_error err) { IUResetSwitch(&ReadOutSP); ReadOutSP.s = IPS_ALERT; DEBUGF(INDI::Logger::DBG_ERROR, "put_ReadoutSpeed() failed. %s.", err.what()); IDSetSwitch(&ReadOutSP, nullptr); return false; } } else { try { QSICam.put_ReadoutSpeed(QSICamera::FastReadout); } catch (std::runtime_error err) { IUResetSwitch(&ReadOutSP); ReadOutSP.s = IPS_ALERT; DEBUGF(INDI::Logger::DBG_ERROR, "put_ReadoutSpeed() failed. %s.", err.what()); IDSetSwitch(&ReadOutSP, nullptr); return false; } ReadOutSP.s = IPS_OK; IDSetSwitch(&ReadOutSP, nullptr); } ReadOutSP.s = IPS_OK; IDSetSwitch(&ReadOutSP, nullptr); return true; } /* Cooler */ if (!strcmp(name, CoolerSP.name)) { if (IUUpdateSwitch(&CoolerSP, states, names, n) < 0) return false; if (CoolerS[0].s == ISS_ON) activateCooler(true); else activateCooler(false); return true; } /* Shutter */ if (!strcmp(name, ShutterSP.name)) { if (IUUpdateSwitch(&ShutterSP, states, names, n) < 0) return false; shutterControl(); return true; } if (!strcmp(name, GainSP.name)) { int prevGain = IUFindOnSwitchIndex(&GainSP); IUUpdateSwitch(&GainSP, states, names, n); int targetGain = IUFindOnSwitchIndex(&GainSP); if (prevGain == targetGain) { GainSP.s = IPS_OK; IDSetSwitch(&GainSP, nullptr); return true; } try { QSICam.put_CameraGain(((QSICamera::CameraGain)targetGain)); } catch (std::runtime_error err) { IUResetSwitch(&GainSP); GainS[prevGain].s = ISS_ON; GainSP.s = IPS_ALERT; DEBUGF(INDI::Logger::DBG_ERROR, "put_CameraGain failed. %s.", err.what()); IDSetSwitch(&GainSP, nullptr); return false; } GainSP.s = IPS_OK; IDSetSwitch(&GainSP, nullptr); return true; } if (!strcmp(name, FanSP.name)) { int prevFan = IUFindOnSwitchIndex(&FanSP); IUUpdateSwitch(&FanSP, states, names, n); int targetFan = IUFindOnSwitchIndex(&FanSP); if (prevFan == targetFan) { FanSP.s = IPS_OK; IDSetSwitch(&FanSP, nullptr); return true; } try { QSICam.put_FanMode(((QSICamera::FanMode)targetFan)); } catch (std::runtime_error err) { IUResetSwitch(&FanSP); FanS[prevFan].s = ISS_ON; FanSP.s = IPS_ALERT; DEBUGF(INDI::Logger::DBG_ERROR, "put_FanMode failed. %s.", err.what()); IDSetSwitch(&FanSP, nullptr); return false; } FanSP.s = IPS_OK; IDSetSwitch(&FanSP, nullptr); return true; } if (!strcmp(name, ABSP.name)) { int prevAB = IUFindOnSwitchIndex(&ABSP); IUUpdateSwitch(&ABSP, states, names, n); int targetAB = IUFindOnSwitchIndex(&ABSP); if (prevAB == targetAB) { ABSP.s = IPS_OK; IDSetSwitch(&ABSP, nullptr); return true; } try { QSICam.put_AntiBlooming(((QSICamera::AntiBloom)targetAB)); } catch (std::runtime_error err) { IUResetSwitch(&ABSP); ABS[prevAB].s = ISS_ON; ABSP.s = IPS_ALERT; DEBUGF(INDI::Logger::DBG_ERROR, "put_AntiBlooming failed. %s.", err.what()); IDSetSwitch(&ABSP, nullptr); return false; } ABSP.s = IPS_OK; IDSetSwitch(&ABSP, nullptr); return true; } /* Filter Wheel */ if (!strcmp(name, FilterSP.name)) { if (IUUpdateSwitch(&FilterSP, states, names, n) < 0) return false; turnWheel(); return true; } } // Nobody has claimed this, so, ignore it return INDI::CCD::ISNewSwitch(dev, name, states, names, n); }
void QSICCD::TimerHit() { long timeleft = 0; double ccdTemp = 0; double coolerPower = 0; if (isConnected() == false) return; // No need to reset timer if we are not connected anymore if (InExposure) { bool imageReady; timeleft = CalcTimeLeft(ExpStart, ExposureRequest); if (timeleft < 1) { QSICam.get_ImageReady(&imageReady); while (!imageReady) { usleep(100); QSICam.get_ImageReady(&imageReady); } /* We're done exposing */ DEBUG(INDI::Logger::DBG_SESSION, "Exposure done, downloading image..."); PrimaryCCD.setExposureLeft(0); InExposure = false; /* grab and save image */ grabImage(); } else { DEBUGF(INDI::Logger::DBG_DEBUG, "Image not ready, time left %ld\n", timeleft); PrimaryCCD.setExposureLeft(timeleft); } } switch (TemperatureNP.s) { case IPS_IDLE: case IPS_OK: try { QSICam.get_CCDTemperature(&ccdTemp); } catch (std::runtime_error err) { TemperatureNP.s = IPS_IDLE; DEBUGF(INDI::Logger::DBG_ERROR, "get_CCDTemperature() failed. %s.", err.what()); IDSetNumber(&TemperatureNP, nullptr); return; } if (fabs(TemperatureN[0].value - ccdTemp) >= TEMP_THRESHOLD) { TemperatureN[0].value = ccdTemp; IDSetNumber(&TemperatureNP, nullptr); } break; case IPS_BUSY: try { QSICam.get_CCDTemperature(&TemperatureN[0].value); } catch (std::runtime_error err) { TemperatureNP.s = IPS_ALERT; DEBUGF(INDI::Logger::DBG_ERROR, "get_CCDTemperature() failed. %s.", err.what()); IDSetNumber(&TemperatureNP, nullptr); return; } if (fabs(TemperatureN[0].value - targetTemperature) <= TEMP_THRESHOLD) TemperatureNP.s = IPS_OK; IDSetNumber(&TemperatureNP, nullptr); break; case IPS_ALERT: break; } switch (CoolerNP.s) { case IPS_IDLE: case IPS_OK: try { QSICam.get_CoolerPower(&coolerPower); } catch (std::runtime_error err) { CoolerNP.s = IPS_IDLE; DEBUGF(INDI::Logger::DBG_ERROR, "get_CoolerPower() failed. %s.", err.what()); IDSetNumber(&CoolerNP, nullptr); return; } if (CoolerN[0].value != coolerPower) { CoolerN[0].value = coolerPower; IDSetNumber(&CoolerNP, nullptr); } if (coolerPower > 0) CoolerNP.s = IPS_BUSY; break; case IPS_BUSY: try { QSICam.get_CoolerPower(&coolerPower); } catch (std::runtime_error err) { CoolerNP.s = IPS_ALERT; DEBUGF(INDI::Logger::DBG_ERROR, "get_CoolerPower() failed. %s.", err.what()); IDSetNumber(&CoolerNP, nullptr); return; } if (coolerPower == 0) CoolerNP.s = IPS_IDLE; CoolerN[0].value = coolerPower; IDSetNumber(&CoolerNP, nullptr); break; case IPS_ALERT: break; } SetTimer(POLLMS); return; }
void QSICCD::turnWheel() { short current_filter = 0; switch (FilterS[0].s) { case ISS_ON: try { current_filter = QueryFilter(); if (current_filter < filterCount) current_filter++; else current_filter = 1; SelectFilter(current_filter); } catch (std::runtime_error err) { FilterSP.s = IPS_IDLE; FilterS[0].s = ISS_OFF; FilterS[1].s = ISS_OFF; DEBUGF(INDI::Logger::DBG_ERROR, "QSICamera::get_FilterPos() failed. %s.", err.what()); return; } FilterSlotN[0].value = current_filter; FilterS[0].s = ISS_OFF; FilterS[1].s = ISS_OFF; FilterSP.s = IPS_OK; DEBUGF(INDI::Logger::DBG_DEBUG, "The current filter is %d", current_filter); IDSetSwitch(&FilterSP, nullptr); break; case ISS_OFF: try { current_filter = QueryFilter(); if (current_filter > 1) current_filter--; else current_filter = filterCount; SelectFilter(current_filter); } catch (std::runtime_error err) { FilterSP.s = IPS_IDLE; FilterS[0].s = ISS_OFF; FilterS[1].s = ISS_OFF; DEBUGF(INDI::Logger::DBG_ERROR, "QSICamera::get_FilterPos() failed. %s.", err.what()); return; } FilterSlotN[0].value = current_filter; FilterS[0].s = ISS_OFF; FilterS[1].s = ISS_OFF; FilterSP.s = IPS_OK; DEBUGF(INDI::Logger::DBG_DEBUG, "The current filter is %d", current_filter); IDSetSwitch(&FilterSP, nullptr); IDSetNumber(&FilterSlotNP, nullptr); break; } }
void QSICCD::shutterControl() { bool hasShutter; try { QSICam.get_HasShutter(&hasShutter); } catch (std::runtime_error err) { ShutterSP.s = IPS_IDLE; ShutterS[0].s = ISS_OFF; ShutterS[1].s = ISS_OFF; DEBUGF(INDI::Logger::DBG_ERROR, "QSICamera::get_HasShutter() failed. %s.", err.what()); return; } if (hasShutter) { switch (ShutterS[0].s) { case ISS_ON: try { QSICam.put_ManualShutterMode(true); QSICam.put_ManualShutterOpen(true); } catch (std::runtime_error err) { ShutterSP.s = IPS_IDLE; ShutterS[0].s = ISS_OFF; ShutterS[1].s = ISS_ON; DEBUGF(INDI::Logger::DBG_ERROR, "Error: ManualShutterOpen() failed. %s.", err.what()); IDSetSwitch(&ShutterSP, nullptr); return; } /* Success! */ ShutterS[0].s = ISS_ON; ShutterS[1].s = ISS_OFF; ShutterSP.s = IPS_OK; DEBUG(INDI::Logger::DBG_SESSION, "Shutter opened manually."); IDSetSwitch(&ShutterSP, nullptr); break; case ISS_OFF: try { QSICam.put_ManualShutterOpen(false); QSICam.put_ManualShutterMode(false); } catch (std::runtime_error err) { ShutterSP.s = IPS_IDLE; ShutterS[0].s = ISS_ON; ShutterS[1].s = ISS_OFF; DEBUGF(INDI::Logger::DBG_ERROR, "Error: ManualShutterOpen() failed. %s.", err.what()); IDSetSwitch(&ShutterSP, nullptr); return; } /* Success! */ ShutterS[0].s = ISS_OFF; ShutterS[1].s = ISS_ON; ShutterSP.s = IPS_IDLE; DEBUG(INDI::Logger::DBG_SESSION, "Shutter closed manually."); IDSetSwitch(&ShutterSP, nullptr); break; } } }
void QSICCD::activateCooler(bool enable) { bool coolerOn; if (enable) { try { QSICam.get_CoolerOn(&coolerOn); } catch (std::runtime_error err) { CoolerSP.s = IPS_IDLE; CoolerS[0].s = ISS_OFF; CoolerS[1].s = ISS_ON; DEBUGF(INDI::Logger::DBG_ERROR, "Error: CoolerOn() failed. %s.", err.what()); IDSetSwitch(&CoolerSP, nullptr); return; } if (!coolerOn) { try { QSICam.put_CoolerOn(true); } catch (std::runtime_error err) { CoolerSP.s = IPS_IDLE; CoolerS[0].s = ISS_OFF; CoolerS[1].s = ISS_ON; DEBUGF(INDI::Logger::DBG_ERROR, "Error: put_CoolerOn(true) failed. %s.", err.what()); return; } } /* Success! */ CoolerS[0].s = ISS_ON; CoolerS[1].s = ISS_OFF; CoolerSP.s = IPS_OK; DEBUG(INDI::Logger::DBG_SESSION, "Cooler ON"); IDSetSwitch(&CoolerSP, nullptr); CoolerNP.s = IPS_BUSY; } else { CoolerS[0].s = ISS_OFF; CoolerS[1].s = ISS_ON; CoolerSP.s = IPS_IDLE; try { QSICam.get_CoolerOn(&coolerOn); if (coolerOn) QSICam.put_CoolerOn(false); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_ERROR, "Error: CoolerOn() failed. %s.", err.what()); IDSetSwitch(&CoolerSP, nullptr); return; } DEBUG(INDI::Logger::DBG_SESSION, "Cooler is OFF."); IDSetSwitch(&CoolerSP, nullptr); } }
/*Set the debug flags------------------------------------------------*/ void set_debugflags(char *flags) { debugflags = flags; if (strchr(debugflags, '@') != NULL) alldebugflags = true; DEBUGF('a', "Debugflags = \"%s\"\n", debugflags); }
/*-----------------------------------------------------------------------------------*/ struct pbuf * pbuf_alloc(pbuf_layer l, uint16_t size, pbuf_flag flag) { struct pbuf *p, *q, *r; uint16_t offset; int32_t rsize; offset = 0; switch(l) { case PBUF_TRANSPORT: offset += PBUF_TRANSPORT_HLEN; /* FALLTHROUGH */ case PBUF_IP: offset += PBUF_IP_HLEN; offset += PBUF_LINK_HLEN; /* FALLTHROUGH */ case PBUF_LINK: break; case PBUF_RAW: break; default: ASSERT("pbuf_alloc: bad pbuf layer", 0); return NULL; } switch(flag) { case PBUF_POOL: /* Allocate head of pbuf chain into p. */ p = pbuf_pool_alloc(); if(p == NULL) { #ifdef PBUF_STATS ++stats.pbuf.err; #endif /* PBUF_STATS */ return NULL; } p->next = NULL; /* Set the payload pointer so that it points offset bytes into pbuf data memory. */ p->payload = MEM_ALIGN((void *)((uint8_t *)p + (sizeof(struct pbuf) + offset))); /* The total length of the pbuf is the requested size. */ p->tot_len = size; /* Set the length of the first pbuf is the chain. */ p->len = size > PBUF_POOL_BUFSIZE - offset? PBUF_POOL_BUFSIZE - offset: size; p->flags = PBUF_FLAG_POOL; /* Allocate the tail of the pbuf chain. */ r = p; rsize = size - p->len; while(rsize > 0) { q = pbuf_pool_alloc(); if(q == NULL) { DEBUGF(PBUF_DEBUG, ("pbuf_alloc: Out of pbufs in pool,\n")); #ifdef PBUF_STATS ++stats.pbuf.err; #endif /* PBUF_STATS */ pbuf_pool_free(p); return NULL; } q->next = NULL; r->next = q; q->len = rsize > PBUF_POOL_BUFSIZE? PBUF_POOL_BUFSIZE: rsize; q->flags = PBUF_FLAG_POOL; q->payload = (void *)((uint8_t *)q + sizeof(struct pbuf)); r = q; q->ref = 1; q = q->next; rsize -= PBUF_POOL_BUFSIZE; } r->next = NULL; ASSERT("pbuf_alloc: pbuf->payload properly aligned", ((uint32_t)p->payload % MEM_ALIGNMENT) == 0); break; case PBUF_RAM: /* If pbuf is to be allocated in RAM, allocate memory for it. */ p = (struct pbuf*)mem_malloc(MEM_ALIGN_SIZE(sizeof(struct pbuf) + size + offset)); if(p == NULL) { return NULL; } /* Set up internal structure of the pbuf. */ p->payload = MEM_ALIGN((void *)((uint8_t *)p + sizeof(struct pbuf) + offset)); p->len = p->tot_len = size; p->next = NULL; p->flags = PBUF_FLAG_RAM; ASSERT("pbuf_alloc: pbuf->payload properly aligned", ((uint32_t)p->payload % MEM_ALIGNMENT) == 0); break; case PBUF_ROM: /* If the pbuf should point to ROM, we only need to allocate memory for the pbuf structure. */ p = (struct pbuf*)memp_mallocp(MEMP_PBUF); if(p == NULL) { return NULL; } p->payload = NULL; p->len = p->tot_len = size; p->next = NULL; p->flags = PBUF_FLAG_ROM; break; default: ASSERT("pbuf_alloc: erroneous flag", 0); return NULL; } p->ref = 1; return p; }
bool QSICCD::Connect() { bool connected; DEBUG(INDI::Logger::DBG_SESSION, "Attempting to find QSI CCD..."); try { QSICam.get_Connected(&connected); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_ERROR, "Error: get_Connected() failed. %s.", err.what()); return false; } if (!connected) { try { QSICam.put_Connected(true); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_ERROR, "Error: put_Connected(true) failed. %s.", err.what()); return false; } } bool hasST4Port = false; try { QSICam.get_CanPulseGuide(&hasST4Port); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_ERROR, "get_canPulseGuide() failed. %s.", err.what()); return false; } try { QSICam.get_CanAbortExposure(&canAbort); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_ERROR, "get_CanAbortExposure() failed. %s.", err.what()); return false; } uint32_t cap = CCD_CAN_BIN | CCD_CAN_SUBFRAME | CCD_HAS_COOLER | CCD_HAS_SHUTTER; if (canAbort) cap |= CCD_CAN_ABORT; if (hasST4Port) cap |= CCD_HAS_ST4_PORT; SetCCDCapability(cap); /* Success! */ DEBUG(INDI::Logger::DBG_SESSION, "CCD is online. Retrieving basic data."); return true; }
bool get_spc_metadata(int fd, struct mp3entry* id3) { /* Use the trackname part of the id3 structure as a temporary buffer */ unsigned char * buf = (unsigned char *)id3->path; int read_bytes; char * p; unsigned long length; unsigned long fade; bool isbinary = true; int i; /* try to get the ID666 tag */ if ((lseek(fd, 0x2e, SEEK_SET) < 0) || ((read_bytes = read(fd, buf, 0xD2)) < 0xD2)) { DEBUGF("lseek or read failed\n"); return false; } p = id3->id3v2buf; id3->title = p; buf[31] = 0; p = iso_decode(buf, p, 0, 32); buf += 32; id3->album = p; buf[31] = 0; p = iso_decode(buf, p, 0, 32); buf += 48; id3->comment = p; buf[31] = 0; p = iso_decode(buf, p, 0, 32); buf += 32; /* Date check */ if(buf[2] == '/' && buf[5] == '/') isbinary = false; /* Reserved bytes check */ if(buf[0xD2 - 0x2E - 112] >= '0' && buf[0xD2 - 0x2E - 112] <= '9' && buf[0xD3 - 0x2E - 112] == 0x00) isbinary = false; /* is length & fade only digits? */ for (i=0; i<8 && ( (buf[0xA9 - 0x2E - 112+i]>='0'&&buf[0xA9 - 0x2E - 112+i]<='9') || buf[0xA9 - 0x2E - 112+i]=='\0'); i++); if (i==8) isbinary = false; if(isbinary) { id3->year = buf[0] | (buf[1]<<8); buf += 11; length = (buf[0] | (buf[1]<<8) | (buf[2]<<16)) * 1000; buf += 3; fade = (buf[0] | (buf[1]<<8) | (buf[2]<<16) | (buf[3]<<24)); buf += 4; } else { char tbuf[6]; buf += 6; buf[4] = 0; id3->year = atoi(buf); buf += 5; memcpy(tbuf, buf, 3); tbuf[3] = 0; length = atoi(tbuf) * 1000; buf += 3; memcpy(tbuf, buf, 5); tbuf[5] = 0; fade = atoi(tbuf); buf += 5; } id3->artist = p; buf[31] = 0; p = iso_decode(buf, p, 0, 32); if (length==0) { length=3*60*1000; /* 3 minutes */ fade=5*1000; /* 5 seconds */ } id3->length = length+fade; id3->filesize = filesize(fd); id3->genre_string = id3_get_num_genre(36); return true; }
/** * curl_global_init() globally initializes cURL given a bitwise set of the * different features of what to initialize. */ CURLcode curl_global_init(long flags) { if(initialized++) return CURLE_OK; /* Setup the default memory functions here (again) */ Curl_cmalloc = (curl_malloc_callback)malloc; Curl_cfree = (curl_free_callback)free; Curl_crealloc = (curl_realloc_callback)realloc; Curl_cstrdup = (curl_strdup_callback)system_strdup; Curl_ccalloc = (curl_calloc_callback)calloc; #if defined(WIN32) && defined(UNICODE) Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup; #endif if(flags & CURL_GLOBAL_SSL) if(!Curl_ssl_init()) { DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n")); return CURLE_FAILED_INIT; } if(flags & CURL_GLOBAL_WIN32) if(win32_init() != CURLE_OK) { DEBUGF(fprintf(stderr, "Error: win32_init failed\n")); return CURLE_FAILED_INIT; } #ifdef __AMIGA__ if(!Curl_amiga_init()) { DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n")); return CURLE_FAILED_INIT; } #endif #ifdef NETWARE if(netware_init()) { DEBUGF(fprintf(stderr, "Warning: LONG namespace not available\n")); } #endif #ifdef USE_LIBIDN idna_init(); #endif if(Curl_resolver_global_init() != CURLE_OK) { DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n")); return CURLE_FAILED_INIT; } #if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT) if(libssh2_init(0)) { DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n")); return CURLE_FAILED_INIT; } #endif if(flags & CURL_GLOBAL_ACK_EINTR) Curl_ack_eintr = 1; init_flags = flags; return CURLE_OK; }
/*-----------------------------------------------------------------------------------*/ void tcp_slowtmr(void) { static struct tcp_pcb *pcb, *pcb2, *prev; static struct tcp_seg *seg, *useg; static uint32_t eff_wnd; static uint8_t pcb_remove; /* flag if a PCB should be removed */ ++tcp_ticks; /* Steps through all of the active PCBs. */ prev = NULL; pcb = tcp_active_pcbs; while(pcb != NULL) { ASSERT("tcp_timer_coarse: active pcb->state != CLOSED", pcb->state != CLOSED); ASSERT("tcp_timer_coarse: active pcb->state != LISTEN", pcb->state != LISTEN); ASSERT("tcp_timer_coarse: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); pcb_remove = 0; if(pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { ++pcb_remove; } else if(pcb->nrtx == TCP_MAXRTX) { ++pcb_remove; } else { ++pcb->rtime; seg = pcb->unacked; if(seg != NULL && pcb->rtime >= pcb->rto) { DEBUGF(TCP_RTO_DEBUG, ("tcp_timer_coarse: rtime %ld pcb->rto %d\n", tcp_ticks - pcb->rtime, pcb->rto)); /* Double retransmission time-out unless we are trying to connect to somebody (i.e., we are in SYN_SENT). */ if(pcb->state != SYN_SENT) { pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; } /* Move all other unacked segments to the unsent queue. */ if(seg->next != NULL) { for(useg = seg->next; useg->next != NULL; useg = useg->next); /* useg now points to the last segment on the unacked queue. */ useg->next = pcb->unsent; pcb->unsent = seg->next; seg->next = NULL; pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno); } /* Do the actual retransmission. */ tcp_rexmit_seg(pcb, seg); /* Reduce congestion window and ssthresh. */ eff_wnd = MIN(pcb->cwnd, pcb->snd_wnd); pcb->ssthresh = eff_wnd >> 1; if(pcb->ssthresh < pcb->mss) { pcb->ssthresh = pcb->mss * 2; } pcb->cwnd = pcb->mss; DEBUGF(TCP_CWND_DEBUG, ("tcp_rexmit_seg: cwnd %u ssthresh %u\n", pcb->cwnd, pcb->ssthresh)); } }
/* * Write bytes to the drive via the CBM default protocol. * Returns number of successful written bytes or 0 on error. */ static uint16_t iec_raw_write(uint16_t len, uint8_t flags) { uint8_t atn, talk, data; uint16_t rv; rv = len; atn = flags & XUM_WRITE_ATN; talk = flags & XUM_WRITE_TALK; eoi = 0; DEBUGF(DBG_INFO, "cwr %d, atn %d, talk %d\n", len, atn, talk); if (len == 0) return 0; usbInitIo(len, ENDPOINT_DIR_OUT); /* * First, check if any device is present on the bus. * If ATN and RST are both low (active), we know that at least one * drive is attached but none are powered up. In this case, we * bail out early. Otherwise, we'd get stuck in wait_for_listener(). */ if (!iec_wait_timeout_2ms(IO_ATN|IO_RESET, 0)) { DEBUGF(DBG_ERROR, "write: no devs on bus\n"); usbIoDone(); return 0; } iec_release(IO_DATA); iec_set(IO_CLK | (atn ? IO_ATN : 0)); IEC_DELAY(); // Wait for any device to pull data after we set CLK. This is actually // IEC_T_AT (1 ms) but we allow a bit longer. if (!iec_wait_timeout_2ms(IO_DATA, IO_DATA)) { DEBUGF(DBG_ERROR, "write: no devs\n"); iec_release(IO_CLK | IO_ATN); usbIoDone(); return 0; } /* * Wait a short while for drive to be ready for us to release CLK. * This uses the typical value for IEC_T_NE. Even though it has no * minimum, the transfer starts to be unreliable for Tne somewhere * below 10 us. */ DELAY_US(IEC_T_NE); // Respond with data as soon as device is ready (max time Tne, 200 us). while (len != 0) { // Be sure DATA line has been pulled by device. If not, we timed // out without a device being ready. if (!iec_get(IO_DATA)) { DEBUGF(DBG_ERROR, "write: dev not pres\n"); rv = 0; break; } // Release CLK and wait forever for listener to release data. if (!wait_for_listener()) { DEBUGF(DBG_ERROR, "write: w4l abrt\n"); rv = 0; break; } /* * Signal EOI by waiting so long (IEC_T_YE, > 200 us) that * listener pulls DATA, then wait for it to be released. * The device will do so in IEC_T_EI, >= 60 us. * * If we're not signalling EOI, we must set CLK (below) in less * than 200 us after wait_for_listener() (IEC_T_RY). */ if (len == 1 && !atn) { iec_wait_timeout_2ms(IO_DATA, IO_DATA); iec_wait_timeout_2ms(IO_DATA, 0); } iec_set(IO_CLK); // Get a data byte from host, quitting if it signalled an abort. if (usbRecvByte(&data) != 0) { rv = 0; break; } if (send_byte(data)) { len--; DELAY_US(IEC_T_BB); } else { DEBUGF(DBG_ERROR, "write: io err\n"); rv = 0; break; } wdt_reset(); } usbIoDone(); /* * We rely on the per-byte IEC_T_BB delay (above) being more than * the minimum time before releasing ATN (IEC_T_R). */ if (rv != 0) { // Talk-ATN turn around (talker and listener exchange roles). if (talk) { // Hold DATA and release ATN, waiting talk-ATN release time. iec_set_release(IO_DATA, IO_ATN); DELAY_US(IEC_T_TK); // Now release CLK and wait for device to grab it. iec_release(IO_CLK); IEC_DELAY(); // Wait forever for device (IEC_T_DC). while (!iec_get(IO_CLK)) { if (!TimerWorker()) { rv = 0; break; } } } else iec_release(IO_ATN); } else { /* * If there was an error, release all lines before returning. * Delay the minimum time to releasing ATN after frame, just in * case the IEC_T_BB delay (above) was skipped. It is only performed * if send_byte() succeeded and not in this error case. */ DELAY_US(IEC_T_R); iec_release(IO_CLK | IO_ATN); } DEBUGF(DBG_INFO, "wrv=%d\n", rv); return rv; }
int main(int argc, char *argv[]) { int fd, fd_dec; int res, datasize,i; int nb_frames = 0; #ifdef DUMP_RAW_FRAMES char filename[15]; int fd_out; #endif int32_t outbuf[2048]; uint16_t fs,sps,h; uint32_t packet_count; COOKContext q; RMContext rmctx; RMPacket pkt; memset(&q,0,sizeof(COOKContext)); memset(&rmctx,0,sizeof(RMContext)); memset(&pkt,0,sizeof(RMPacket)); if (argc != 2) { DEBUGF("Incorrect number of arguments\n"); return -1; } fd = open(argv[1],O_RDONLY); if (fd < 0) { DEBUGF("Error opening file %s\n", argv[1]); return -1; } /* copy the input rm file to a memory buffer */ uint8_t * filebuf = (uint8_t *)calloc((int)filesize(fd),sizeof(uint8_t)); res = read(fd,filebuf,filesize(fd)); fd_dec = open_wav("output.wav"); if (fd_dec < 0) { DEBUGF("Error creating output file\n"); return -1; } res = real_parse_header(fd, &rmctx); packet_count = rmctx.nb_packets; rmctx.audio_framesize = rmctx.block_align; rmctx.block_align = rmctx.sub_packet_size; fs = rmctx.audio_framesize; sps= rmctx.block_align; h = rmctx.sub_packet_h; cook_decode_init(&rmctx,&q); /* change the buffer pointer to point at the first audio frame */ advance_buffer(&filebuf, rmctx.data_offset+ DATA_HEADER_SIZE); while(packet_count) { rm_get_packet(&filebuf, &rmctx, &pkt); //DEBUGF("total frames = %d packet count = %d output counter = %d \n",rmctx.audio_pkt_cnt*(fs/sps), packet_count,rmctx.audio_pkt_cnt); for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++) { /* output raw audio frames that are sent to the decoder into separate files */ #ifdef DUMP_RAW_FRAMES snprintf(filename,sizeof(filename),"dump%d.raw",++x); fd_out = open(filename,O_WRONLY|O_CREAT|O_APPEND, 0666); write(fd_out,pkt.frames[i],sps); close(fd_out); #endif nb_frames = cook_decode_frame(&rmctx,&q, outbuf, &datasize, pkt.frames[i] , rmctx.block_align); rmctx.frame_number++; res = write(fd_dec,outbuf,datasize); } packet_count -= rmctx.audio_pkt_cnt; rmctx.audio_pkt_cnt = 0; } close_wav(fd_dec, &rmctx, &q); close(fd); return 0; }
static uint16_t iec_raw_read(uint16_t len) { uint8_t ok, bit, b; uint16_t to, count; DEBUGF(DBG_INFO, "crd %d\n", len); usbInitIo(len, ENDPOINT_DIR_IN); count = 0; do { to = 0; /* wait for clock to be released. typically times out during: */ /* directory read */ while (iec_get(IO_CLK)) { if (to >= 50000 || !TimerWorker()) { /* 1.0 (50000 * 20us) sec timeout */ DEBUGF(DBG_ERROR, "rd to\n"); usbIoDone(); return 0; } to++; DELAY_US(20); } // XXX is this right? why treat EOI differently here? if (eoi) { usbIoDone(); return 0; } /* release DATA line */ iec_release(IO_DATA); /* use special "timer with wait for clock" */ iec_wait_clk(); // Is the talking device signalling EOI? if (iec_get(IO_CLK) == 0) { eoi = 1; iec_set(IO_DATA); DELAY_US(70); iec_release(IO_DATA); } /* * Disable IRQs to make sure the byte transfer goes uninterrupted. * This isn't strictly needed since the only interrupt we use is the * one for USB control transfers. */ cli(); // Wait up to 2 ms for CLK to be asserted ok = iec_wait_timeout_2ms(IO_CLK, IO_CLK); // Read all 8 bits of a byte for (bit = b = 0; bit < 8 && ok; bit++) { // Wait up to 2 ms for CLK to be released ok = iec_wait_timeout_2ms(IO_CLK, 0); if (ok) { b >>= 1; if (iec_get(IO_DATA) == 0) b |= 0x80; // Wait up to 2 ms for CLK to be asserted ok = iec_wait_timeout_2ms(IO_CLK, IO_CLK); } } sei(); if (ok) { // Acknowledge byte received ok iec_set(IO_DATA); // Send the data byte to host, quitting if it signalled an abort. if (usbSendByte(b)) break; count++; DELAY_US(50); } wdt_reset(); } while (count != len && ok && !eoi); if (!ok) { DEBUGF(DBG_ERROR, "read io err\n"); count = 0; } DEBUGF(DBG_INFO, "rv=%d\n", count); usbIoDone(); return count; }
void QHYCCD::updateTemperature() { double ccdtemp=0,coolpower=0; double nextPoll=POLLMS; if (sim) { ccdtemp = TemperatureN[0].value; if (TemperatureN[0].value < TemperatureRequest) ccdtemp += TEMP_THRESHOLD; else if (TemperatureN[0].value > TemperatureRequest) ccdtemp -= TEMP_THRESHOLD; coolpower = 128; } else { ccdtemp = GetQHYCCDParam(camhandle,CONTROL_CURTEMP); coolpower = GetQHYCCDParam(camhandle,CONTROL_CURPWM); ControlQHYCCDTemp(camhandle,TemperatureRequest); } DEBUGF(INDI::Logger::DBG_DEBUG, "CCD Temp: %g CCD RAW Cooling Power: %g, CCD Cooling percentage: %g", ccdtemp, coolpower, coolpower / 255.0 * 100); TemperatureN[0].value = ccdtemp; CoolerN[0].value = coolpower / 255.0 * 100; if (coolpower > 0 && CoolerS[0].s == ISS_OFF) { CoolerNP.s = IPS_BUSY; CoolerSP.s = IPS_OK; CoolerS[0].s = ISS_ON; CoolerS[1].s = ISS_OFF; IDSetSwitch(&CoolerSP, NULL); } else if (coolpower <= 0 && CoolerS[0].s == ISS_ON) { CoolerNP.s = IPS_IDLE; CoolerSP.s = IPS_IDLE; CoolerS[0].s = ISS_OFF; CoolerS[1].s = ISS_ON; IDSetSwitch(&CoolerSP, NULL); } if (TemperatureNP.s == IPS_BUSY && fabs(TemperatureN[0].value - TemperatureRequest) <= TEMP_THRESHOLD) { TemperatureN[0].value = TemperatureRequest; TemperatureNP.s = IPS_OK; } /* //we need call ControlQHYCCDTemp every second to control temperature if (TemperatureNP.s == IPS_BUSY) nextPoll = TEMPERATURE_BUSY_MS; */ IDSetNumber(&TemperatureNP, NULL); IDSetNumber(&CoolerNP, NULL); temperatureID = IEAddTimer(nextPoll,QHYCCD::updateTemperatureHelper, this); }
void pciauto_setup_device(struct pci_controller *hose, pci_dev_t dev, int bars_num, struct pci_region *mem, struct pci_region *prefetch, struct pci_region *io) { unsigned int bar_response; pci_addr_t bar_value; pci_size_t bar_size; unsigned int cmdstat = 0; struct pci_region *bar_res; int bar, bar_nr = 0; int found_mem64 = 0; pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat); cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER; for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_0 + (bars_num*4); bar += 4) { /* Tickle the BAR and get the response */ pci_hose_write_config_dword(hose, dev, bar, 0xffffffff); pci_hose_read_config_dword(hose, dev, bar, &bar_response); /* If BAR is not implemented go to the next BAR */ if (!bar_response) continue; found_mem64 = 0; /* Check the BAR type and set our address mask */ if (bar_response & PCI_BASE_ADDRESS_SPACE) { bar_size = ((~(bar_response & PCI_BASE_ADDRESS_IO_MASK)) & 0xffff) + 1; bar_res = io; DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ", bar_nr, (u64)bar_size); } else { if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) { u32 bar_response_upper; u64 bar64; pci_hose_write_config_dword(hose, dev, bar+4, 0xffffffff); pci_hose_read_config_dword(hose, dev, bar+4, &bar_response_upper); bar64 = ((u64)bar_response_upper << 32) | bar_response; bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1; found_mem64 = 1; } else { bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1); } if (prefetch && (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH)) bar_res = prefetch; else bar_res = mem; DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%llx, ", bar_nr, (u64)bar_size); } if (pciauto_region_allocate(bar_res, bar_size, &bar_value) == 0) { /* Write it out and update our limit */ pci_hose_write_config_dword(hose, dev, bar, (u32)bar_value); if (found_mem64) { bar += 4; #ifdef CONFIG_SYS_PCI_64BIT pci_hose_write_config_dword(hose, dev, bar, (u32)(bar_value>>32)); #else /* * If we are a 64-bit decoder then increment to the * upper 32 bits of the bar and force it to locate * in the lower 4GB of memory. */ pci_hose_write_config_dword(hose, dev, bar, 0x00000000); #endif } cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ? PCI_COMMAND_IO : PCI_COMMAND_MEMORY; } DEBUGF("\n"); bar_nr++; }
bool QHYCCD::Connect() { sim = isSimulation(); int ret; uint32_t cap; if (sim) { cap = CCD_CAN_SUBFRAME | CCD_CAN_ABORT | CCD_CAN_BIN | CCD_HAS_COOLER | CCD_HAS_ST4_PORT; SetCCDCapability(cap); HasUSBTraffic = true; HasUSBSpeed = true; HasGain = true; HasOffset = true; HasFilters = true; return true; } camhandle = OpenQHYCCD(camid); if(camhandle != NULL) { DEBUGF(INDI::Logger::DBG_SESSION, "Connected to %s.",camid); cap = CCD_CAN_ABORT | CCD_CAN_SUBFRAME | CCD_HAS_STREAMING; ret = InitQHYCCD(camhandle); if(ret != QHYCCD_SUCCESS) { DEBUGF(INDI::Logger::DBG_ERROR, "Error: Init Camera failed (%d)", ret); return false; } ret = IsQHYCCDControlAvailable(camhandle,CAM_MECHANICALSHUTTER); if(ret == QHYCCD_SUCCESS) { cap |= CCD_HAS_SHUTTER; } DEBUGF(INDI::Logger::DBG_DEBUG, "Shutter Control: %s", cap & CCD_HAS_SHUTTER ? "True" : "False"); ret = IsQHYCCDControlAvailable(camhandle,CONTROL_COOLER); if(ret == QHYCCD_SUCCESS) { cap |= CCD_HAS_COOLER; } DEBUGF(INDI::Logger::DBG_DEBUG, "Cooler Control: %s", cap & CCD_HAS_COOLER ? "True" : "False"); ret = IsQHYCCDControlAvailable(camhandle,CONTROL_ST4PORT); if(ret == QHYCCD_SUCCESS) { cap |= CCD_HAS_ST4_PORT; } DEBUGF(INDI::Logger::DBG_DEBUG, "Guider Port Control: %s", cap & CCD_HAS_ST4_PORT ? "True" : "False"); ret = IsQHYCCDControlAvailable(camhandle,CONTROL_SPEED); if(ret == QHYCCD_SUCCESS) { HasUSBSpeed = true; } DEBUGF(INDI::Logger::DBG_DEBUG, "USB Speed Control: %s", HasUSBSpeed ? "True" : "False"); ret = IsQHYCCDControlAvailable(camhandle,CONTROL_GAIN); if(ret == QHYCCD_SUCCESS) { HasGain = true; } DEBUGF(INDI::Logger::DBG_DEBUG, "Gain Control: %s", HasGain ? "True" : "False"); ret = IsQHYCCDControlAvailable(camhandle,CONTROL_OFFSET); if(ret == QHYCCD_SUCCESS) { HasOffset = true; } DEBUGF(INDI::Logger::DBG_DEBUG, "Offset Control: %s", HasOffset ? "True" : "False"); ret = IsQHYCCDControlAvailable(camhandle,CONTROL_CFWPORT); if(ret == QHYCCD_SUCCESS) { HasFilters = true; } DEBUGF(INDI::Logger::DBG_DEBUG, "Has Filters: %s", HasFilters ? "True" : "False"); // Using software binning cap |= CCD_CAN_BIN; camxbin = 1; camybin = 1; /*ret = IsQHYCCDControlAvailable(camhandle,CAM_BIN1X1MODE); if(ret == QHYCCD_SUCCESS) { camxbin = 1; camybin = 1; } DEBUGF(INDI::Logger::DBG_DEBUG, "Bin 1x1: %s", (ret == QHYCCD_SUCCESS) ? "True" : "False"); ret &= IsQHYCCDControlAvailable(camhandle,CAM_BIN2X2MODE); ret &= IsQHYCCDControlAvailable(camhandle,CAM_BIN3X3MODE); ret &= IsQHYCCDControlAvailable(camhandle,CAM_BIN4X4MODE); if(ret == QHYCCD_SUCCESS) { cap |= CCD_CAN_BIN; } DEBUGF(INDI::Logger::DBG_DEBUG, "Binning Control: %s", cap & CCD_CAN_BIN ? "True" : "False"); */ ret= IsQHYCCDControlAvailable(camhandle, CONTROL_USBTRAFFIC); if (ret == QHYCCD_SUCCESS) { HasUSBTraffic = true; } DEBUGF(INDI::Logger::DBG_DEBUG, "USB Traffic Control: %s", HasUSBTraffic ? "True" : "False"); ret = IsQHYCCDControlAvailable(camhandle,CAM_COLOR); if(ret != QHYCCD_ERROR && ret != QHYCCD_ERROR_NOTSUPPORT) { if(ret == BAYER_GB) IUSaveText(&BayerT[2], "GBGR"); else if (ret == BAYER_GR) IUSaveText(&BayerT[2], "GRGB"); else if (ret == BAYER_BG) IUSaveText(&BayerT[2], "BGGR"); else IUSaveText(&BayerT[2], "RGGB"); DEBUGF(INDI::Logger::DBG_DEBUG, "Color CCD: %s", BayerT[2].text); cap |= CCD_HAS_BAYER; } SetCCDCapability(cap); pthread_create( &primary_thread, NULL, &streamVideoHelper, this); return true; } DEBUGF(INDI::Logger::DBG_ERROR, "Connecting to CCD failed (%s)",camid); return false; }
int ares_init_options(ares_channel *channelptr, struct ares_options *options, int optmask) { ares_channel channel; int i; int status = ARES_SUCCESS; struct timeval now; #ifdef CURLDEBUG const char *env = getenv("CARES_MEMDEBUG"); if (env) curl_memdebug(env); env = getenv("CARES_MEMLIMIT"); if (env) { char *endptr; long num = strtol(env, &endptr, 10); if((endptr != env) && (endptr == env + strlen(env)) && (num > 0)) curl_memlimit(num); } #endif if (ares_library_initialized() != ARES_SUCCESS) return ARES_ENOTINITIALIZED; channel = malloc(sizeof(struct ares_channeldata)); if (!channel) { *channelptr = NULL; return ARES_ENOMEM; } now = ares__tvnow(); /* Set everything to distinguished values so we know they haven't * been set yet. */ channel->flags = -1; channel->timeout = -1; channel->tries = -1; channel->ndots = -1; channel->rotate = -1; channel->udp_port = -1; channel->tcp_port = -1; channel->socket_send_buffer_size = -1; channel->socket_receive_buffer_size = -1; channel->nservers = -1; channel->ndomains = -1; channel->nsort = -1; channel->tcp_connection_generation = 0; channel->lookups = NULL; channel->domains = NULL; channel->sortlist = NULL; channel->servers = NULL; channel->sock_state_cb = NULL; channel->sock_state_cb_data = NULL; channel->sock_create_cb = NULL; channel->sock_create_cb_data = NULL; channel->last_server = 0; channel->last_timeout_processed = (time_t)now.tv_sec; memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name)); channel->local_ip4 = 0; memset(&channel->local_ip6, 0, sizeof(channel->local_ip6)); /* Initialize our lists of queries */ ares__init_list_head(&(channel->all_queries)); for (i = 0; i < ARES_QID_TABLE_SIZE; i++) { ares__init_list_head(&(channel->queries_by_qid[i])); } for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++) { ares__init_list_head(&(channel->queries_by_timeout[i])); } /* Initialize configuration by each of the four sources, from highest * precedence to lowest. */ if (status == ARES_SUCCESS) { status = init_by_options(channel, options, optmask); if (status != ARES_SUCCESS) DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n", ares_strerror(status))); } if (status == ARES_SUCCESS) { status = init_by_environment(channel); if (status != ARES_SUCCESS) DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n", ares_strerror(status))); } if (status == ARES_SUCCESS) { status = init_by_resolv_conf(channel); if (status != ARES_SUCCESS) DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n", ares_strerror(status))); } /* * No matter what failed or succeeded, seed defaults to provide * useful behavior for things that we missed. */ status = init_by_defaults(channel); if (status != ARES_SUCCESS) DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n", ares_strerror(status))); /* Generate random key */ if (status == ARES_SUCCESS) { status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN); if (status == ARES_SUCCESS) channel->next_id = ares__generate_new_id(&channel->id_key); else DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n", ares_strerror(status))); } if (status != ARES_SUCCESS) { /* Something failed; clean up memory we may have allocated. */ if (channel->servers) free(channel->servers); if (channel->domains) { for (i = 0; i < channel->ndomains; i++) free(channel->domains[i]); free(channel->domains); } if (channel->sortlist) free(channel->sortlist); if(channel->lookups) free(channel->lookups); free(channel); return status; } /* Trim to one server if ARES_FLAG_PRIMARY is set. */ if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1) channel->nservers = 1; ares__init_servers_state(channel); *channelptr = channel; return ARES_SUCCESS; }
static int _search_parent_process(ParentCtx *ctx) { assert(ctx != NULL); assert(ctx->child_pid > 0); assert(ctx->outfd > 0); assert(ctx->errfd > 0); fd_set rfds; Buffer outbuf; Buffer errbuf; ReaderArgs reader_args; int lc = 0; int status = PROCESS_STATUS_OK; DEBUG("search", "Initializing parent process."); buffer_init(&outbuf, 4096); buffer_init(&errbuf, 4096); _search_reader_args_init(&reader_args, &ctx->filter_args, ctx->user_data); DEBUGF("search", "Reading data from child process (pid=%ld).", ctx->child_pid); int maxfd = (ctx->errfd > ctx->outfd ? ctx->errfd : ctx->outfd) + 1; while(status == PROCESS_STATUS_OK) { FD_ZERO(&rfds); FD_SET(ctx->outfd, &rfds); FD_SET(ctx->errfd, &rfds); ssize_t bytes; ssize_t sum = 0; do { sum = 0; if(select(maxfd, &rfds, NULL, NULL, NULL) > 0) { if(FD_ISSET(ctx->outfd, &rfds)) { reader_args.buffer = &outbuf; reader_args.cb = ctx->found_file; reader_args.filter = true; while(status == PROCESS_STATUS_OK && (bytes = buffer_fill_from_fd(&outbuf, ctx->outfd, 512)) > 0) { status = _search_process_lines_from_buffer(&reader_args); TRACEF("search", "Received %ld byte(s) from stdout, read %d line(s) from stdout buffer.", bytes, reader_args.count); if(status == PROCESS_STATUS_OK) { if(INT32_MAX - reader_args.count >= lc) { lc += reader_args.count; } else { ERROR("search", "Integer overflow."); } } if(SSIZE_MAX - bytes >= sum) { sum += bytes; } } } if(FD_ISSET(ctx->errfd, &rfds)) { reader_args.buffer = &errbuf; reader_args.cb = ctx->err_message; reader_args.filter = false; while(status == PROCESS_STATUS_OK && (bytes = buffer_fill_from_fd(&errbuf, ctx->errfd, 512)) > 0) { TRACEF("search", "Read %ld byte(s) from stderr.", bytes); _search_process_lines_from_buffer(&reader_args); if(SSIZE_MAX - sum >= bytes) { sum += bytes; } } } } } while(status == PROCESS_STATUS_OK && sum); if(status == PROCESS_STATUS_STOP || status == PROCESS_STATUS_ERROR) { _search_kill_child(ctx->child_pid); } status = _search_wait_for_child(ctx, status); } TRACEF("search", "Child process exited: lc=%d, status=%#x.", lc, status); if(status == PROCESS_STATUS_OK) { TRACE("search", "Flushing all buffers."); reader_args.buffer = &outbuf; reader_args.cb = ctx->found_file; reader_args.filter = true; if(_search_flush_and_process_buffer(&reader_args) == PROCESS_STATUS_OK) { if(INT32_MAX - reader_args.count >= lc) { lc += reader_args.count; } else { ERROR("search", "Integer overflow."); } TRACEF("search", "Flushed stdout, lc=%d.", lc); } reader_args.buffer = &errbuf; reader_args.cb = ctx->err_message; reader_args.filter = false; _search_flush_and_process_buffer(&reader_args); } else if(status == PROCESS_STATUS_ERROR) { lc = -1; } TRACE("search", "Cleaning up parent process."); _search_reader_args_free(&reader_args); buffer_free(&outbuf); buffer_free(&errbuf); return lc; }
static int init_by_resolv_conf(ares_channel channel) { #ifndef WATT32 char *line = NULL; #endif int status = -1, nservers = 0, nsort = 0; struct server_state *servers = NULL; struct apattern *sortlist = NULL; #ifdef WIN32 /* NameServer info via IPHLPAPI (IP helper API): GetNetworkParams() should be the trusted source for this. Available in Win-98/2000 and later. If that fail, fall-back to registry information. NameServer Registry: On Windows 9X, the DNS server can be found in: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer On Windows NT/2000/XP/2003: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer or HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer or HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\ NameServer or HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\ DhcpNameServer */ HKEY mykey; HKEY subkey; DWORD data_type; DWORD bytes; DWORD result; char buf[512]; win_platform platform; if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */ return ARES_SUCCESS; if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0) { status = config_nameserver(&servers, &nservers, buf); if (status == ARES_SUCCESS) goto okay; } platform = ares__getplatform(); if (platform == WIN_NT) { if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, &mykey ) == ERROR_SUCCESS) { RegOpenKeyEx(mykey, "Interfaces", 0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey); if (get_res_nt(mykey, NAMESERVER, &line)) { status = config_nameserver(&servers, &nservers, line); free(line); } else if (get_res_nt(mykey, DHCPNAMESERVER, &line)) { status = config_nameserver(&servers, &nservers, line); free(line); } /* Try the interfaces */ else if (get_res_interfaces_nt(subkey, NAMESERVER, &line)) { status = config_nameserver(&servers, &nservers, line); free(line); } else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line)) { status = config_nameserver(&servers, &nservers, line); free(line); } RegCloseKey(subkey); RegCloseKey(mykey); } } else if (platform == WIN_9X) { if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ, &mykey ) == ERROR_SUCCESS) { if ((result = RegQueryValueEx( mykey, NAMESERVER, NULL, &data_type, NULL, &bytes ) ) == ERROR_SUCCESS || result == ERROR_MORE_DATA) { if (bytes) { line = malloc(bytes+1); if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type, (unsigned char *)line, &bytes) == ERROR_SUCCESS) { status = config_nameserver(&servers, &nservers, line); } free(line); } } } RegCloseKey(mykey); } if (status == ARES_SUCCESS) status = ARES_EOF; else /* Catch the case when all the above checks fail (which happens when there is no network card or the cable is unplugged) */ status = ARES_EFILE; #elif defined(__riscos__) /* Under RISC OS, name servers are listed in the system variable Inet$Resolvers, space separated. */ line = getenv("Inet$Resolvers"); status = ARES_EOF; if (line) { char *resolvers = strdup(line), *pos, *space; if (!resolvers) return ARES_ENOMEM; pos = resolvers; do { space = strchr(pos, ' '); if (space) *space = '\0'; status = config_nameserver(&servers, &nservers, pos); if (status != ARES_SUCCESS) break; pos = space + 1; } while (space); if (status == ARES_SUCCESS) status = ARES_EOF; free(resolvers); } #elif defined(WATT32) int i; sock_init(); for (i = 0; def_nameservers[i]; i++) ; if (i == 0) return ARES_SUCCESS; /* use localhost DNS server */ nservers = i; servers = calloc(i, sizeof(struct server_state)); if (!servers) return ARES_ENOMEM; for (i = 0; def_nameservers[i]; i++) { servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]); servers[i].addr.family = AF_INET; } status = ARES_EOF; #elif defined(ANDROID) char value[PROP_VALUE_MAX]=""; __system_property_get("net.dns1", value); status = config_nameserver(&servers, &nservers, value); if (status == ARES_SUCCESS) status = ARES_EOF; #else { char *p; FILE *fp; size_t linesize; int error; /* Don't read resolv.conf and friends if we don't have to */ if (ARES_CONFIG_CHECK(channel)) return ARES_SUCCESS; fp = fopen(PATH_RESOLV_CONF, "r"); if (fp) { while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) { if ((p = try_config(line, "domain", ';'))) status = config_domain(channel, p); else if ((p = try_config(line, "lookup", ';')) && !channel->lookups) status = config_lookup(channel, p, "bind", "file"); else if ((p = try_config(line, "search", ';'))) status = set_search(channel, p); else if ((p = try_config(line, "nameserver", ';')) && channel->nservers == -1) status = config_nameserver(&servers, &nservers, p); else if ((p = try_config(line, "sortlist", ';')) && channel->nsort == -1) status = config_sortlist(&sortlist, &nsort, p); else if ((p = try_config(line, "options", ';'))) status = set_options(channel, p); else status = ARES_SUCCESS; if (status != ARES_SUCCESS) break; } fclose(fp); } else { error = ERRNO; switch(error) { case ENOENT: case ESRCH: status = ARES_EOF; break; default: DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error, strerror(error))); DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF)); status = ARES_EFILE; } } if ((status == ARES_EOF) && (!channel->lookups)) { /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */ fp = fopen("/etc/nsswitch.conf", "r"); if (fp) { while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) { if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups) /* ignore errors */ (void)config_lookup(channel, p, "dns", "files"); } fclose(fp); } else { error = ERRNO; switch(error) { case ENOENT: case ESRCH: status = ARES_EOF; break; default: DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error, strerror(error))); DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf")); status = ARES_EFILE; } } } if ((status == ARES_EOF) && (!channel->lookups)) { /* Linux / GNU libc 2.x and possibly others have host.conf */ fp = fopen("/etc/host.conf", "r"); if (fp) { while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) { if ((p = try_config(line, "order", '\0')) && !channel->lookups) /* ignore errors */ (void)config_lookup(channel, p, "bind", "hosts"); } fclose(fp); } else { error = ERRNO; switch(error) { case ENOENT: case ESRCH: status = ARES_EOF; break; default: DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error, strerror(error))); DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf")); status = ARES_EFILE; } } } if ((status == ARES_EOF) && (!channel->lookups)) { /* Tru64 uses /etc/svc.conf */ fp = fopen("/etc/svc.conf", "r"); if (fp) { while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) { if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups) /* ignore errors */ (void)config_lookup(channel, p, "bind", "local"); } fclose(fp); } else { error = ERRNO; switch(error) { case ENOENT: case ESRCH: status = ARES_EOF; break; default: DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error, strerror(error))); DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf")); status = ARES_EFILE; } } } if(line) free(line); } #endif /* Handle errors. */ if (status != ARES_EOF) { if (servers != NULL) free(servers); if (sortlist != NULL) free(sortlist); return status; } /* If we got any name server entries, fill them in. */ #ifdef WIN32 okay: #endif if (servers) { channel->servers = servers; channel->nservers = nservers; } /* If we got any sortlist entries, fill them in. */ if (sortlist) { channel->sortlist = sortlist; channel->nsort = nsort; } return ARES_SUCCESS; }
/* * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to * do protocol-specific actions at connect-time. */ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done) { int i; struct SSHPROTO *ssh; const char *fingerprint; const char *authlist; char *home; char rsa_pub[PATH_MAX]; char rsa[PATH_MAX]; char tempHome[PATH_MAX]; curl_socket_t sock; char *real_path; char *working_path; int working_path_len; bool authed = FALSE; CURLcode result; struct SessionHandle *data = conn->data; rsa_pub[0] = rsa[0] = '\0'; result = ssh_init(conn); if (result) return result; ssh = data->reqdata.proto.ssh; working_path = curl_easy_unescape(data, data->reqdata.path, 0, &working_path_len); if (!working_path) return CURLE_OUT_OF_MEMORY; #ifdef CURL_LIBSSH2_DEBUG if (ssh->user) { infof(data, "User: %s\n", ssh->user); } if (ssh->passwd) { infof(data, "Password: %s\n", ssh->passwd); } #endif /* CURL_LIBSSH2_DEBUG */ sock = conn->sock[FIRSTSOCKET]; ssh->ssh_session = libssh2_session_init_ex(libssh2_malloc, libssh2_free, libssh2_realloc, ssh); if (ssh->ssh_session == NULL) { failf(data, "Failure initialising ssh session\n"); Curl_safefree(ssh->path); return CURLE_FAILED_INIT; } #ifdef CURL_LIBSSH2_DEBUG infof(data, "SSH socket: %d\n", sock); #endif /* CURL_LIBSSH2_DEBUG */ if (libssh2_session_startup(ssh->ssh_session, sock)) { failf(data, "Failure establishing ssh session\n"); libssh2_session_free(ssh->ssh_session); ssh->ssh_session = NULL; Curl_safefree(ssh->path); return CURLE_FAILED_INIT; } /* * Before we authenticate we should check the hostkey's fingerprint against * our known hosts. How that is handled (reading from file, whatever) is * up to us. As for know not much is implemented, besides showing how to * get the fingerprint. */ fingerprint = libssh2_hostkey_hash(ssh->ssh_session, LIBSSH2_HOSTKEY_HASH_MD5); #ifdef CURL_LIBSSH2_DEBUG /* The fingerprint points to static storage (!), don't free() it. */ infof(data, "Fingerprint: "); for (i = 0; i < 16; i++) { infof(data, "%02X ", (unsigned char) fingerprint[i]); } infof(data, "\n"); #endif /* CURL_LIBSSH2_DEBUG */ /* TBD - methods to check the host keys need to be done */ /* * Figure out authentication methods * NB: As soon as we have provided a username to an openssh server we must * never change it later. Thus, always specify the correct username here, * even though the libssh2 docs kind of indicate that it should be possible * to get a 'generic' list (not user-specific) of authentication methods, * presumably with a blank username. That won't work in my experience. * So always specify it here. */ authlist = libssh2_userauth_list(ssh->ssh_session, ssh->user, strlen(ssh->user)); /* * Check the supported auth types in the order I feel is most secure with the * requested type of authentication */ if ((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) && (strstr(authlist, "publickey") != NULL)) { /* To ponder about: should really the lib be messing about with the HOME environment variable etc? */ home = curl_getenv("HOME"); if (data->set.ssh_public_key) snprintf(rsa_pub, sizeof(rsa_pub), "%s", data->set.ssh_public_key); else if (home) snprintf(rsa_pub, sizeof(rsa_pub), "%s/.ssh/id_dsa.pub", home); if (data->set.ssh_private_key) snprintf(rsa, sizeof(rsa), "%s", data->set.ssh_private_key); else if (home) snprintf(rsa, sizeof(rsa), "%s/.ssh/id_dsa", home); curl_free(home); if (rsa_pub[0]) { /* The function below checks if the files exists, no need to stat() here. */ if (libssh2_userauth_publickey_fromfile(ssh->ssh_session, ssh->user, rsa_pub, rsa, "") == 0) { authed = TRUE; } } } if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) && (strstr(authlist, "password") != NULL)) { if (!libssh2_userauth_password(ssh->ssh_session, ssh->user, ssh->passwd)) authed = TRUE; } if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_HOST) && (strstr(authlist, "hostbased") != NULL)) { } if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) && (strstr(authlist, "keyboard-interactive") != NULL)) { /* Authentication failed. Continue with keyboard-interactive now. */ if (libssh2_userauth_keyboard_interactive_ex(ssh->ssh_session, ssh->user, strlen(ssh->user), &kbd_callback) == 0) { authed = TRUE; } } if (!authed) { failf(data, "Authentication failure\n"); libssh2_session_free(ssh->ssh_session); ssh->ssh_session = NULL; Curl_safefree(ssh->path); return CURLE_FAILED_INIT; } /* * At this point we have an authenticated ssh session. */ conn->sockfd = sock; conn->writesockfd = CURL_SOCKET_BAD; if (conn->protocol == PROT_SFTP) { /* * Start the libssh2 sftp session */ ssh->sftp_session = libssh2_sftp_init(ssh->ssh_session); if (ssh->sftp_session == NULL) { failf(data, "Failure initialising sftp session\n"); libssh2_sftp_shutdown(ssh->sftp_session); ssh->sftp_session = NULL; libssh2_session_free(ssh->ssh_session); ssh->ssh_session = NULL; return CURLE_FAILED_INIT; } /* * Get the "home" directory */ i = libssh2_sftp_realpath(ssh->sftp_session, ".", tempHome, PATH_MAX-1); if (i > 0) { /* It seems that this string is not always NULL terminated */ tempHome[i] = '\0'; ssh->homedir = (char *)strdup(tempHome); if (!ssh->homedir) { libssh2_sftp_shutdown(ssh->sftp_session); ssh->sftp_session = NULL; libssh2_session_free(ssh->ssh_session); ssh->ssh_session = NULL; return CURLE_OUT_OF_MEMORY; } } else { /* Return the error type */ i = libssh2_sftp_last_error(ssh->sftp_session); DEBUGF(infof(data, "error = %d\n", i)); } } /* Check for /~/ , indicating realative to the users home directory */ if (conn->protocol == PROT_SCP) { real_path = (char *)malloc(working_path_len+1); if (real_path == NULL) { Curl_safefree(working_path); libssh2_session_free(ssh->ssh_session); ssh->ssh_session = NULL; return CURLE_OUT_OF_MEMORY; } if (working_path[1] == '~') /* It is referenced to the home directory, so strip the leading '/' */ memcpy(real_path, working_path+1, 1 + working_path_len-1); else memcpy(real_path, working_path, 1 + working_path_len); } else if (conn->protocol == PROT_SFTP) { if (working_path[1] == '~') { real_path = (char *)malloc(strlen(ssh->homedir) + working_path_len + 1); if (real_path == NULL) { libssh2_sftp_shutdown(ssh->sftp_session); ssh->sftp_session = NULL; libssh2_session_free(ssh->ssh_session); ssh->ssh_session = NULL; Curl_safefree(working_path); return CURLE_OUT_OF_MEMORY; } /* It is referenced to the home directory, so strip the leading '/' */ memcpy(real_path, ssh->homedir, strlen(ssh->homedir)); real_path[strlen(ssh->homedir)] = '/'; real_path[strlen(ssh->homedir)+1] = '\0'; if (working_path_len > 3) { memcpy(real_path+strlen(ssh->homedir)+1, working_path + 3, 1 + working_path_len -3); } } else { real_path = (char *)malloc(working_path_len+1); if (real_path == NULL) { libssh2_session_free(ssh->ssh_session); ssh->ssh_session = NULL; Curl_safefree(working_path); return CURLE_OUT_OF_MEMORY; } memcpy(real_path, working_path, 1+working_path_len); } } else return CURLE_FAILED_INIT; Curl_safefree(working_path); ssh->path = real_path; *done = TRUE; return CURLE_OK; }
/* Buffer data for the given handle. Return whether or not the buffering should continue explicitly. */ static bool buffer_handle(int handle_id) { logf("buffer_handle(%d)", handle_id); struct memory_handle *h = find_handle(handle_id); bool stop = false; if (!h) return true; if (h->filerem == 0) { /* nothing left to buffer */ return true; } if (h->fd < 0) /* file closed, reopen */ { if (*h->path) h->fd = open(h->path, O_RDONLY); if (h->fd < 0) { /* could not open the file, truncate it where it is */ h->filesize -= h->filerem; h->filerem = 0; return true; } if (h->offset) lseek(h->fd, h->offset, SEEK_SET); } trigger_cpu_boost(); if (h->type == TYPE_ID3) { if (!get_metadata((struct mp3entry *)(buffer + h->data), h->fd, h->path)) { /* metadata parsing failed: clear the buffer. */ memset(buffer + h->data, 0, sizeof(struct mp3entry)); } close(h->fd); h->fd = -1; h->filerem = 0; h->available = sizeof(struct mp3entry); h->widx += sizeof(struct mp3entry); send_event(BUFFER_EVENT_FINISHED, &h->id); return true; } while (h->filerem > 0 && !stop) { /* max amount to copy */ size_t copy_n = MIN( MIN(h->filerem, BUFFERING_DEFAULT_FILECHUNK), buffer_len - h->widx); ssize_t overlap; uintptr_t next_handle = ringbuf_offset(h->next); /* stop copying if it would overwrite the reading position */ if (ringbuf_add_cross(h->widx, copy_n, buf_ridx) >= 0) return false; /* FIXME: This would overwrite the next handle * If this is true, then there's a handle even though we have still * data to buffer. This should NEVER EVER happen! (but it does :( ) */ if (h->next && (overlap = ringbuf_add_cross(h->widx, copy_n, next_handle)) > 0) { /* stop buffering data for now and post-pone buffering the rest */ stop = true; DEBUGF( "%s(): Preventing handle corruption: h1.id:%d h2.id:%d" " copy_n:%lu overlap:%ld h1.filerem:%lu\n", __func__, h->id, h->next->id, (unsigned long)copy_n, overlap, (unsigned long)h->filerem); copy_n -= overlap; } /* rc is the actual amount read */ int rc = read(h->fd, &buffer[h->widx], copy_n); if (rc < 0) { /* Some kind of filesystem error, maybe recoverable if not codec */ if (h->type == TYPE_CODEC) { logf("Partial codec"); break; } DEBUGF("File ended %ld bytes early\n", (long)h->filerem); h->filesize -= h->filerem; h->filerem = 0; break; } /* Advance buffer */ h->widx = ringbuf_add(h->widx, rc); if (h == cur_handle) buf_widx = h->widx; h->available += rc; h->filerem -= rc; /* If this is a large file, see if we need to break or give the codec * more time */ if (h->type == TYPE_PACKET_AUDIO && pcmbuf_is_lowdata() && !buffer_is_low()) { sleep(1); } else { yield(); } if (!queue_empty(&buffering_queue)) break; } if (h->filerem == 0) { /* finished buffering the file */ close(h->fd); h->fd = -1; send_event(BUFFER_EVENT_FINISHED, &h->id); } return !stop; }