From d35526599510fd44e338e4dee42be1da9dc01ad3 Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Tue, 2 Jun 2026 18:28:27 +0300 Subject: [PATCH] start refactoring --- ccdcapture.c | 119 +++-- ccdcapture.h | 22 +- ccdfunc.c | 49 ++- ccdfunc.h | 2 +- client.c | 385 ++++++++++------- locale/ru/LC_MESSAGES/ccd_capture.mo | Bin 14991 -> 0 bytes locale/ru/messages.po | 594 ------------------------- locale/ru/ru.po | 625 --------------------------- locale/ru/ru.po.bkp | 586 ------------------------- main.c | 1 + server.c | 320 ++++++-------- server.h | 7 + 12 files changed, 448 insertions(+), 2262 deletions(-) delete mode 100644 locale/ru/LC_MESSAGES/ccd_capture.mo delete mode 100644 locale/ru/messages.po delete mode 100644 locale/ru/ru.po delete mode 100644 locale/ru/ru.po.bkp diff --git a/ccdcapture.c b/ccdcapture.c index 58ce3d7..a6df8a2 100644 --- a/ccdcapture.c +++ b/ccdcapture.c @@ -134,15 +134,19 @@ int cc_senddata(int fd, void *data, size_t l){ DBG("fd=%d, l=%zd", fd, l); if(fd < 1 || !data || l < 1) return TRUE; // empty message DBG("send new data (size=%zd) to fd %d", l, fd); -//strncpy((char*)data, "TEST image data\n", 17); -//l = 16; - if(l != (size_t)send(fd, data, l, MSG_NOSIGNAL)){ - WARN("write()"); - LOGWARN("write()"); - return FALSE; + size_t total = 0; + while(total < l){ + ssize_t sent = send(fd, (char*)data + total, l - total, MSG_NOSIGNAL); + if(sent <= 0){ + WARN("send()"); + LOGWARN("send()"); + break; // error + } + total += sent; } + if(total != l) return FALSE; DBG("success"); - if(sl_globlog) LOGDBG("SEND data (size=%d) to fd %d", l, fd); + LOGDBG("SEND data (size=%d) to fd %d", l, fd); return TRUE; } @@ -155,25 +159,36 @@ int cc_sendmessage(int fd, const char *msg, int l){ static int buflen = 0; if(l + 1 > buflen){ buflen = 1024 * (1 + l/1024); - tmpbuf = realloc(tmpbuf, buflen); + char *newbuf = realloc(tmpbuf, buflen); + if(!newbuf){ + LOGERR("realloc())"); + return FALSE; + } + tmpbuf = newbuf; } DBG("send to fd %d:\n%s[%d]", fd, msg, l); memcpy(tmpbuf, msg, l); if(msg[l-1] != '\n') tmpbuf[l++] = '\n'; - if(l != send(fd, tmpbuf, l, MSG_NOSIGNAL)){ - WARN("write()"); - LOGWARN("write()"); - pthread_mutex_unlock(&mutex); - return FALSE; - }else{ - //DBG("success"); + int total = 0; + while(total < l){ + ssize_t sent = send(fd, tmpbuf + total, l - total, MSG_NOSIGNAL); + if(sent <= 0){ + WARN("send()"); + LOGWARN("send()"); + break; // error + } + total += sent; + } + int ret = FALSE; + if(total == l){ + ret = TRUE; if(sl_globlog){ // logging turned ON tmpbuf[l-1] = 0; // remove trailing '\n' for logging LOGDBG("SEND '%s'", tmpbuf); } } pthread_mutex_unlock(&mutex); - return TRUE; + return ret; } int cc_sendstrmessage(int fd, const char *msg){ if(fd < 1 || !msg) return TRUE; // empty message @@ -230,36 +245,6 @@ char *cc_get_keyval(char **keyval){ return val; } -/** - * check data from fd (polling function for client) - * @param fd - file descriptor - * @return 0 in case of timeout, 1 in case of fd have data, -1 if error - */ -int cc_canberead(int fd){ - fd_set fds; - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 100; - FD_ZERO(&fds); - FD_SET(fd, &fds); - do{ - int rc = select(fd+1, &fds, NULL, NULL, &timeout); - if(rc < 0){ - if(errno != EINTR){ - LOGWARN("select()"); - WARN("select()"); - return -1; - } - continue; - } - break; - }while(1); - if(FD_ISSET(fd, &fds)){ - return 1; - } - return 0; -} - /** * @brief cc_getshm - get shared memory segment for image * @param imsize - size of image data (in bytes): if !=0 allocate as server, else - as client (readonly) @@ -453,8 +438,14 @@ int cc_read2buf(int fd, cc_strbuff *buf){ pthread_mutex_lock(&buf->mutex); if(!buf->buf || buf->buflen >= buf->bufsize) goto ret; size_t maxlen = buf->bufsize - buf->buflen; - ssize_t rd = read(fd, buf->buf + buf->buflen, maxlen); - if(rd <= 0) goto ret; + ssize_t rd; + do{ + rd = read(fd, buf->buf + buf->buflen, maxlen); + if(rd <= 0){ + if(errno == EAGAIN || errno == EWOULDBLOCK) continue; + goto ret; + }else break; + }while(1); DBG("got %zd bytes", rd); if(rd) buf->buflen += rd; ret = TRUE; @@ -470,7 +461,7 @@ ret: * @return TRUE if got data */ int cc_refreshbuf(int fd, cc_strbuff *buf){ - if(!cc_canberead(fd)) return FALSE; + if(!sl_canread(fd)) return FALSE; return cc_read2buf(fd, buf); } @@ -548,7 +539,7 @@ static cc_hresult ask4cmd(int fd, cc_strbuff *buf, const char *cmdwargs){ if(!cc_sendstrmessage(fd, cmdwargs)) continue; double t0 = sl_dtime(); while(sl_dtime() - t0 < answer_timeout){ - int r = cc_canberead(fd); + int r = sl_canread(fd); if(r == 0) continue; else if(r < 0){ LOGERR("Socket disconnected"); @@ -651,54 +642,59 @@ cc_hresult cc_getfloat(int fd, cc_strbuff *cbuf, const char *cmd, float *val){ // get next record from external buffer, newlines==1 if every record ends with '\n' -char *cc_nextkw(char *buf, char record[FLEN_CARD+1], int newlines){ +char *cc_nextkw(char *buf, char record[FLEN_CARD], int newlines){ char *nextline = NULL; - int l = FLEN_CARD - 1; + int l = FLEN_CARD; if(newlines){ char *e = strchr(buf, '\n'); if(e){ - if(e - buf < FLEN_CARD) l = e - buf; + if(e - buf < FLEN_CARD) l = e - buf + 1; nextline = e + 1; } }else nextline = buf + (FLEN_CARD - 1); strncpy(record, buf, l); - record[l] = 0; return nextline; } /** * @brief cc_kwfromfile - add records from file - * @param b - buffer to add + * @param img - buffer to add * @param filename - file name with FITS headers ('\n'-terminated or by 80 chars) * @return amount of bytes added */ -size_t cc_kwfromfile(cc_charbuff *b, char *filename){ - if(!b) return 0; +size_t cc_kwfromfile(cc_IMG *img, char *filename){ + if(!img) return 0; sl_mmapbuf_t *buf = sl_mmap(filename); if(!buf || buf->len < 1){ WARNX("Can't add FITS records from file %s", filename); LOGWARN("Can't add FITS records from file %s", filename); return 0; } - size_t blen0 = b->buflen; - char rec[FLEN_CARD+1], card[FLEN_CARD+1]; + char rec[FLEN_CARD], card[FLEN_CARD]; char *data = buf->data, *x = strchr(data, '\n'), *eodata = buf->data + buf->len; int newlines = 0; if(x && (x - data) < FLEN_CARD){ // we found newline -> this is a format with newlines newlines = 1; } + size_t written = 0; do{ data = cc_nextkw(data, rec, newlines); if(data > eodata) break; int status = 0, kt = 0; fits_parse_template(rec, card, &kt, &status); if(status) fits_report_error(stderr, status); - else cc_charbufaddline(b, card); + else{ + if(img->headerstrings < FITS_HEADER_STRINGS_MAX){ + ++written; + snprintf(img->fitsheader[img->headerstrings++], FLEN_CARD, "%s", card); + }else break; + } }while(data && *data); sl_munmap(buf); - return b->buflen - blen0; + return written; } +#if 0 /** * @brief cc_charbuf2kw - write all keywords from `b` to file `f` * `b` should be prepared by cc_kwfromfile or similar @@ -734,6 +730,7 @@ int cc_charbuf2kw(cc_charbuff *b, fitsfile *f){ } return TRUE; } +#endif static size_t print_val(cc_partype_t t, void *val, char *buf, size_t bufl){ size_t l = 0; diff --git a/ccdcapture.h b/ccdcapture.h index a07492a..38187bf 100644 --- a/ccdcapture.h +++ b/ccdcapture.h @@ -23,12 +23,16 @@ #include #include // for size_t +// max strings in header +#define FITS_HEADER_STRINGS_MAX (1000) + // magic to mark our SHM #define CC_SHM_MAGIC (0xdeadbeef) // base image parameters - sent by socket and stored in shared memory -typedef struct __attribute__((packed, aligned(4))){ +typedef struct { uint32_t MAGICK; // magick (DEADBEEF) - to mark our shm + pthread_mutex_t mutex; // shared mutex double timestamp; // timestamp of image taken uint8_t bitpix; // bits per pixel (8 or 16) int w, h; // image size @@ -39,6 +43,8 @@ typedef struct __attribute__((packed, aligned(4))){ size_t imnumber; // counter of images captured from server's start void *data; // pointer to data (next byte after this struct) - only for server /* `data` is uint8_t or uint16_t depending on `bitpix` */ + char fitsheader[FITS_HEADER_STRINGS_MAX][FLEN_CARD]; // FITS-header for given image + size_t headerstrings; // amount of records in header } cc_IMG; typedef struct{ @@ -230,11 +236,7 @@ typedef enum{ #define CC_CMD_CAMLIST "camlist" #define CC_CMD_CAMDEVNO "camdevno" #define CC_CMD_EXPOSITION "exptime" -#define CC_CMD_LASTFNAME "lastfilename" -#define CC_CMD_FILENAME "filename" -#define CC_CMD_FILENAMEPREFIX "filenameprefix" // rewrite=1 will rewrite files, =0 - not (only for `filename`) -#define CC_CMD_REWRITE "rewrite" #define CC_CMD_HBIN "hbin" #define CC_CMD_VBIN "vbin" #define CC_CMD_CAMTEMPER "tcold" @@ -250,7 +252,7 @@ typedef enum{ // expstate=CAMERA_CAPTURE will start exposition, CAMERA_IDLE - cancel #define CC_CMD_EXPSTATE "expstate" #define CC_CMD_TREMAIN "tremain" -#define CC_CMD_8BIT "8bit" +#define CC_CMD_8BIT "lowres" #define CC_CMD_FASTSPD "fastspeed" #define CC_CMD_DARK "dark" #define CC_CMD_INFTY "infty" @@ -262,7 +264,6 @@ typedef enum{ #define CC_CMD_OBJECT "object" #define CC_CMD_PROGRAM "program" #define CC_CMD_OBJTYPE "objtype" -#define CC_CMD_HEADERFILES "headerfiles" // focuser #define CC_CMD_FOCLIST "foclist" @@ -328,12 +329,11 @@ int cc_sendmessage(int fd, const char *msg, int l); int cc_sendstrmessage(int fd, const char *msg); char *cc_get_keyval(char **keyval); cc_IMG *cc_getshm(key_t key, size_t imsize); -int cc_canberead(int fd); cc_hresult cc_setint(int fd, cc_strbuff *cbuf, const char *cmd, int val); cc_hresult cc_getint(int fd, cc_strbuff *cbuf, const char *cmd, int *val); cc_hresult cc_setfloat(int fd, cc_strbuff *cbuf, const char *cmd, float val); cc_hresult cc_getfloat(int fd, cc_strbuff *cbuf, const char *cmd, float *val); -char *cc_nextkw(char *buf, char record[FLEN_CARD+1], int newlines); -size_t cc_kwfromfile(cc_charbuff *b, char *filename); -int cc_charbuf2kw(cc_charbuff *b, fitsfile *f); +char *cc_nextkw(char *buf, char record[FLEN_CARD], int newlines); +size_t cc_kwfromfile(cc_IMG *img, char *filename); +//int cc_charbuf2kw(cc_charbuff *b, fitsfile *f); diff --git a/ccdfunc.c b/ccdfunc.c index 76a83f6..dce7e36 100644 --- a/ccdfunc.c +++ b/ccdfunc.c @@ -73,15 +73,20 @@ static int check_filenameprefix(char *buff, int buflen){ return FALSE; } -cc_charbuff *getFITSheader(cc_IMG *img){ - static cc_charbuff charbuf = {0}; - cc_charbufclr(&charbuf); - char card[FLEN_CARD+1], templ[2*FLEN_CARD+1], bufc[FLEN_CARD+1]; +/** + * @brief fillFITSheader (server-side only!) - update img->fitsheader by image data and additional headers + * @param img (io) - image to update + * @return img->headerstrings + */ +size_t fillFITSheader(cc_IMG *img){ + if(!img) return 0; + img->headerstrings = 0; + char card[FLEN_CARD], templ[2*FLEN_CARD], bufc[FLEN_CARD]; #define FORMKW(in) \ do{ int status = 0, kt = 0; \ fits_parse_template(in, card, &kt, &status); \ if(status) fits_report_error(stderr, status);\ - else{cc_charbufaddline(&charbuf, card);} \ + else if(img->headerstrings < FITS_HEADER_STRINGS_MAX) snprintf(img->fitsheader[img->headerstrings++], FLEN_CARD, "%s", card); \ }while(0) #define FORMINT(key, val, comment) do{ \ snprintf(templ, FLEN_CARD, "%s = %d / %s", key, val, comment); \ @@ -98,12 +103,6 @@ do{ int status = 0, kt = 0; \ calculate_stat(img); float tmpf = 0.0; int tmpi = 0; - /* FORMKW("COMMENT this is just a test comment - 0"); - FORMKW("COMMENT this is just a test comment - 1"); - FORMKW("COMMENT this is just a test comment - 2"); - FORMKW("HIERARCH longsome1 = 'this is just a test comment'"); - FORMKW("HIERARCH longsome2 = 'this is just a test comment'"); - FORMKW("HIERARCH longsome3 = 'this is just a test comment'");*/ FORMKW("ORIGIN = 'SAO RAS' / Organization responsible for the data"); FORMKW("OBSERVAT = 'Special Astrophysical Observatory, Russia' / Observatory name"); FORMKW("INSTRUME = 'direct imaging' / Instrument"); @@ -171,10 +170,10 @@ do{ int status = 0, kt = 0; \ if(wheel->getTbody && wheel->getTbody(&tmpf)) FORMFLT("FILTTEMP", tmpf, "Filter wheel body temperature, degr C"); } - if(GP->addhdr){ // add records from files + if(GP->addhdr){ // add records from server-side files char **nxtfile = GP->addhdr; while(*nxtfile){ - cc_kwfromfile(&charbuf, *(nxtfile++)); + cc_kwfromfile(img, *(nxtfile++)); } } // add these keywords after all to override records from files @@ -185,7 +184,7 @@ do{ int status = 0, kt = 0; \ if(camera->getModelName && camera->getModelName(bufc, FLEN_CARD)) FORMSTR("DETECTOR", bufc, "Detector model"); if(GP->instrument) FORMSTR("INSTRUME", GP->instrument, "Instrument"); - return &charbuf; + return img->headerstrings; } // save FITS file `img` into GP->outfile or GP->outfileprefix_XXXX.fits @@ -193,14 +192,10 @@ do{ int status = 0, kt = 0; \ // return FALSE if failed int saveFITS(cc_IMG *img, char **outp){ int ret = FALSE; - if(!camera){ - LOGERR("Can't save image: no camera device"); - WARNX(_("Camera device unknown")); - return FALSE; - } char fnam[PATH_MAX+1]; if(!GP->outfile && !GP->outfileprefix){ LOGWARN("Image not saved: neither filename nor filename prefix pointed"); + WARNX("Image not saved: neither filename nor filename prefix pointed"); return FALSE; } if(GP->outfile){ // pointed specific output file name like "file.fits", check it @@ -236,8 +231,20 @@ int saveFITS(cc_IMG *img, char **outp){ if(nbytes == 1) TRYFITS(fits_create_img, fp, BYTE_IMG, 2, naxes); else TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes); if(fitserror) goto cloerr; - cc_charbuff *bufhdr = getFITSheader(img); - cc_charbuf2kw(bufhdr, fp); + // write header + char key[FLEN_KEYWORD]; + for(size_t i = 0; i < img->headerstrings; ++i){ + char *rec = img->fitsheader[i]; + char *eq = strchr(rec, '='); + int status = 0; + if(eq){ // found 'key = value / comment' + size_t l = eq - rec; + if(l > FLEN_KEYWORD-1) l = FLEN_KEYWORD-1; + memcpy(key, rec, l); key[l] = 0; + fits_update_card(fp, key, rec, &status); + }else fits_write_record(fp, rec, &status); + if(status) fits_report_error(stderr, status); + } // creation date/time int s = 0; fits_write_date(fp, &s); diff --git a/ccdfunc.h b/ccdfunc.h index 4e46e34..47a7919 100644 --- a/ccdfunc.h +++ b/ccdfunc.h @@ -24,7 +24,7 @@ extern cc_Focuser *focuser; extern cc_Wheel *wheel; void calculate_stat(cc_IMG *image); -cc_charbuff *getFITSheader(cc_IMG *img); +size_t fillFITSheader(cc_IMG *img); int saveFITS(cc_IMG *img, char **outp); // for imageview module void focusers(); void wheels(); diff --git a/client.c b/client.c index 7a2fc54..69b67c1 100644 --- a/client.c +++ b/client.c @@ -37,6 +37,7 @@ extern double answer_timeout; static char sendbuf[BUFSIZ]; +static char *lastfilename = NULL; // send message and wait any answer #define SENDMSG(...) do{DBG("SENDMSG"); snprintf(sendbuf, BUFSIZ-1, __VA_ARGS__); verbose(2, "\t> %s", sendbuf); cc_sendstrmessage(sock, sendbuf); while(getans(sock, NULL));} while(0) // send message and wait answer starting with 'cmd' @@ -47,13 +48,13 @@ static volatile atomic_int expstate = CAMERA_CAPTURE; static int xm0,ym0,xm1,ym1; // max format static int xc0,yc0,xc1,yc1; // current format -#ifdef IMAGEVIEW -static volatile atomic_int grabno = 0, oldgrabno = 0; +static volatile atomic_int grabno = 0; +static int oldgrabno = 0; // IPC key for shared memory static cc_IMG ima = {0}, *shmima = NULL; // ima - local storage, shmima - shm (if available) static size_t imbufsz = 0; // image buffer for allocated `ima` static uint8_t *imbuf = NULL; -#endif + // read message from queue or file descriptor static char *readmsg(int fd){ @@ -70,7 +71,7 @@ static char *readmsg(int fd){ return FALSE; } if(test()) return buf->string; - if(1 == cc_canberead(fd)){ + if(1 == sl_canread(fd)){ if(cc_read2buf(fd, buf)){ if(test()) return buf->string; }else ERRX("Server disconnected"); @@ -78,33 +79,37 @@ static char *readmsg(int fd){ return NULL; } +#define CMP_ANS(cmd, ans) strncmp(cmd, ans, sizeof(cmd)-1) // parser of CCD server messages; return TRUE to exit from polling cycle of `getans` (if receive 'FAIL', 'OK' or 'BUSY') -static int parseans(char *ans){ - if(!ans) return FALSE; +static cc_hresult parseans(char *ans){ + if(!ans) return CC_RESULT_BADKEY; //TIMESTAMP("parseans() begin"); //DBG("Parsing of '%s'", ans); - if(0 == strcmp(cc_hresult2str(CC_RESULT_BUSY), ans)){ - WARNX("Server busy"); - return FALSE; + if(0 == strcmp(cc_hresult2str(CC_RESULT_OK), ans)) return CC_RESULT_OK; + for(cc_hresult res = CC_RESULT_BUSY; res < CC_RESULT_NUM; ++res){ + const char *resmsg = cc_hresult2str(res); + if(0 == strcmp(resmsg, ans)){ + WARNX("Server answered: %s", resmsg); + return res; + } } - if(0 == strcmp(cc_hresult2str(CC_RESULT_FAIL), ans)) return TRUE; - if(0 == strcmp(cc_hresult2str(CC_RESULT_OK), ans)) return TRUE; char *val = cc_get_keyval(&ans); // now `ans` is a key and `val` its value - if(0 == strcmp(CC_CMD_EXPSTATE, ans)){ - expstate = atoi(val); - DBG("Exposition state: %d", expstate); - return TRUE; - }else if(0 == strcmp(CC_CMD_FRAMEMAX, ans)){ + if(0 == CMP_ANS(CC_CMD_EXPSTATE, ans)){ + int st = atoi(val); + atomic_store(&expstate, st); + DBG("Exposition state: %d", st); + return CC_RESULT_OK; + }else if(0 == CMP_ANS(CC_CMD_FRAMEMAX, ans)){ sscanf(val, "%d,%d,%d,%d", &xm0, &ym0, &xm1, &ym1); DBG("Got maxformat: %d,%d,%d,%d", xm0, ym0, xm1, ym1); - return TRUE; - }else if(0 == strcmp(CC_CMD_FRAMEFORMAT, ans)){ + return CC_RESULT_OK; + }else if(0 == CMP_ANS(CC_CMD_FRAMEFORMAT, ans)){ sscanf(val, "%d,%d,%d,%d", &xc0, &yc0, &xc1, &yc1); DBG("Got current format: %d,%d,%d,%d", xc0, yc0, xc1, yc1); - return TRUE; - }else if(0 == strcmp(CC_CMD_INFTY, ans)) return TRUE; + return CC_RESULT_OK; + } //TIMESTAMP("parseans() end"); - return FALSE; + return CC_RESULT_SILENCE; // echo of sent command or something else } // read until timeout all messages from server; return FALSE if there was no messages from server @@ -112,23 +117,30 @@ static int parseans(char *ans){ static int getans(int sock, const char *msg){ double t0 = sl_dtime(); char *ans = NULL; - while(sl_dtime() - t0 < answer_timeout){ - char *s = readmsg(sock); - if(!s) continue; + double tmout = answer_timeout; + if(msg) tmout *= 5.; // make first timeout larger for slow networks + cc_hresult res = CC_RESULT_FAIL; + while(sl_dtime() - t0 < tmout){ + ans = readmsg(sock); + if(!ans) continue; + // got answer -> make timeout less + tmout = answer_timeout; t0 = sl_dtime(); - ans = s; TIMESTAMP("Got from server: %s", ans); verbose(1, "\t%s", ans); -DBG("1 msg-> %s, ans -> %s", msg, ans); - if(parseans(ans)){ - DBG("2 msg-> %s, ans -> %s", msg, ans); - if(msg && strncmp(ans, msg, strlen(msg))) continue; - DBG("BREAK"); - break; + DBG("1 msg-> %s, ans -> %s", msg, ans); + res = parseans(ans); + DBG("2 msg-> %s, ans -> %s; result: %d", msg, ans, res); + if(res == CC_RESULT_SILENCE && msg){ + if(strncmp(ans, msg, strlen(msg))) continue; + else res = CC_RESULT_OK; } - + DBG("Got answer -> break"); + break; } - return ((ans) ? TRUE : FALSE); + if(!ans) DBG("Got no answer from server"); + if(res == CC_RESULT_OK) return TRUE; + return FALSE; } /** @@ -200,16 +212,6 @@ static void send_headers(int sock){ if(GP->dark) SENDMSGW(CC_CMD_DARK, "=1"); else SENDMSGW(CC_CMD_DARK, "=0"); } - if(GP->outfile){ - if(!*GP->outfile) SENDMSGW(CC_CMD_FILENAME, "="); - else SENDMSGW(CC_CMD_FILENAME, "=%s", makeabspath(GP->outfile, FALSE)); - if(GP->rewrite) SENDMSGW(CC_CMD_REWRITE, "=1"); - else SENDMSGW(CC_CMD_REWRITE, "=0"); - } - if(GP->outfileprefix){ - if(!*GP->outfileprefix) SENDMSGW(CC_CMD_FILENAMEPREFIX, "="); - else SENDMSGW(CC_CMD_FILENAMEPREFIX, "=%s", makeabspath(GP->outfileprefix, FALSE)); - } // FITS header keywords: #define CHKHDR(x, cmd) do{if(x) SENDMSG(cmd "=%s", x);}while(0) CHKHDR(GP->author, CC_CMD_AUTHOR); @@ -219,107 +221,6 @@ static void send_headers(int sock){ CHKHDR(GP->prog_id, CC_CMD_PROGRAM); CHKHDR(GP->objtype, CC_CMD_OBJTYPE); #undef CHKHDR - if(GP->addhdr){ - char buf[1024], *ptr = buf, **sptr = GP->addhdr; - *buf = 0; - int L = 1024; - while(*sptr){ - if(!**sptr){ - ++sptr; continue; - } - int N = snprintf(ptr, L-1, "%s,", *sptr++); - L -= N; ptr += N; - } - SENDMSGW(CC_CMD_HEADERFILES, "=%s", buf); - } -} - -void client(int sock){ - if(GP->restart){ - SENDCMDW(CC_CMD_RESTART); - return; - } - send_headers(sock); - double t0 = sl_dtime(), tw = t0; - int Nremain = 0, nframe = 1; - // if client gives filename/prefix or Nframes, make exposition - if((GP->outfile && *GP->outfile) || (GP->outfileprefix && *GP->outfileprefix) || GP->nframes > 0){ - Nremain = GP->nframes - 1; - if(Nremain < 1) Nremain = 0; - else GP->waitexpend = TRUE; // N>1 - wait for exp ends - SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); - }else{ - int cntr = 0; - while(sl_dtime() - t0 < CC_WAIT_TIMEOUT && cntr < 3) - if(!getans(sock, NULL)) ++cntr; - DBG("RETURN: no more data"); - return; - } - double timeout = GP->waitexpend ? CC_CLIENT_TIMEOUT : CC_WAIT_TIMEOUT; - verbose(1, "Exposing frame 1..."); - if(GP->waitexpend){ - expstate = CAMERA_CAPTURE; // could be changed earlier - verbose(2, "Wait for exposition end"); - } - while(sl_dtime() - t0 < timeout){ - if(GP->waitexpend && sl_dtime() - tw > CC_WAIT_TIMEOUT){ - SENDCMDW(CC_CMD_TREMAIN); // get remained time - tw = sl_dtime(); - sprintf(sendbuf, "%s", CC_CMD_EXPSTATE); - cc_sendstrmessage(sock, sendbuf); - } - if(getans(sock, NULL)){ // got next portion of data - DBG("server message"); - t0 = sl_dtime(); - if(expstate == CAMERA_ERROR){ - WARNX(_("Can't make exposition")); - continue; - } - //if(expstate != CAMERA_CAPTURE){ - if(expstate == CAMERA_FRAMERDY){ - verbose(2, "Frame ready!"); - expstate = CAMERA_IDLE; - if(Nremain){ - verbose(1, "\n"); - if(GP->pause_len > 0){ - double delta, time1 = sl_dtime() + GP->pause_len; - while(1){ - SENDCMDW(CC_CMD_CAMTEMPER); - if((delta = time1 - sl_dtime()) < __FLT_EPSILON__) break; - if(delta > 1.) verbose(1, _("%d seconds till pause ends\n"), (int)delta); - if(delta > 6.) sleep(5); - else if(delta > 1.) sleep((int)delta); - else usleep((int)(delta*1e6 + 1)); - } - } - verbose(1, "Exposing frame %d...", ++nframe); - --Nremain; - SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); - }else{ - GP->waitexpend = 0; - timeout = answer_timeout; // wait for last file name - } - } - } - } - if(GP->waitexpend) WARNX(_("Server timeout")); - // clear "filename" and "filenameprefix" - SENDMSGW(CC_CMD_FILENAME, "="); - SENDMSGW(CC_CMD_FILENAMEPREFIX, "="); - // clear "rewrite" - SENDMSGW(CC_CMD_REWRITE, "=0"); - DBG("Timeout"); -} - -#ifdef IMAGEVIEW -static int controlfd = -1; // control socket FD -void init_grab_sock(int sock){ - if(sock < 0) ERRX("Can't run without command socket"); - controlfd = sock; - send_headers(sock); - if(!GP->forceimsock && !shmima){ // init shm buffer if user don't ask to work through image socket - shmima = cc_getshm(GP->shmkey, 0); // try to init client shm - } } /** @@ -329,10 +230,11 @@ void init_grab_sock(int sock){ static int readNbytes(int fd, size_t N, uint8_t *buf){ size_t got = 0, need = N; double t0 = sl_dtime(); - while(sl_dtime() - t0 < CC_CLIENT_TIMEOUT /*&& cc_canberead(fd)*/ && need){ + while(sl_dtime() - t0 < CC_CLIENT_TIMEOUT /*&& sl_canread(fd)*/ && need){ t0 = sl_dtime(); ssize_t rd = read(fd, buf + got, need); if(rd <= 0){ + if(errno == EAGAIN || errno == EWOULDBLOCK) continue; WARNX("Server disconnected"); signals(1); } @@ -344,13 +246,27 @@ static int readNbytes(int fd, size_t N, uint8_t *buf){ /** * @brief getimage - read image from shared memory or socket + * @param askheader == TRUE for storing FITS-header + * @return FALSE if failed to catch image */ -static void getimage(){ +static int getimage(int askheader){ FNAME(); - int imsock = -1; + int imsock = -1, shmlocked = FALSE, ret = FALSE; static double oldtimestamp = -1.; TIMESTAMP("Get image sizes"); if(shmima){ // read image from shared memory + double t0 = sl_dtime(); + while(sl_dtime() - t0 < MUTEX_LOCK_TMOUT){ + if(client_lock_shm(shmima)){ + shmlocked = TRUE; + break; + } + usleep(100); + } + if(!shmlocked){ + WARNX("Can't lock shared memory"); + return FALSE; + } memcpy(&ima, shmima, sizeof(cc_IMG)); }else{ // get image by socket imsock = cc_open_socket(FALSE, GP->imageport, TRUE); @@ -379,31 +295,165 @@ static void getimage(){ uint8_t *datastart = (uint8_t*)shmima + sizeof(cc_IMG); memcpy(imbuf, datastart, ima.bytelen); TIMESTAMP("Got by shared memory"); + if(!askheader){ + unlock_shm(shmima); + shmlocked = FALSE; + } + ret = TRUE; }else{ if(!readNbytes(imsock, ima.bytelen, imbuf)){ WARNX("Can't read image data"); goto eofg; } + ret = TRUE; TIMESTAMP("Got by socket"); } - DBG("timestamps old-new=%g; imno: %zd", oldtimestamp-ima.timestamp, ima.imnumber); + DBG("timestamps new-old=%g; imno: %zd", ima.timestamp - oldtimestamp, ima.imnumber); if(ima.timestamp != oldtimestamp){ // test if image is really new oldtimestamp = ima.timestamp; - grabno = ima.imnumber; + atomic_store(&grabno, ima.imnumber); TIMESTAMP("Got image #%zd", ima.imnumber); + if(askheader){ // read FITS-header for later saving + if(shmima){ + size_t rsz = FLEN_CARD * ima.headerstrings; + memcpy(ima.fitsheader, shmima->fitsheader, rsz); + }else{ + uint8_t card[FLEN_CARD]; + for(size_t i = 0; i < ima.headerstrings; ++i){ + if(!readNbytes(imsock, FLEN_CARD, card)){ + WARNX("Can't read full header, got %zd records from %zd", i, ima.headerstrings); + break; + } + memcpy(&ima.fitsheader[i], card, FLEN_CARD); + } + } + if(GP->addhdr){ // add records from client-side files + char **nxtfile = GP->addhdr; + while(*nxtfile){ + cc_kwfromfile(&ima, *(nxtfile++)); + } + } + }else ima.headerstrings = 0; }else WARNX("Still got old image"); eofg: - if(!shmima) close(imsock); + if(imsock != -1) close(imsock); + if(shmlocked) unlock_shm(shmima); + return ret; } -static void *grabnext(void _U_ *arg){ // daemon grabbing images through the net +void client(int sock){ + if(GP->restart){ + SENDCMDW(CC_CMD_RESTART); + return; + } + TIMEINIT(); + send_headers(sock); + TIMESTAMP("Got headers"); + double t0 = sl_dtime(), tw = t0; + int Nremain = 0, nframe = 1; + // if client gives filename/prefix or Nframes, make exposition + if((GP->outfile && *GP->outfile) || (GP->outfileprefix && *GP->outfileprefix) || GP->nframes > 0){ + Nremain = GP->nframes; + if(Nremain < 1) Nremain = 1; + else GP->waitexpend = TRUE; // N>1 - wait for exp ends + SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); + }else{ + int cntr = 0; + while(sl_dtime() - t0 < CC_WAIT_TIMEOUT && cntr < 3) + if(!getans(sock, NULL)) ++cntr; + DBG("RETURN: no more data"); + return; + } + double timeout = GP->waitexpend ? CC_CLIENT_TIMEOUT : CC_WAIT_TIMEOUT; + verbose(1, "Exposing frame 1..."); + if(GP->waitexpend){ + atomic_store(&expstate, CAMERA_CAPTURE); // could be changed earlier + verbose(2, "Wait for exposition end"); + } + while(sl_dtime() - t0 < timeout){ + if(GP->waitexpend && sl_dtime() - tw > CC_WAIT_TIMEOUT){ + SENDCMDW(CC_CMD_TREMAIN); // get remained time + tw = sl_dtime(); + sprintf(sendbuf, "%s", CC_CMD_EXPSTATE); + cc_sendstrmessage(sock, sendbuf); + } + if(getans(sock, NULL)){ // got next portion of data + DBG("server message"); + t0 = sl_dtime(); + int curst = atomic_load(&expstate); + if(curst == CAMERA_ERROR){ + WARNX(_("Can't make exposition")); + if(Nremain > 1){ + verbose(1, "Exposing frame %d...", nframe); + SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); + } + continue; + } + //if(expstate != CAMERA_CAPTURE){ + if(curst == CAMERA_FRAMERDY){ + atomic_store(&expstate, CAMERA_IDLE); + if(Nremain > 1){ + verbose(1, "Exposing frame %d...", nframe+1); + SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); + } + verbose(2, "Frame ready, try to grab"); + int failed = TRUE; + if(!getimage(TRUE)){ + WARNX("Can't get next image"); + }else{ + if(saveFITS(&ima, &lastfilename)){ + --Nremain; + ++nframe; + failed = FALSE; + } + } + if(failed && Nremain == 1){ // last image -> should re-expose + verbose(1, "Exposing frame %d...", nframe); + SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); + } + if(Nremain > 0){ + if(GP->pause_len > 0){ + double delta, time1 = sl_dtime() + GP->pause_len; + while(1){ + SENDCMDW(CC_CMD_CAMTEMPER); + if((delta = time1 - sl_dtime()) < __FLT_EPSILON__) break; + if(delta > 1.) verbose(1, _("%d seconds till pause ends\n"), (int)delta); + if(delta > 6.) sleep(5); + else if(delta > 1.) sleep((int)delta); + else usleep((int)(delta*1e6 + 1)); + } + } + }else{ + GP->waitexpend = 0; + DBG("All images saved -> exit"); + break; + } + } + } + } + if(GP->waitexpend) WARNX(_("Server timeout")); +} + +#ifdef IMAGEVIEW +static int controlfd = -1; // control socket FD +void init_grab_sock(int sock){ + if(sock < 0) ERRX("Can't run without command socket"); + controlfd = sock; + send_headers(sock); + if(!GP->forceimsock && !shmima){ // init shm buffer if user don't ask to work through image socket + shmima = cc_getshm(GP->shmkey, 0); // try to init client shm + } +} + +// grab image for active viewer +static void *grabnext(void _U_ *arg){ FNAME(); if(controlfd < 0) return NULL; int sock = controlfd; while(1){ if(!getWin()) exit(1); TIMESTAMP("End of cycle, start new"); - expstate = CAMERA_CAPTURE; + atomic_store(&expstate, CAMERA_CAPTURE); TIMEINIT(); SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); // start capture double timeout = GP->exptime + CC_CLIENT_TIMEOUT, t0 = sl_dtime(); @@ -413,45 +463,45 @@ static void *grabnext(void _U_ *arg){ // daemon grabbing images through the net if(sleept < 1000) sleept = 1000; } // double exptime = GP->exptime; + TIMESTAMP("Wait for exposition ends (%g s)", timeout); while(sl_dtime() - t0 < timeout){ - TIMESTAMP("Wait for exposition ends (%u us)", sleept); usleep(sleept); - TIMESTAMP("check answer"); // getans(sock, NULL); //TIMESTAMP("EXPSTATE ===> %d", expstate); - if(expstate != CAMERA_CAPTURE) break; + if(atomic_load(&expstate) != CAMERA_CAPTURE) break; if(sl_dtime() - t0 < GP->exptime + 0.5) sleept = 1000; } - if(sl_dtime() - t0 >= timeout || expstate != CAMERA_FRAMERDY){ + if(sl_dtime() - t0 >= timeout || atomic_load(&expstate) != CAMERA_FRAMERDY){ WARNX("Image wasn't received"); continue; } TIMESTAMP("Frame ready"); - getimage(); + getimage(FALSE); } return NULL; } -static void *waitimage(void _U_ *arg){ // passive waiting for next image +// passive waiting for next image +static void *waitimage(void _U_ *arg){ FNAME(); if(controlfd < 0) return NULL; int sock = controlfd; while(1){ if(!getWin()) exit(1); getans(sock, NULL); - if(expstate != CAMERA_FRAMERDY){ + if(atomic_load(&expstate) != CAMERA_FRAMERDY){ usleep(1000); continue; } TIMESTAMP("End of cycle, start new"); TIMEINIT(); - getimage(); - expstate = CAMERA_IDLE; + getimage(FALSE); + atomic_store(&expstate, CAMERA_IDLE); } return NULL; } -// try to capture images through socket +// try to capture images for viewer int sockcaptured(cc_IMG **imgptr){ //TIMESTAMP("sockcaptured() start"); if(!imgptr) return FALSE; @@ -484,13 +534,12 @@ int sockcaptured(cc_IMG **imgptr){ } } }else{ // grab in process - if(grabno != oldgrabno){ // image is ready - TIMESTAMP("Image #%d ready", grabno); + int curno = atomic_load(&grabno); + if(curno != oldgrabno){ // image is ready + TIMESTAMP("Image #%d ready", curno); if(*imgptr && (*imgptr != &ima)) free(*imgptr); - *imgptr = &ima; /* - ssize_t delta = ima.imnumber - oldgrabno; - if(delta > 0 && delta != 1) WARNX("sockcaptured(): missed %zd images", delta-1);*/ - oldgrabno = grabno; + *imgptr = &ima; + oldgrabno = curno; framerate(); //TIMESTAMP("sockcaptured() end, return TRUE"); return TRUE; diff --git a/locale/ru/LC_MESSAGES/ccd_capture.mo b/locale/ru/LC_MESSAGES/ccd_capture.mo deleted file mode 100644 index 4d8772b7b25e1bd5010c06af0e0782f64318bdbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14991 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 z 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 BXuSXc diff --git a/locale/ru/messages.po b/locale/ru/messages.po deleted file mode 100644 index 945f3cf..0000000 --- a/locale/ru/messages.po +++ /dev/null @@ -1,594 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-18 15:56+0300\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=koi8-r\n" -"Content-Transfer-Encoding: 8bit\n" - -#: cmdlnopts.c:48 -msgid "common device plugin (e.g devfli.so)" -msgstr "" - -#: cmdlnopts.c:49 -msgid "custom camera device plugin command" -msgstr "" - -#: cmdlnopts.c:50 -msgid "camera device plugin (e.g. devfli.so)" -msgstr "" - -#: cmdlnopts.c:51 -msgid "focuser device plugin (e.g. devzwo.so)" -msgstr "" - -#: cmdlnopts.c:52 -msgid "wheel device plugin (e.g. devdummy.so)" -msgstr "" - -#: cmdlnopts.c:53 -msgid "list connected devices" -msgstr "" - -#: cmdlnopts.c:54 -msgid "camera device number (if many: 0, 1, 2 etc)" -msgstr "" - -#: cmdlnopts.c:55 -msgid "filter wheel device number (if many: 0, 1, 2 etc)" -msgstr "" - -#: cmdlnopts.c:56 -msgid "focuser device number (if many: 0, 1, 2 etc)" -msgstr "" - -#: cmdlnopts.c:57 -msgid "show this help" -msgstr "" - -#: cmdlnopts.c:58 -msgid "rewrite output file if exists" -msgstr "" - -#: cmdlnopts.c:59 -msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)" -msgstr "" - -#: cmdlnopts.c:60 -msgid "not open shutter, when exposing (\"dark frames\")" -msgstr "" - -#: cmdlnopts.c:61 -msgid "run in 8-bit mode" -msgstr "" - -#: cmdlnopts.c:62 -msgid "fast readout mode" -msgstr "" - -#: cmdlnopts.c:63 -msgid "set CCD temperature to given value (degr C)" -msgstr "" - -#: cmdlnopts.c:64 -msgid "set fan speed (0 - off, 1 - low, 2 - high)" -msgstr "" - -#: cmdlnopts.c:66 -msgid "program author" -msgstr "" - -#: cmdlnopts.c:67 -msgid "object type (neon, object, flat etc)" -msgstr "" - -#: cmdlnopts.c:68 -msgid "instrument name" -msgstr "" - -#: cmdlnopts.c:69 -msgid "object name" -msgstr "" - -#: cmdlnopts.c:70 -msgid "observers' names" -msgstr "" - -#: cmdlnopts.c:71 -msgid "observing program name" -msgstr "" - -#: cmdlnopts.c:72 -msgid "add records to header from given file[s]" -msgstr "" - -#: cmdlnopts.c:73 -msgid "output file name" -msgstr "" - -#: cmdlnopts.c:74 -msgid "wait while exposition ends" -msgstr "" - -#: cmdlnopts.c:76 -msgid "N flushes before exposing (default: 1)" -msgstr "" - -#: cmdlnopts.c:77 -msgid "horizontal binning to N pixels" -msgstr "" - -#: cmdlnopts.c:78 -msgid "vertical binning to N pixels" -msgstr "" - -#: cmdlnopts.c:79 -msgid "make series of N frames" -msgstr "" - -#: cmdlnopts.c:80 -msgid "make pause for N seconds between expositions" -msgstr "" - -#: cmdlnopts.c:81 -msgid "set exposure time to given value (seconds!)" -msgstr "" - -#: cmdlnopts.c:82 -msgid "cancel current exposition" -msgstr "" - -#: cmdlnopts.c:83 -msgid "" -"absolute (not divided by binning!) frame X0 coordinate (-1 - all with " -"overscan)" -msgstr "" - -#: cmdlnopts.c:84 -msgid "absolute frame Y0 coordinate (-1 - all with overscan)" -msgstr "" - -#: cmdlnopts.c:85 -msgid "absolute frame X1 coordinate (-1 - all with overscan)" -msgstr "" - -#: cmdlnopts.c:86 -msgid "absolute frame Y1 coordinate (-1 - all with overscan)" -msgstr "" - -#: cmdlnopts.c:88 -msgid "open shutter" -msgstr "" - -#: cmdlnopts.c:89 -msgid "close shutter" -msgstr "" - -#: cmdlnopts.c:90 -msgid "run exposition on LOW @ pin5 I/O port" -msgstr "" - -#: cmdlnopts.c:91 -msgid "run exposition on HIGH @ pin5 I/O port" -msgstr "" - -#: cmdlnopts.c:92 -msgid "get value of I/O port pins" -msgstr "" - -#: cmdlnopts.c:93 -msgid "move stepper motor asynchronous" -msgstr "" - -#: cmdlnopts.c:95 -msgid "set I/O port pins to given value (decimal number, pin1 is LSB)" -msgstr "" - -#: cmdlnopts.c:96 -msgid "" -"configure I/O port pins to given value (decimal number, pin1 is LSB, 1 == " -"output, 0 == input)" -msgstr "" - -#: cmdlnopts.c:98 -msgid "move focuser to absolute position, mm" -msgstr "" - -#: cmdlnopts.c:99 -msgid "move focuser to relative position, mm (only for standalone)" -msgstr "" - -#: cmdlnopts.c:101 -msgid "set wheel position" -msgstr "" - -#: cmdlnopts.c:103 -msgid "CMOS gain level" -msgstr "" - -#: cmdlnopts.c:104 -msgid "CMOS brightness level" -msgstr "" - -#: cmdlnopts.c:106 -msgid "logging file name (if run as server)" -msgstr "" - -#: cmdlnopts.c:107 -msgid "UNIX socket name (command socket)" -msgstr "" - -#: cmdlnopts.c:108 -msgid "local INET command socket port" -msgstr "" - -#: cmdlnopts.c:109 -msgid "INET image socket port" -msgstr "" - -#: cmdlnopts.c:110 -msgid "run as client" -msgstr "" - -#: cmdlnopts.c:111 -msgid "passive viewer (only get last images)" -msgstr "" - -#: cmdlnopts.c:112 -msgid "restart image server" -msgstr "" - -#: cmdlnopts.c:113 -msgid "network answer timeout (default: 0.1s)" -msgstr "" - -#: cmdlnopts.c:115 -msgid "shared memory (with image data) key (default: 7777777)" -msgstr "" - -#: cmdlnopts.c:116 -msgid "force using image through socket transition even if can use SHM" -msgstr "" - -#: cmdlnopts.c:117 -msgid "start (!=0) or stop(==0) infinity capturing loop" -msgstr "" - -#: cmdlnopts.c:120 -msgid "Display image in OpenGL window" -msgstr "" - -#: ccdfunc.c:198 -msgid "Camera device unknown" -msgstr "" - -#: ccdfunc.c:221 -#, c-format -msgid "Can't save file with prefix %s" -msgstr "" - -#: ccdfunc.c:269 -#, c-format -msgid "File saved as '%s'" -msgstr "" - -#: ccdfunc.c:278 -msgid "Error saving file" -msgstr "" - -#: ccdfunc.c:333 -#, c-format -msgid "Image stat:\n" -msgstr "" - -#: ccdfunc.c:342 -msgid "Focuser device not pointed" -msgstr "" - -#: ccdfunc.c:349 -msgid "No focusers found" -msgstr "" - -#: ccdfunc.c:379 -#, c-format -msgid "Found %d focusers, you point number %d" -msgstr "" - -#: ccdfunc.c:383 -msgid "Can't set active focuser number" -msgstr "" - -#: ccdfunc.c:397 -msgid "Can't get focuser limit positions" -msgstr "" - -#: ccdfunc.c:404 -msgid "Can't get current focuser position" -msgstr "" - -#: ccdfunc.c:418 -#, c-format -msgid "Can't set position %g: out of limits [%g, %g]" -msgstr "" - -#: ccdfunc.c:422 -msgid "Can't home focuser" -msgstr "" - -#: ccdfunc.c:424 -#, c-format -msgid "Can't set position %g" -msgstr "" - -#: ccdfunc.c:430 -msgid "Wheel device not pointed" -msgstr "" - -#: ccdfunc.c:437 -msgid "No wheels found" -msgstr "" - -#: ccdfunc.c:467 -#, c-format -msgid "Found %d wheels, you point number %d" -msgstr "" - -#: ccdfunc.c:471 -msgid "Can't set active wheel number" -msgstr "" - -#: ccdfunc.c:487 -msgid "Can't get max wheel position" -msgstr "" - -#: ccdfunc.c:494 -#, c-format -msgid "Wheel position should be from 0 to %d" -msgstr "" - -#: ccdfunc.c:498 -#, c-format -msgid "Can't set wheel position %d" -msgstr "" - -#: ccdfunc.c:511 -msgid "Camera plugin have no capture polling funtion." -msgstr "" - -#: ccdfunc.c:517 -#, c-format -msgid "%.1f seconds till exposition ends" -msgstr "" - -#: ccdfunc.c:532 -msgid "Camera device not pointed" -msgstr "" - -#: ccdfunc.c:539 ccdfunc.c:540 -msgid "No cameras found" -msgstr "" - -#: ccdfunc.c:560 -msgid "Camera plugin have no model name getter" -msgstr "" - -#: ccdfunc.c:571 -#, c-format -msgid "Found %d cameras, you point number %d" -msgstr "" - -#: ccdfunc.c:575 -msgid "Can't set active camera number" -msgstr "" - -#: ccdfunc.c:581 -msgid "Camera plugin have no custom commands" -msgstr "" - -#: ccdfunc.c:606 -msgid "Camera plugin have no fun speed setter" -msgstr "" - -#: ccdfunc.c:609 -msgid "Can't set fan speed" -msgstr "" - -#: ccdfunc.c:610 -#, c-format -msgid "Set fan speed to %d" -msgstr "" - -#: ccdfunc.c:615 -#, c-format -msgid "Camera model: %s" -msgstr "" - -#: ccdfunc.c:616 -#, c-format -msgid "Pixel size: %g x %g" -msgstr "" - -#: ccdfunc.c:622 -#, c-format -msgid "Full array: %s" -msgstr "" - -#: ccdfunc.c:625 -#, c-format -msgid "Field of view: %s" -msgstr "" - -#: ccdfunc.c:628 -#, c-format -msgid "Current format: %s" -msgstr "" - -#: ccdfunc.c:630 -msgid "Camera plugin have no temperature setter" -msgstr "" - -#: ccdfunc.c:631 -#, c-format -msgid "Can't set T to %g degC" -msgstr "" - -#: ccdfunc.c:640 -#, c-format -msgid "Shutter command: %s\n" -msgstr "" - -#: ccdfunc.c:642 -#, c-format -msgid "Can't run shutter command %s (unsupported?)" -msgstr "" - -#: ccdfunc.c:645 -#, c-format -msgid "Try to configure I/O port as %d" -msgstr "" - -#: ccdfunc.c:647 -msgid "Can't configure (unsupported?)" -msgstr "" - -#: ccdfunc.c:654 -msgid "Can't get IOport state (unsupported?)" -msgstr "" - -#: ccdfunc.c:657 -#, c-format -msgid "Try to write %d to I/O port" -msgstr "" - -#: ccdfunc.c:659 -msgid "Can't set IOport" -msgstr "" - -#: ccdfunc.c:666 -#, c-format -msgid "Set gain to %g" -msgstr "" - -#: ccdfunc.c:667 -#, c-format -msgid "Can't set gain to %g" -msgstr "" - -#: ccdfunc.c:672 -#, c-format -msgid "Set brightness to %g" -msgstr "" - -#: ccdfunc.c:673 -#, c-format -msgid "Can't set brightness to %g" -msgstr "" - -#: ccdfunc.c:679 server.c:284 -#, c-format -msgid "Can't set binning %dx%d" -msgstr "" - -#: ccdfunc.c:691 server.c:285 -msgid "Can't set given geometry" -msgstr "" - -#: ccdfunc.c:695 -#, c-format -msgid "Can't set %d flushes" -msgstr "" - -#: ccdfunc.c:698 -msgid "Camera plugin have no exposition setter" -msgstr "" - -#: ccdfunc.c:700 -#, c-format -msgid "Can't set exposure time to %f seconds" -msgstr "" - -#: ccdfunc.c:703 -msgid "Can't change frame type" -msgstr "" - -#: ccdfunc.c:706 -msgid "Can't set bit depth" -msgstr "" - -#: ccdfunc.c:708 -msgid "Can't set readout speed" -msgstr "" - -#: ccdfunc.c:709 -#, c-format -msgid "Readout mode: %s" -msgstr "" - -#: ccdfunc.c:710 -msgid "Only show statistics" -msgstr "" - -#: ccdfunc.c:713 -msgid "Can't get current binning" -msgstr "" - -#: ccdfunc.c:738 -#, c-format -msgid "Capture frame %d" -msgstr "" - -#: ccdfunc.c:739 ccdfunc.c:816 server.c:153 server.c:154 -msgid "Camera plugin have no function `start exposition`" -msgstr "" - -#: ccdfunc.c:741 ccdfunc.c:818 server.c:159 server.c:160 -msgid "Can't start exposition" -msgstr "" - -#: ccdfunc.c:746 -msgid "Can't capture image" -msgstr "" - -#: ccdfunc.c:749 -msgid "Read grabbed image" -msgstr "" - -#: ccdfunc.c:751 ccdfunc.c:831 server.c:177 server.c:178 -msgid "Camera plugin have no function `capture`" -msgstr "" - -#: ccdfunc.c:753 ccdfunc.c:832 -msgid "Can't grab image" -msgstr "" - -#: ccdfunc.c:767 client.c:289 -#, c-format -msgid "%d seconds till pause ends\n" -msgstr "" - -#: ccdfunc.c:829 -msgid "Some error when capture" -msgstr "" - -#: server.c:205 -msgid "No camera device" -msgstr "" - -#: client.c:275 -msgid "Can't make exposition" -msgstr "" - -#: client.c:305 -msgid "Server timeout" -msgstr "" diff --git a/locale/ru/ru.po b/locale/ru/ru.po deleted file mode 100644 index 2ee6724..0000000 --- a/locale/ru/ru.po +++ /dev/null @@ -1,625 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "Project-Id-Version: PACKAGE VERSION\n" - "Report-Msgid-Bugs-To: \n" - "POT-Creation-Date: 2026-04-18 15:55+0300\n" - "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" - "Last-Translator: FULL NAME \n" - "Language-Team: LANGUAGE \n" - "Language: \n" - "MIME-Version: 1.0\n" - "Content-Type: text/plain; charset=koi8-r\n" - "Content-Transfer-Encoding: 8bit\n" - -#: ccdfunc.c:517 -#, c-format -msgid "%.1f seconds till exposition ends" -msgstr "%.1f секунд до окончания экспозиции" - -#: ccdfunc.c:767 client.c:289 -#, c-format -msgid "%d seconds till pause ends\n" -msgstr "%d секунд до окончания паузы\n" - -#: cmdlnopts.c:104 -msgid "CMOS brightness level" -msgstr "уровень яркости CMOS" - -#: cmdlnopts.c:103 -msgid "CMOS gain level" -msgstr "уровень Gain CMOS" - -#: ccdfunc.c:532 -msgid "Camera device not pointed" -msgstr "Устройство свеоприемника не подключено" - -#: ccdfunc.c:198 -msgid "Camera device unknown" -msgstr "Устройство свеоприемника не опознано" - -#: ccdfunc.c:615 -#, c-format -msgid "Camera model: %s" -msgstr "Модель светоприемника: %s" - -#: ccdfunc.c:511 -#, fuzzy -msgid "Camera plugin have no capture polling funtion." -msgstr "У плагина камеры нет особых команд" - -#: ccdfunc.c:581 -msgid "Camera plugin have no custom commands" -msgstr "У плагина камеры нет особых команд" - -#: ccdfunc.c:698 -#, fuzzy -msgid "Camera plugin have no exposition setter" -msgstr "У плагина камеры нет особых команд" - -#: ccdfunc.c:606 -#, fuzzy -msgid "Camera plugin have no fun speed setter" -msgstr "У плагина камеры нет особых команд" - -#: ccdfunc.c:751 ccdfunc.c:831 server.c:177 server.c:178 -#, fuzzy -msgid "Camera plugin have no function `capture`" -msgstr "У плагина камеры нет особых команд" - -#: ccdfunc.c:739 ccdfunc.c:816 server.c:153 server.c:154 -#, fuzzy -msgid "Camera plugin have no function `start exposition`" -msgstr "У плагина камеры нет особых команд" - -#: ccdfunc.c:560 -#, fuzzy -msgid "Camera plugin have no model name getter" -msgstr "У плагина камеры нет особых команд" - -#: ccdfunc.c:630 -#, fuzzy -msgid "Camera plugin have no temperature setter" -msgstr "У плагина камеры нет особых команд" - -#: ccdfunc.c:746 -msgid "Can't capture image" -msgstr "Не могу захватить изображение" - -#: ccdfunc.c:703 -msgid "Can't change frame type" -msgstr "Не могу изменить тип кадра" - -#: ccdfunc.c:647 -msgid "Can't configure (unsupported?)" -msgstr "Не могу сконфигурировать (опция не поддерживается?)" - -#: ccdfunc.c:654 -msgid "Can't get IOport state (unsupported?)" -msgstr "Не могу получить состояние порта I/O (не поддерживается?)" - -#: ccdfunc.c:713 -msgid "Can't get current binning" -msgstr "Не могу получить текущее значение биннинга" - -#: ccdfunc.c:404 -msgid "Can't get current focuser position" -msgstr "Не могу определить текущую позицию фокусера" - -#: ccdfunc.c:397 -msgid "Can't get focuser limit positions" -msgstr "Не могу определить предельную позицию фокусера" - -#: ccdfunc.c:487 -msgid "Can't get max wheel position" -msgstr "Не могу определить предельную позицию колеса" - -#: ccdfunc.c:753 ccdfunc.c:832 -msgid "Can't grab image" -msgstr "Не могу захватить изображение" - -#: ccdfunc.c:422 -msgid "Can't home focuser" -msgstr "Не могу установить фокусер в нуль" - -#: client.c:275 -msgid "Can't make exposition" -msgstr "Не могу выполнить экспозицию" - -#: ccdfunc.c:642 -#, c-format -msgid "Can't run shutter command %s (unsupported?)" -msgstr "Не могу выполнить команду затвора %s (не поддерживается?)" - -#: ccdfunc.c:221 -#, c-format -msgid "Can't save file with prefix %s" -msgstr "Не могу сохранить файл с префиксом %s" - -#: ccdfunc.c:695 -#, c-format -msgid "Can't set %d flushes" -msgstr "Не могу установить %d сбросов" - -#: ccdfunc.c:659 -msgid "Can't set IOport" -msgstr "Не могу поменять значения порта I/O" - -#: ccdfunc.c:631 -#, c-format -msgid "Can't set T to %g degC" -msgstr "Не могу установить температуру в %g градЦ" - -#: ccdfunc.c:575 -msgid "Can't set active camera number" -msgstr "Не могу установить номер активной камеры" - -#: ccdfunc.c:383 -msgid "Can't set active focuser number" -msgstr "Не могу установить номер активного фокусера" - -#: ccdfunc.c:471 -msgid "Can't set active wheel number" -msgstr "Не могу установить номер активного колеса" - -#: ccdfunc.c:679 server.c:284 -#, c-format -msgid "Can't set binning %dx%d" -msgstr "Не могу установить биннинг %dx%d" - -#: ccdfunc.c:706 -msgid "Can't set bit depth" -msgstr "Не могу установить разрядность АЦП" - -#: ccdfunc.c:673 -#, c-format -msgid "Can't set brightness to %g" -msgstr "Не могу установить яркость в %g" - -#: ccdfunc.c:700 -#, c-format -msgid "Can't set exposure time to %f seconds" -msgstr "Не могу установить экспозицию в %f секунд" - -#: ccdfunc.c:609 -msgid "Can't set fan speed" -msgstr "Не могу установить скорость вентиляторов" - -#: ccdfunc.c:667 -#, c-format -msgid "Can't set gain to %g" -msgstr "Не могу установить Gain в %g" - -#: ccdfunc.c:691 server.c:285 -msgid "Can't set given geometry" -msgstr "Не могу установить геометрию" - -#: ccdfunc.c:424 -#, c-format -msgid "Can't set position %g" -msgstr "Не могу изменить позицию на %g" - -#: ccdfunc.c:418 -#, c-format -msgid "Can't set position %g: out of limits [%g, %g]" -msgstr "Не могу установить позицию %g: вне пределов [%g, %g]" - -#: ccdfunc.c:708 -msgid "Can't set readout speed" -msgstr "Не могу установить скорость считывания" - -#: ccdfunc.c:498 -#, c-format -msgid "Can't set wheel position %d" -msgstr "Не могу установить положение колеса %d" - -#: ccdfunc.c:741 ccdfunc.c:818 server.c:159 server.c:160 -msgid "Can't start exposition" -msgstr "Не могу начать экспозицию" - -#: ccdfunc.c:738 -#, c-format -msgid "Capture frame %d" -msgstr "Захват кадра %d" - -#: ccdfunc.c:628 -#, c-format -msgid "Current format: %s" -msgstr "Текущий формат: %s" - -#: cmdlnopts.c:120 -msgid "Display image in OpenGL window" -msgstr "отображение изображения в окне OpenGL" - -#: ccdfunc.c:278 -msgid "Error saving file" -msgstr "Ошибка сохранения файла" - -#: ccdfunc.c:625 -#, c-format -msgid "Field of view: %s" -msgstr "Поле зрения: %s" - -#: ccdfunc.c:269 -#, c-format -msgid "File saved as '%s'" -msgstr "Файл сохранен как '%s'" - -#: ccdfunc.c:342 -msgid "Focuser device not pointed" -msgstr "Устройство фокусера не указано" - -#: ccdfunc.c:571 -#, c-format -msgid "Found %d cameras, you point number %d" -msgstr "Обнаружено %d камер, вы указали %d" - -#: ccdfunc.c:379 -#, c-format -msgid "Found %d focusers, you point number %d" -msgstr "Обнаружено %d фокусеров, вы указали %d" - -#: ccdfunc.c:467 -#, c-format -msgid "Found %d wheels, you point number %d" -msgstr "Обнаружено %d колес, вы указали %d" - -#: ccdfunc.c:622 -#, c-format -msgid "Full array: %s" -msgstr "Полный формат: %s" - -#: cmdlnopts.c:109 -msgid "INET image socket port" -msgstr "порт локального сетевого сокета передачи изображения" - -#: ccdfunc.c:333 -#, c-format -msgid "Image stat:\n" -msgstr "Статистика по изображению: \n" - -#: cmdlnopts.c:76 -msgid "N flushes before exposing (default: 1)" -msgstr "N засвечиваний перед экспозицией (по умолчанию: 1)" - -#: server.c:205 -msgid "No camera device" -msgstr "Не указано устройство камеры" - -#: ccdfunc.c:539 ccdfunc.c:540 -msgid "No cameras found" -msgstr "Камер не обнаружено" - -#: ccdfunc.c:349 -msgid "No focusers found" -msgstr "Фокусеров не обнаружено" - -#: ccdfunc.c:437 -msgid "No wheels found" -msgstr "Турелей не обнаружено" - -#: ccdfunc.c:710 -msgid "Only show statistics" -msgstr "Только отобразить статистику" - -#: ccdfunc.c:616 -#, c-format -msgid "Pixel size: %g x %g" -msgstr "Размер пикселя: %g x %g" - -#: ccdfunc.c:749 -msgid "Read grabbed image" -msgstr "Считывание изображения" - -#: ccdfunc.c:709 -#, c-format -msgid "Readout mode: %s" -msgstr "Режим считывания: %s" - -#: client.c:305 -msgid "Server timeout" -msgstr "Таймаут сервера" - -#: ccdfunc.c:672 -#, c-format -msgid "Set brightness to %g" -msgstr "Установить яркость в %g" - -#: ccdfunc.c:610 -#, c-format -msgid "Set fan speed to %d" -msgstr "Не могу установить скорость вентиляторов в %d" - -#: ccdfunc.c:666 -#, c-format -msgid "Set gain to %g" -msgstr "Установить Gain в %g" - -#: ccdfunc.c:640 -#, c-format -msgid "Shutter command: %s\n" -msgstr "Команда затвора: %s\n" - -#: ccdfunc.c:829 -msgid "Some error when capture" -msgstr "Ошибка при захвате" - -#: ccdfunc.c:645 -#, c-format -msgid "Try to configure I/O port as %d" -msgstr "Попытка сконфигурировать порт I/O как %d" - -#: ccdfunc.c:657 -#, c-format -msgid "Try to write %d to I/O port" -msgstr "Попытка записи %d в порт I/O" - -#: cmdlnopts.c:107 -msgid "UNIX socket name (command socket)" -msgstr "имя UNIX-сокета" - -#: ccdfunc.c:430 -msgid "Wheel device not pointed" -msgstr "Устройство турели не указано" - -#: ccdfunc.c:494 -#, c-format -msgid "Wheel position should be from 0 to %d" -msgstr "Позиция колеса должна быть от 0 до %d" - -#: cmdlnopts.c:83 -msgid "absolute (not divided by binning!) frame X0 coordinate (-1 - all " - "with overscan)" -msgstr "абсолютная (не деленная на биннинг!) координата X0 (-1 - включая " - "оверскан)" - -#: cmdlnopts.c:85 -msgid "absolute frame X1 coordinate (-1 - all with overscan)" -msgstr "абсолютная координата X1 (-1 - включая оверскан)" - -#: cmdlnopts.c:84 -msgid "absolute frame Y0 coordinate (-1 - all with overscan)" -msgstr "абсолютная координата Y0 (-1 - включая оверскан)" - -#: cmdlnopts.c:86 -msgid "absolute frame Y1 coordinate (-1 - all with overscan)" -msgstr "абсолютная координата Y1 (-1 - включая оверскан)" - -#: cmdlnopts.c:72 -msgid "add records to header from given file[s]" -msgstr "добавить записи к шапке FITS-файла из заданных файлов" - -#: cmdlnopts.c:54 -msgid "camera device number (if many: 0, 1, 2 etc)" -msgstr "номер устройства камеры" - -#: cmdlnopts.c:50 -msgid "camera device plugin (e.g. devfli.so)" -msgstr "плагин камеры (например, devfli.so)" - -#: cmdlnopts.c:82 -msgid "cancel current exposition" -msgstr "отмена текущей экспозиции" - -#: cmdlnopts.c:89 -msgid "close shutter" -msgstr "закрыть затвор" - -#: cmdlnopts.c:48 -msgid "common device plugin (e.g devfli.so)" -msgstr "общий плагин для всех устройств (например, devfli.so)" - -#: cmdlnopts.c:96 -msgid "configure I/O port pins to given value (decimal number, pin1 is LSB, " - "1 == output, 0 == input)" -msgstr "сконфигурировать порт I/O в заданное состояние (десятичное число, " - "pin1 - младший бит, 1 - выход, 0 - вход)" - -#: cmdlnopts.c:49 -msgid "custom camera device plugin command" -msgstr "особые команды плагина камеры" - -#: cmdlnopts.c:62 -msgid "fast readout mode" -msgstr "быстрый режим считывания" - -#: cmdlnopts.c:55 -msgid "filter wheel device number (if many: 0, 1, 2 etc)" -msgstr "номер устройства турели" - -#: cmdlnopts.c:56 -msgid "focuser device number (if many: 0, 1, 2 etc)" -msgstr "номер устройства фокусера" - -#: cmdlnopts.c:51 -msgid "focuser device plugin (e.g. devzwo.so)" -msgstr "плагин фокусера (например, devzwo.so)" - -#: cmdlnopts.c:116 -msgid "force using image through socket transition even if can use SHM" -msgstr "принудительно брать изображения из сокета даже если возможно " - "пользоваться разделяемой памятью" - -#: cmdlnopts.c:92 -msgid "get value of I/O port pins" -msgstr "получить значение порта I/O" - -#: cmdlnopts.c:77 -msgid "horizontal binning to N pixels" -msgstr "горизонтальный биннинг в N пикселей" - -#: cmdlnopts.c:68 -msgid "instrument name" -msgstr "название прибора" - -#: cmdlnopts.c:53 -msgid "list connected devices" -msgstr "список подключенных устройств" - -#: cmdlnopts.c:108 -msgid "local INET command socket port" -msgstr "порт локального сетевого сокета" - -#: cmdlnopts.c:106 -msgid "logging file name (if run as server)" -msgstr "имя файла логгирования (если запущен сервер)" - -#: cmdlnopts.c:80 -msgid "make pause for N seconds between expositions" -msgstr "пауза в N секунд между экспозициями" - -#: cmdlnopts.c:79 -msgid "make series of N frames" -msgstr "последовательность из N кадров" - -#: cmdlnopts.c:98 -msgid "move focuser to absolute position, mm" -msgstr "переместить фокусер в абсолютное положение, мм" - -#: cmdlnopts.c:99 -msgid "move focuser to relative position, mm (only for standalone)" -msgstr "переместить фокусер в относительное положение, мм (не для сервер/" - "клиент)" - -#: cmdlnopts.c:93 -msgid "move stepper motor asynchronous" -msgstr "асинхронное движение шагового двигателя" - -#: cmdlnopts.c:113 -msgid "network answer timeout (default: 0.1s)" -msgstr "" - -#: cmdlnopts.c:60 -msgid "not open shutter, when exposing (\"dark frames\")" -msgstr "не открывать затвор при экспозиции (\"темновые\")" - -#: cmdlnopts.c:69 -msgid "object name" -msgstr "название объекта" - -#: cmdlnopts.c:67 -msgid "object type (neon, object, flat etc)" -msgstr "тип объекта (neon, object, flat и т.д.)" - -#: cmdlnopts.c:70 -msgid "observers' names" -msgstr "имена наблюдателей" - -#: cmdlnopts.c:71 -msgid "observing program name" -msgstr "название программы" - -#: cmdlnopts.c:88 -msgid "open shutter" -msgstr "открыть затвор" - -#: cmdlnopts.c:73 -msgid "output file name" -msgstr "имя файла" - -#: cmdlnopts.c:111 -msgid "passive viewer (only get last images)" -msgstr "пассивный просмотр (только последние кадры)" - -#: cmdlnopts.c:66 -msgid "program author" -msgstr "автор программы" - -#: cmdlnopts.c:112 -msgid "restart image server" -msgstr "перезапуск сервера" - -#: cmdlnopts.c:58 -msgid "rewrite output file if exists" -msgstr "перезапись выходного файла" - -#: cmdlnopts.c:110 -msgid "run as client" -msgstr "запустить клиент" - -#: cmdlnopts.c:91 -msgid "run exposition on HIGH @ pin5 I/O port" -msgstr "запуск экспозиции по ВЫСОКОМУ сигналу на контакте 5 порта I/O" - -#: cmdlnopts.c:90 -msgid "run exposition on LOW @ pin5 I/O port" -msgstr "запуск экспозиции по НИЗКОМУ сигналу на контакте 5 порта I/O" - -#: cmdlnopts.c:61 -msgid "run in 8-bit mode" -msgstr "8-битный режим" - -#: cmdlnopts.c:63 -msgid "set CCD temperature to given value (degr C)" -msgstr "установить температуру светоприемника (градЦ)" - -#: cmdlnopts.c:95 -msgid "set I/O port pins to given value (decimal number, pin1 is LSB)" -msgstr "установить порт I/O (десятичное число, pin1 - младший бит)" - -#: cmdlnopts.c:81 -msgid "set exposure time to given value (seconds!)" -msgstr "установить время экспозиции (секунды!)" - -#: cmdlnopts.c:64 -msgid "set fan speed (0 - off, 1 - low, 2 - high)" -msgstr "установить скорость вентилятора (0 - выкл, 1 - низкая, 2 - высокая)" - -#: cmdlnopts.c:101 -msgid "set wheel position" -msgstr "установить положение колеса" - -#: cmdlnopts.c:115 -msgid "shared memory (with image data) key (default: 7777777)" -msgstr "ключ разделяемой памяти с данными изображения (по умолчанию: 7777777)" - -#: cmdlnopts.c:57 -msgid "show this help" -msgstr "отобразить эту справку" - -#: cmdlnopts.c:117 -msgid "start (!=0) or stop(==0) infinity capturing loop" -msgstr "начать (!=0) или закончить (==0) бесконечный цикл захвата изображений" - -#: cmdlnopts.c:59 -msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)" -msgstr "уровень болтливости (-V - сообщения, -VV - отладка, -VVV - все)" - -#: cmdlnopts.c:78 -msgid "vertical binning to N pixels" -msgstr "вертикальный биннинг в N пикселей" - -#: cmdlnopts.c:74 -msgid "wait while exposition ends" -msgstr "ждать, пока не кончится экспозиция" - -#: cmdlnopts.c:52 -msgid "wheel device plugin (e.g. devdummy.so)" -msgstr "плагин устройства турели (например, devdummy.so)" - -#~ msgid "Already initialized!" -#~ msgstr "Уже инициализировано!" - -#~ msgid "Can't init mutex!" -#~ msgstr "Не могу инициализировать мьютекс!" - -#~ msgid "Can't open OpenGL window, image preview will be inaccessible" -#~ msgstr "Не могу открыть окно OpenGL, отображение будет недоступно" - -#, c-format -#~ msgid "Equalization of histogram: %s" -#~ msgstr "Эквализация гистограммы: %s" - -#, c-format -#~ msgid "Histogram conversion: %s" -#~ msgstr "Преобразование гистограммы: %s" - -#~ msgid "off" -#~ msgstr "выкл" - -#~ msgid "on" -#~ msgstr "вкл" diff --git a/locale/ru/ru.po.bkp b/locale/ru/ru.po.bkp deleted file mode 100644 index 8b70e75..0000000 --- a/locale/ru/ru.po.bkp +++ /dev/null @@ -1,586 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "Project-Id-Version: PACKAGE VERSION\n" - "Report-Msgid-Bugs-To: \n" - "POT-Creation-Date: 2022-04-18 16:50+0300\n" - "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" - "Last-Translator: FULL NAME \n" - "Language-Team: LANGUAGE \n" - "Language: \n" - "MIME-Version: 1.0\n" - "Content-Type: text/plain; charset=koi8-r\n" - "Content-Transfer-Encoding: 8bit\n" - -#: ccdfunc.c:570 -#, c-format -msgid "%.1f seconds till exposition ends" -msgstr "%.1f секунд до окончания экспозиции" - -#. %d секунд до окончания паузы\n -#: ccdfunc.c:805 client.c:260 -#, c-format -msgid "%d seconds till pause ends\n" -msgstr "%d секунд до окончания паузы\n" - -#: imageview.c:282 -msgid "Already initialized!" -msgstr "Уже инициализировано!" - -#: cmdlnopts.c:97 -msgid "CMOS brightness level" -msgstr "уровень яркости CMOS" - -#: cmdlnopts.c:96 -msgid "CMOS gain level" -msgstr "уровень Gain CMOS" - -#: ccdfunc.c:584 -msgid "Camera device not pointed" -msgstr "Устройство свеоприемника не подключено" - -#: ccdfunc.c:155 -msgid "Camera device unknown" -msgstr "Устройство свеоприемника не опознано" - -#: ccdfunc.c:643 -#, c-format -msgid "Camera model: %s" -msgstr "Модель светоприемника: %s" - -#: ccdfunc.c:762 ccdfunc.c:784 ccdfunc.c:825 -msgid "Can't capture image" -msgstr "Не могу захватить изображение" - -#: ccdfunc.c:726 -msgid "Can't change frame type" -msgstr "Не могу изменить тип кадра" - -#: ccdfunc.c:671 -msgid "Can't configure (unsupported?)" -msgstr "Не могу сконфигурировать (опция не поддерживается?)" - -#: ccdfunc.c:86 -#, c-format -msgid "Can't find camera in plugin %s: %s" -msgstr "Не могу найти плагин камеры %s: %s" - -#: ccdfunc.c:75 -#, c-format -msgid "Can't find focuser in plugin %s: %s" -msgstr "Не могу найти плагин фокусера %s: %s" - -#: ccdfunc.c:63 -#, c-format -msgid "Can't find plugin %s: %s" -msgstr "Не могу найти плагин %s: %s" - -#: ccdfunc.c:97 -#, c-format -msgid "Can't find wheel in plugin %s: %s" -msgstr "Не могу найти плагин турели %s: %s" - -#: ccdfunc.c:677 -msgid "Can't get IOport state (unsupported?)" -msgstr "Не могу получить состояние порта I/O (не поддерживается?)" - -#. GET binning should be AFTER setgeometry! -#: ccdfunc.c:735 -msgid "Can't get current binning" -msgstr "Не могу получить текущее значение биннинга" - -#: ccdfunc.c:455 -msgid "Can't get current focuser position" -msgstr "Не могу определить текущую позицию фокусера" - -#: ccdfunc.c:448 -msgid "Can't get focuser limit positions" -msgstr "Не могу определить предельную позицию фокусера" - -#: ccdfunc.c:542 -msgid "Can't get max wheel position" -msgstr "Не могу определить предельную позицию колеса" - -#: ccdfunc.c:768 ccdfunc.c:788 ccdfunc.c:829 -msgid "Can't grab image" -msgstr "Не могу захватить изображение" - -#: ccdfunc.c:473 -msgid "Can't home focuser" -msgstr "Не могу установить фокусер в нуль" - -#: imageview.c:264 -msgid "Can't init mutex!" -msgstr "Не могу инициализировать мьютекс!" - -#: client.c:247 -msgid "Can't make exposition" -msgstr "Не могу выполнить экспозицию" - -#: ccdfunc.c:748 -msgid "Can't open OpenGL window, image preview will be inaccessible" -msgstr "Не могу открыть окно OpenGL, отображение будет недоступно" - -#: ccdfunc.c:665 -#, c-format -msgid "Can't run shutter command %s (unsupported?)" -msgstr "Не могу выполнить команду затвора %s (не поддерживается?)" - -#. Не могу сохранить файл -#: ccdfunc.c:180 -#, c-format -msgid "Can't save file with prefix %s" -msgstr "Не могу сохранить файл с префиксом %s" - -#: ccdfunc.c:719 -#, c-format -msgid "Can't set %d flushes" -msgstr "Не могу установить %d сбросов" - -#: ccdfunc.c:683 -msgid "Can't set IOport" -msgstr "Не могу поменять значения порта I/O" - -#: ccdfunc.c:656 -#, c-format -msgid "Can't set T to %g degC" -msgstr "Не могу установить температуру в %g градЦ" - -#: ccdfunc.c:631 -msgid "Can't set active camera number" -msgstr "Не могу установить номер активной камеры" - -#: ccdfunc.c:434 -msgid "Can't set active focuser number" -msgstr "Не могу установить номер активного фокусера" - -#: ccdfunc.c:526 -msgid "Can't set active wheel number" -msgstr "Не могу установить номер активного колеса" - -#: ccdfunc.c:705 server.c:223 -#, c-format -msgid "Can't set binning %dx%d" -msgstr "Не могу установить биннинг %dx%d" - -#: ccdfunc.c:729 -msgid "Can't set bit depth" -msgstr "Не могу установить разрядность АЦП" - -#: ccdfunc.c:697 -#, c-format -msgid "Can't set brightness to %g" -msgstr "Не могу установить яркость в %g" - -#: ccdfunc.c:723 -#, c-format -msgid "Can't set exposure time to %f seconds" -msgstr "Не могу установить экспозицию в %f секунд" - -#: ccdfunc.c:637 -msgid "Can't set fan speed" -msgstr "Не могу установить скорость вентиляторов" - -#: ccdfunc.c:691 -#, c-format -msgid "Can't set gain to %g" -msgstr "Не могу установить Gain в %g" - -#: ccdfunc.c:715 server.c:224 -msgid "Can't set given geometry" -msgstr "Не могу установить геометрию" - -#: ccdfunc.c:475 -#, c-format -msgid "Can't set position %g" -msgstr "Не могу изменить позицию на %g" - -#: ccdfunc.c:469 -#, c-format -msgid "Can't set position %g: out of limits [%g, %g]" -msgstr "Не могу установить позицию %g: вне пределов [%g, %g]" - -#: ccdfunc.c:731 -msgid "Can't set readout speed" -msgstr "Не могу установить скорость считывания" - -#: ccdfunc.c:553 -#, c-format -msgid "Can't set wheel position %d" -msgstr "Не могу установить положение колеса %d" - -#: ccdfunc.c:758 server.c:121 -msgid "Can't start exposition" -msgstr "Не могу начать экспозицию" - -#. Захват кадра %d\n -#: ccdfunc.c:756 -#, c-format -msgid "Capture frame %d" -msgstr "Захват кадра %d" - -#: cmdlnopts.c:107 -msgid "Display image in OpenGL window" -msgstr "Отображение изображения в окне OpenGL" - -#: imageview.c:517 -#, c-format -msgid "Equalization of histogram: %s" -msgstr "Эквализация гистограммы: %s" - -#: ccdfunc.c:343 -msgid "Error saving file" -msgstr "Ошибка сохранения файла" - -#: ccdfunc.c:653 -#, c-format -msgid "Field of view: %s" -msgstr "Поле зрения: %s" - -#: ccdfunc.c:334 -#, c-format -msgid "File saved as '%s'" -msgstr "Файл сохранен как '%s'" - -#: ccdfunc.c:391 -msgid "Focuser device not pointed" -msgstr "Устройство фокусера не указано" - -#: ccdfunc.c:627 -#, c-format -msgid "Found %d cameras, you point number %d" -msgstr "Обнаружено %d камер, вы указали %d" - -#: ccdfunc.c:430 -#, c-format -msgid "Found %d focusers, you point number %d" -msgstr "Обнаружено %d фокусеров, вы указали %d" - -#: ccdfunc.c:522 -#, c-format -msgid "Found %d wheels, you point number %d" -msgstr "Обнаружено %d колес, вы указали %d" - -#: ccdfunc.c:650 -#, c-format -msgid "Full array: %s" -msgstr "Полный формат: %s" - -#: imageview.c:408 -#, c-format -msgid "Histogram conversion: %s" -msgstr "Преобразование гистограммы: %s" - -#: ccdfunc.c:383 -#, c-format -msgid "Image stat:\n" -msgstr "Статистика по изображению: \n" - -#: cmdlnopts.c:69 -msgid "N flushes before exposing (default: 1)" -msgstr "N засвечиваний перед экспозицией (по умолчанию: 1)" - -#: ccdfunc.c:161 -msgid "Neither filename nor filename prefix pointed!" -msgstr "Ни имя файла, ни префикс не указаны!" - -#: server.c:163 -msgid "No camera device" -msgstr "Не указано устройство камеры" - -#: ccdfunc.c:591 ccdfunc.c:592 -msgid "No cameras found" -msgstr "Камер не обнаружено" - -#: ccdfunc.c:398 -msgid "No focusers found" -msgstr "Фокусеров не обнаружено" - -#: ccdfunc.c:490 -msgid "No wheels found" -msgstr "Турелей не обнаружено" - -#: ccdfunc.c:733 -msgid "Only show statistics" -msgstr "Только отобразить статистику" - -#: cmdlnopts.c:103 -msgid "PID file (default: " -msgstr "PID-файл (по умолчанию: " - -#: ccdfunc.c:644 -#, c-format -msgid "Pixel size: %g x %g" -msgstr "Размер пикселя: %g x %g" - -#: ccdfunc.c:765 -msgid "Read grabbed image" -msgstr "Считывание изображения" - -#: ccdfunc.c:732 -#, c-format -msgid "Readout mode: %s" -msgstr "Режим считывания: %s" - -#: client.c:276 -msgid "Server timeout" -msgstr "Таймаут сервера" - -#: ccdfunc.c:696 -#, c-format -msgid "Set brightness to %g" -msgstr "Установить яркость в %g" - -#: ccdfunc.c:638 -#, c-format -msgid "Set fan speed to %d" -msgstr "Не могу установить скорость вентиляторов в %d" - -#: ccdfunc.c:690 -#, c-format -msgid "Set gain to %g" -msgstr "Установить Gain в %g" - -#: ccdfunc.c:663 -#, c-format -msgid "Shutter command: %s\n" -msgstr "Команда затвора: %s\n" - -#. "Попытка сконфигурировать порт I/O как %d\n" -#: ccdfunc.c:669 -#, c-format -msgid "Try to configure I/O port as %d" -msgstr "Попытка сконфигурировать порт I/O как %d" - -#. "Попытка записи %d в порт I/O\n" -#: ccdfunc.c:681 -#, c-format -msgid "Try to write %d to I/O port" -msgstr "Попытка записи %d в порт I/O" - -#: cmdlnopts.c:100 -msgid "UNIX socket name" -msgstr "Имя UNIX-сокета" - -#: ccdfunc.c:483 -msgid "Wheel device not pointed" -msgstr "Устройство турели не указано" - -#: ccdfunc.c:549 -#, c-format -msgid "Wheel position should be from 0 to %d" -msgstr "Позиция колеса должна быть от 0 до %d" - -#: cmdlnopts.c:76 -msgid "absolute (not divided by binning!) frame X0 coordinate (-1 - all " - "with overscan)" -msgstr "абсолютная (не деленная на биннинг!) координата X0 (-1 - включая оверскан)" - -#: cmdlnopts.c:78 -msgid "absolute frame X1 coordinate (-1 - all with overscan)" -msgstr "абсолютная координата X1 (-1 - включая оверскан)" - -#: cmdlnopts.c:77 -msgid "absolute frame Y0 coordinate (-1 - all with overscan)" -msgstr "абсолютная координата Y0 (-1 - включая оверскан)" - -#: cmdlnopts.c:79 -msgid "absolute frame Y1 coordinate (-1 - all with overscan)" -msgstr "абсолютная координата Y1 (-1 - включая оверскан)" - -#: cmdlnopts.c:65 -msgid "add records to header from given file[s]" -msgstr "добавить записи к шапке FITS-файла из заданных файлов" - -#: cmdlnopts.c:47 -msgid "camera device number (if many: 0, 1, 2 etc)" -msgstr "номер устройства камеры" - -#: cmdlnopts.c:43 -msgid "camera device plugin (e.g. devfli.so)" -msgstr "плагин камеры (например, devfli.so)" - -#: cmdlnopts.c:75 -msgid "cancel current exposition" -msgstr "отмена текущей экспозиции" - -#: cmdlnopts.c:82 -msgid "close shutter" -msgstr "закрыть затвор" - -#: cmdlnopts.c:42 -msgid "common device plugin (e.g devfli.so)" -msgstr "общий плагин для всех устройств (например, devfli.so)" - -#: cmdlnopts.c:89 -msgid "configure I/O port pins to given value (decimal number, pin1 is LSB, " - "1 == output, 0 == input)" -msgstr "сконфигурировать порт I/O в заданное состояние (десятичное число, pin1 - младший бит, 1 - выход, 0 - вход)" - -#: cmdlnopts.c:55 -msgid "fast readout mode" -msgstr "быстрый режим считывания" - -#: cmdlnopts.c:48 -msgid "filter wheel device number (if many: 0, 1, 2 etc)" -msgstr "номер устройства турели" - -#: cmdlnopts.c:49 -msgid "focuser device number (if many: 0, 1, 2 etc)" -msgstr "номер устройства фокусера" - -#: cmdlnopts.c:44 -msgid "focuser device plugin (e.g. devzwo.so)" -msgstr "плагин фокусера (например, devzwo.so)" - -#: cmdlnopts.c:85 -msgid "get value of I/O port pins" -msgstr "получить значение порта I/O" - -#: cmdlnopts.c:70 -msgid "horizontal binning to N pixels" -msgstr "горизонтальный биннинг в N пикселей" - -#: cmdlnopts.c:61 -msgid "instrument name" -msgstr "название прибора" - -#: cmdlnopts.c:46 -msgid "list connected devices" -msgstr "список подключенных устройств" - -#: cmdlnopts.c:101 -msgid "local INET socket port" -msgstr "порт локального сетевого сокета" - -#: cmdlnopts.c:99 -msgid "logging file name (if run as server)" -msgstr "имя файла логгирования (если запущен сервер)" - -#: cmdlnopts.c:73 -msgid "make pause for N seconds between expositions" -msgstr "пауза в N секунд между экспозициями" - -#: cmdlnopts.c:72 -msgid "make series of N frames" -msgstr "последовательность из N кадров" - -#: cmdlnopts.c:91 -msgid "move focuser to absolute position, mm" -msgstr "переместить фокусер в абсолютное положение, мм" - -#: cmdlnopts.c:92 -msgid "move focuser to relative position, mm (only for standalone)" -msgstr "переместить фокусер в относительное положение, мм (не для сервер/клиент)" - -#: cmdlnopts.c:86 -msgid "move stepper motor asynchronous" -msgstr "асинхронное движение шагового двигателя" - -#: cmdlnopts.c:53 -msgid "not open shutter, when exposing (\"dark frames\")" -msgstr "не открывать затвор при экспозиции (\"темновые\")" - -#: cmdlnopts.c:62 -msgid "object name" -msgstr "название объекта" - -#: cmdlnopts.c:60 -msgid "object type (neon, object, flat etc)" -msgstr "тип объекта (neon, object, flat и т.д.)" - -#: cmdlnopts.c:63 -msgid "observers' names" -msgstr "имена наблюдателей" - -#: cmdlnopts.c:64 -msgid "observing program name" -msgstr "название программы" - -#: imageview.c:517 -msgid "off" -msgstr "выкл" - -#: imageview.c:517 -msgid "on" -msgstr "вкл" - -#: cmdlnopts.c:81 -msgid "open shutter" -msgstr "открыть затвор" - -#: cmdlnopts.c:66 -msgid "output file name" -msgstr "имя файла" - -#: cmdlnopts.c:59 -msgid "program author" -msgstr "автор программы" - -#: cmdlnopts.c:104 -msgid "restart image server" -msgstr "перезапуск сервера" - -#: cmdlnopts.c:51 -msgid "rewrite output file if exists" -msgstr "перезапись выходного файла" - -#: cmdlnopts.c:102 -msgid "run as client" -msgstr "запустить клиент" - -#: cmdlnopts.c:84 -msgid "run exposition on HIGH @ pin5 I/O port" -msgstr "" - -#: cmdlnopts.c:83 -msgid "run exposition on LOW @ pin5 I/O port" -msgstr "" - -#: cmdlnopts.c:54 -msgid "run in 8-bit mode" -msgstr "8-битный режим" - -#: cmdlnopts.c:56 -msgid "set CCD temperature to given value (degr C)" -msgstr "установить температуру светоприемника (градЦ)" - -#: cmdlnopts.c:88 -msgid "set I/O port pins to given value (decimal number, pin1 is LSB)" -msgstr "установить порт I/O (десятичное число, pin1 - младший бит)" - -#: cmdlnopts.c:74 -msgid "set exposure time to given value (seconds!)" -msgstr "установить время экспозиции (секунды!)" - -#: cmdlnopts.c:57 -msgid "set fan speed (0 - off, 1 - low, 2 - high)" -msgstr "установить скорость вентилятора (0 - выкл, 1 - низкая, 2 - высокая)" - -#: cmdlnopts.c:94 -msgid "set wheel position" -msgstr "установить положение колеса" - -#: cmdlnopts.c:50 -msgid "show this help" -msgstr "отобразить эту справку" - -#: cmdlnopts.c:52 -msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)" -msgstr "уровень болтливости (-V - сообщения, -VV - отладка, -VVV - все)" - -#: cmdlnopts.c:71 -msgid "vertical binning to N pixels" -msgstr "вертикальный биннинг в N пикселей" - -#: cmdlnopts.c:67 -msgid "wait while exposition ends" -msgstr "ждать, пока не кончится экспозиция" - -#: cmdlnopts.c:45 -msgid "wheel device plugin (e.g. devdummy.so)" -msgstr "плагин устройства турели (например, devdummy.so)" diff --git a/main.c b/main.c index 9c61027..ab90c9e 100644 --- a/main.c +++ b/main.c @@ -129,6 +129,7 @@ int main(int argc, char **argv){ signal(SIGTERM, signals); signal(SIGHUP, SIG_IGN); signal(SIGTSTP, SIG_IGN); + signal(SIGPIPE, SIG_IGN); signal(SIGUSR1, signals); // restart server if(!isserver){ // run in standalone or client mode int camerainit = FALSE; diff --git a/server.c b/server.c index 364163d..0f1c309 100644 --- a/server.c +++ b/server.c @@ -38,14 +38,13 @@ static _Atomic cc_camera_state camstate = CAMERA_IDLE; #define FLAG_CANCEL (1<<1) #define FLAG_RESTARTSERVER (1<<2) static atomic_int camflags = 0, camfanspd = 0, confio = 0, nflushes, infty = 0; -static char *outfile = NULL, *lastfile = NULL; // current output file name/prefix; last name of saved file static cc_frameformat frmformatmax = {0}, curformat = {0}; // maximal format static float focmaxpos = 0., focminpos = 0.; // focuser extremal positions static int wmaxpos = 0.; // wheel max pos static float tremain = 0.; // time when capture done -// IPC key for shared memory +// IPC key for shared memory (for client's getter) static key_t shmkey = IPC_PRIVATE; typedef struct{ @@ -67,8 +66,6 @@ strpair allcommands[] = { "or set (0: cancel, 1: start exp)\n also get camflags (bits: 0-start capture, 1-cancel, 2-restart server" }, { CC_CMD_EXPOSITION, "exposition time" }, { CC_CMD_FASTSPD, "fast readout speed" }, - { CC_CMD_FILENAME, "save file with this name, like file.fits" }, - { CC_CMD_FILENAMEPREFIX,"prefix of files, like ex (will be saved as exXXXX.fits)" }, { CC_CMD_FDEVNO, "focuser device number" }, { CC_CMD_FOCLIST, "list all connected focusers" }, { CC_CMD_FGOTO, "focuser position" }, @@ -76,7 +73,6 @@ strpair allcommands[] = { { CC_CMD_GAIN, "camera gain" }, { CC_CMD_GETHEADERS, "get last file FITS headers" }, { CC_CMD_HBIN, "horizontal binning" }, - { CC_CMD_HEADERFILES, "add FITS records from these files (comma-separated list)" }, { CC_CMD_HELP, "show this help" }, { CC_CMD_IMHEIGHT, "last image height" }, { CC_CMD_IMWIDTH, "last image width" }, @@ -84,7 +80,6 @@ strpair allcommands[] = { { CC_CMD_INFTY, "an infinity loop taking images until there's connected clients" }, { CC_CMD_INSTRUMENT, "FITS 'INSTRUME' field" }, { CC_CMD_IO, "get/set camera IO" }, - { CC_CMD_LASTFNAME, "path to last saved file"}, { CC_CMD_FRAMEMAX, "camera maximal available format" }, { CC_CMD_NFLUSHES, "camera number of preflushes" }, { CC_CMD_OBJECT, "FITS 'OBJECT' field" }, @@ -93,7 +88,6 @@ strpair allcommands[] = { { CC_CMD_PLUGINCMD, "custom camera plugin command" }, { CC_CMD_PROGRAM, "FITS 'PROG-ID' field" }, { CC_CMD_RESTART, "restart server" }, - { CC_CMD_REWRITE, "rewrite file (if give `filename`, not `filenameprefix`)" }, { CC_CMD_SHMEMKEY, "get shared memory key" }, { CC_CMD_SHUTTER, "camera shutter's operations" }, { CC_CMD_CAMTEMPER, "camera chip temperature" }, @@ -116,18 +110,71 @@ static int lock(){ return TRUE; } static void unlock(){ - if(pthread_mutex_unlock(&locmutex)) ERR("Can't unlock mutex"); + if(pthread_mutex_unlock(&locmutex)){ + LOGERR("Can't unlock socket mutex"); + ERR("Can't unlock socket mutex"); + } } static cc_IMG *ima = NULL; +// client-side SHM lock +int client_lock_shm(cc_IMG *img){ + if(!img) return FALSE; + if(pthread_mutex_trylock(&img->mutex)) + return FALSE; + return TRUE; +} + +// server-side SHM lock (first - try gracefully, next - force) +static void server_lock_shm(cc_IMG *img){ + if(!img) return; + double t0 = sl_dtime(); + int locked = FALSE; + // lock socket operations + while(sl_dtime() - t0 < MUTEX_LOCK_TMOUT){ + int l = pthread_mutex_trylock(&img->mutex); + if(0 == l){ + locked = TRUE; + break; + } + if(l == EOWNERDEAD){ // locked while locking thread is dead + pthread_mutex_consistent(&img->mutex); + } + } + if(!locked) while(!client_lock_shm(img)) unlock_shm(img); +} + +void unlock_shm(cc_IMG *img){ + if(!img) return; + if(pthread_mutex_unlock(&img->mutex)){ + LOGERR("Can't unlock image mutex"); + ERR("Can't unlock image mutex"); + } +} + static void fixima(){ FNAME(); if(!camera) return; + double t0 = sl_dtime(); + int locked = FALSE; + // lock socket operations + while(!(locked = lock()) && sl_dtime() - t0 < 0.5); + if(!locked) while(!lock()) unlock(); // force unlocking if can't do this gracefully int raw_width = curformat.w / GP->hbin, raw_height = curformat.h / GP->vbin; // allocate memory for largest possible image - if(!ima) ima = cc_getshm(GP->shmkey, camera->array.h * camera->array.w * 2); + if(!ima){ + ima = cc_getshm(GP->shmkey, camera->array.h * camera->array.w * 2); + // init shared robust mutex + pthread_mutexattr_t att; + pthread_mutexattr_init(&att); + pthread_mutexattr_setrobust(&att, PTHREAD_MUTEX_ROBUST); + pthread_mutexattr_setpshared(&att, PTHREAD_PROCESS_SHARED); + pthread_mutex_init(&ima->mutex, &att); + } if(!ima) ERRX("Can't allocate memory for image"); + locked = FALSE; + server_lock_shm(ima); shmkey = GP->shmkey; //if(raw_width == ima->w && raw_height == ima->h) return; // all OK DBG("curformat: %dx%d", curformat.w, curformat.h); @@ -140,6 +187,8 @@ static void fixima(){ DBG("GP->_8bit=%d", GP->_8bit); ima->bytelen = raw_height * raw_width * cc_getNbytes(ima); DBG("new image: %dx%d", raw_width, raw_height); + unlock_shm(ima); + unlock(); } // functions for processCAM finite state machine @@ -169,8 +218,8 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends if(cs != CAPTURE_PROCESS){ TIMESTAMP("Capture ready"); tremain = 0.; - // now save frame - if(!ima->data) LOGERR("Can't save image: not initialized"); + // now capture frame + if(!ima || !ima->data) LOGERR("Can't capture image: data not initialized"); else{ TIMESTAMP("start capture"); if(!camera->capture){ @@ -179,6 +228,7 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends camstate = CAMERA_ERROR; return; } + server_lock_shm(ima); if(!camera->capture(ima)){ LOGERR("Can't capture image"); camstate = CAMERA_ERROR; @@ -186,12 +236,10 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends }else{ ima->gotstat = 0; // fresh image without statistics - recalculate when save ima->timestamp = sl_dtime(); // set timestamp + fillFITSheader(ima); ++ima->imnumber; // increment counter - if(saveFITS(ima, &lastfile)){ - DBG("LAST file name changed"); - } - TIMESTAMP("Image saved"); } + unlock_shm(ima); } camstate = CAMERA_FRAMERDY; } @@ -267,8 +315,8 @@ static int camdevini(int n){ LOGERR("Can't set active camera number"); return FALSE; } - camdevno = n; - LOGMSG("Set camera device number to %d", camdevno); + atomic_store(&camdevno, n); + LOGMSG("Set camera device number to %d", n); cc_frameformat step; if(camera->getgeomlimits) camera->getgeomlimits(&frmformatmax, &step); curformat = frmformatmax; @@ -291,8 +339,8 @@ static int focdevini(int n){ LOGERR("Can't set active focuser number"); return FALSE; } - focdevno = n; - LOGMSG("Set focuser device number to %d", focdevno); + atomic_store(&focdevno, n); + LOGMSG("Set focuser device number to %d", n); focuser->getMaxPos(&focmaxpos); focuser->getMinPos(&focminpos); return TRUE; @@ -303,8 +351,8 @@ static int wheeldevini(int n){ LOGERR("Can't set active wheel number"); return FALSE; } - wheeldevno = n; - LOGMSG("Set wheel device number to %d", wheeldevno); + atomic_store(&wheeldevno, n); + LOGMSG("Set wheel device number to %d", n); wheel->getMaxPos(&wmaxpos); return TRUE; } @@ -323,6 +371,7 @@ static cc_hresult restarthandler(_U_ int fd, _U_ const char *key, _U_ const char // image size static cc_hresult imsizehandler(int fd, const char *key, _U_ const char *val){ char buf[64]; + if(!ima) return CC_RESULT_FAIL; // send image width/height in pixels if(0 == strcmp(key, CC_CMD_IMHEIGHT)) snprintf(buf, 63, CC_CMD_IMHEIGHT "=%d", ima->h); else snprintf(buf, 63, CC_CMD_IMWIDTH "=%d", ima->w); @@ -338,7 +387,8 @@ static cc_hresult camlisthandler(int fd, _U_ const char *key, _U_ const char *va snprintf(buf, BUFSIZ-1, CC_CMD_CAMLIST "='%s'", modname); if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; } - if(camdevno > -1 && camera->setDevNo) camera->setDevNo(camdevno); + int devno = atomic_load(&camdevno); + if(devno > -1 && camera->setDevNo) camera->setDevNo(devno); return CC_RESULT_SILENCE; } static cc_hresult camsetNhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){ @@ -350,7 +400,7 @@ static cc_hresult camsetNhandler(_U_ int fd, _U_ const char *key, _U_ const char } if(!camdevini(num)) return CC_RESULT_FAIL; } - snprintf(buf, 63, CC_CMD_CAMDEVNO "=%d", camdevno); + snprintf(buf, 63, CC_CMD_CAMDEVNO "=%d", atomic_load(&camdevno)); if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; return CC_RESULT_SILENCE; } @@ -371,76 +421,6 @@ static cc_hresult exphandler(int fd, _U_ const char *key, const char *val){ if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; return CC_RESULT_SILENCE; } -// show last filename of saved FITS -static cc_hresult lastfnamehandler(int fd, _U_ const char *key, _U_ const char *val){ - char buf[PATH_MAX+32]; - if(lastfile && *lastfile) snprintf(buf, PATH_MAX+31, CC_CMD_LASTFNAME "=%s", lastfile); - else snprintf(buf, PATH_MAX+31, CC_CMD_LASTFNAME "="); - if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; - return CC_RESULT_SILENCE; -} -// filename setter/getter -static cc_hresult namehandler(int fd, _U_ const char *key, const char *val){ - char buf[PATH_MAX+32]; - DBG("filename=%s", val); - if(val && *val){ - DBG("Make abs path"); - char *path = makeabspath(val, FALSE); - if(!path){ - LOGERR("Can't create file '%s'", val); - return CC_RESULT_BADVAL; - } - FREE(outfile); - outfile = strdup(path); - GP->outfile = outfile; - GP->outfileprefix = NULL; - }else{ // clear names - DBG("Clear names"); - GP->outfileprefix = NULL; - GP->outfile = NULL; - return CC_RESULT_OK; - } - if(!GP->outfile) return CC_RESULT_FAIL; - snprintf(buf, PATH_MAX+31, CC_CMD_FILENAME "=%s", GP->outfile); - if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; - return CC_RESULT_SILENCE; -} -// filename prefix -static cc_hresult nameprefixhandler(_U_ int fd, _U_ const char *key, const char *val){ - char buf[PATH_MAX+32]; - DBG("filename prefix=%s", val); - if(val){ - char *path = makeabspath(val, FALSE); - if(!path){ - LOGERR("Can't create file '%s'", val); - return CC_RESULT_BADVAL; - } - FREE(outfile); - outfile = strdup(path); - GP->outfileprefix = outfile; - GP->outfile = NULL; - }else{ // clear names - GP->outfileprefix = NULL; - GP->outfile = NULL; - return CC_RESULT_OK; - } - if(!GP->outfileprefix) return CC_RESULT_FAIL; - snprintf(buf, PATH_MAX+31, CC_CMD_FILENAMEPREFIX "=%s", GP->outfileprefix); - if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; - return CC_RESULT_SILENCE; -} -// rewrite -static cc_hresult rewritefilehandler(_U_ int fd, _U_ const char *key, const char *val){ - char buf[64]; - if(val){ - int n = atoi(val); - if(n < 0 || n > 1) return CC_RESULT_BADVAL; - GP->rewrite = n; - } - snprintf(buf, 63, CC_CMD_REWRITE "=%d", GP->rewrite); - if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; - return CC_RESULT_SILENCE; -} static cc_hresult binhandler(_U_ int fd, const char *key, const char *val){ char buf[64]; if(val){ @@ -733,77 +713,6 @@ static cc_hresult FITSparhandler(int fd, const char *key, const char *val){ if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; return CC_RESULT_SILENCE; } -static cc_hresult FITSheaderhandler(int fd, _U_ const char *key, const char *val){ - char buf[BUFSIZ], **sptr; - static char *curhdr = NULL; - static int firstrun = 1; - if(val){ - int sz = 10, amount = 0; - // first we should check `val` - char b2[BUFSIZ], *bptr = buf; - snprintf(b2, BUFSIZ-1, "%s", val); - char **list = MALLOC(char*, sz), **lptr = list; - int L = BUFSIZ; - for(char *s = b2; ; s = NULL){ - char *tok = strtok(s, ",;"); - if(!tok){ - *lptr = NULL; - break; - } - // check path - char *newpath = makeabspath(tok, TRUE); - DBG("next token: %s, path: %s", tok, newpath); - if(!newpath){ // error! Free list and return err - DBG("No such file"); - sptr = list; - while(*sptr){ - FREE(*sptr++); - } - FREE(list); - return CC_RESULT_BADVAL; - } - *lptr++ = strdup(newpath); - if(++amount == sz){ - DBG("Realloc"); - sz += 10; - list = realloc(list, sz*sizeof(char*)); - bzero(&list[sz-10], 10*sizeof(char*)); - } - int N = snprintf(bptr, L-1, "%s,", newpath); - bptr += N; L -= N; - } - // free old list and change its value - if(GP->addhdr){ - DBG("Free old list"); - sptr = GP->addhdr; - while(*sptr){ - DBG("Free %s", *sptr); - free(*(sptr++)); - } - } - GP->addhdr = list; - FREE(curhdr); - if(*val && *val != ',') curhdr = strdup(buf); // command with empty arg will clear curhdr - DBG("curhdr now: %s", curhdr); - } - if(!curhdr && firstrun){ - firstrun = 0; - if(GP->addhdr && *GP->addhdr){ - char *ptr = buf; - int L = BUFSIZ; - sptr = GP->addhdr; - while(*sptr){ - DBG("Add to curhdr: %s", *sptr); - int N = snprintf(ptr, L-1, "%s,", *sptr++); - L -= N; ptr += N; - } - curhdr = strdup(buf); - } - } - snprintf(buf, BUFSIZ-1, CC_CMD_HEADERFILES "=%s", curhdr); - if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; - return CC_RESULT_SILENCE; -} /* static cc_hresult handler(_U_ int fd, _U_ const char *key, _U_ const char *val){ char buf[64]; @@ -822,7 +731,8 @@ static cc_hresult wlisthandler(int fd, _U_ const char *key, _U_ const char *val) snprintf(buf, BUFSIZ-1, CC_CMD_WLIST "='%s'", modname); if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; } - if(wheeldevno > -1) wheel->setDevNo(wheeldevno); + int devno = atomic_load(&wheeldevno); + if(devno > -1) wheel->setDevNo(devno); return CC_RESULT_SILENCE; } static cc_hresult wsetNhandler(int fd, _U_ const char *key, const char *val){ @@ -834,7 +744,7 @@ static cc_hresult wsetNhandler(int fd, _U_ const char *key, const char *val){ } if(!wheeldevini(num)) return CC_RESULT_FAIL; } - snprintf(buf, 63, CC_CMD_WDEVNO "=%d", wheeldevno); + snprintf(buf, 63, CC_CMD_WDEVNO "=%d", atomic_load(&wheeldevno)); if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; return CC_RESULT_SILENCE; } @@ -869,7 +779,8 @@ static cc_hresult foclisthandler(int fd, _U_ const char *key, _U_ const char *va snprintf(buf, BUFSIZ-1, CC_CMD_FOCLIST "='%s'", modname); if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; } - if(focdevno > -1) focuser->setDevNo(focdevno); + int devno = atomic_load(&focdevno); + if(devno > -1) focuser->setDevNo(devno); return CC_RESULT_SILENCE; } static cc_hresult fsetNhandler(int fd, _U_ const char *key, const char *val){ @@ -881,7 +792,7 @@ static cc_hresult fsetNhandler(int fd, _U_ const char *key, const char *val){ } if(!focdevini(num)) return CC_RESULT_FAIL; } - snprintf(buf, 63, CC_CMD_FDEVNO "=%d", focdevno); + snprintf(buf, 63, CC_CMD_FDEVNO "=%d", atomic_load(&focdevno)); if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; return CC_RESULT_SILENCE; } @@ -921,12 +832,10 @@ static cc_hresult infohandler(int fd, _U_ const char *key, _U_ const char *val){ if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; } #define RUN(f, arg) do{if(CC_RESULT_DISCONNECTED == f(fd, arg, NULL)) return CC_RESULT_DISCONNECTED;}while(0) - RUN(namehandler, CC_CMD_FILENAME); RUN(binhandler, CC_CMD_HBIN); RUN(binhandler, CC_CMD_VBIN); RUN(temphandler, CC_CMD_CAMTEMPER); RUN(exphandler, CC_CMD_EXPOSITION); - RUN(lastfnamehandler, CC_CMD_LASTFNAME); RUN(expstatehandler, CC_CMD_EXPSTATE); #undef RUN } @@ -981,7 +890,7 @@ static cc_hresult helphandler(int fd, _U_ const char *key, _U_ const char *val){ return CC_RESULT_SILENCE; } -// shared memory key +// shared memory key getter static cc_hresult shmemkeyhandler(int fd, _U_ const char *key, _U_ const char *val){ char buf[64]; if(shmkey == IPC_PRIVATE) return CC_RESULT_FAIL; @@ -1018,9 +927,15 @@ static cc_hresult pluginhandler(int fd, _U_ const char *key, const char *val){ // get headers static cc_hresult gethdrshandler(int fd, _U_ const char *key, _U_ const char *val){ - cc_charbuff *b = getFITSheader(ima); - if(!b) return CC_RESULT_FAIL; - if(!cc_sendstrmessage(fd, b->buf)) return CC_RESULT_DISCONNECTED; + if(!ima) return CC_RESULT_FAIL; + size_t nlines = ima->headerstrings; + if(nlines < 1) return CC_RESULT_FAIL; + char buf[FLEN_CARD+1]; + for(size_t n = 0; n < nlines; ++n){ + snprintf(buf, FLEN_CARD+1, "%s\n", ima->fitsheader[n]); + if(!cc_sendstrmessage(fd, buf)) + return CC_RESULT_DISCONNECTED; + } return CC_RESULT_SILENCE; } @@ -1063,7 +978,6 @@ static cc_handleritem items[] = { {chkcc, camsetNhandler, CC_CMD_CAMDEVNO}, {chkcc, camfanhandler, CC_CMD_CAMFANSPD}, {chkcc, exphandler, CC_CMD_EXPOSITION}, - {chkcc, namehandler, CC_CMD_FILENAME}, {chkcc, binhandler, CC_CMD_HBIN}, {chkcc, binhandler, CC_CMD_VBIN}, {chkcc, temphandler, CC_CMD_CAMTEMPER}, @@ -1079,8 +993,6 @@ static cc_handleritem items[] = { {chktrue,shmemkeyhandler, CC_CMD_SHMEMKEY}, {chktrue,imsizehandler, CC_CMD_IMWIDTH}, {chktrue,imsizehandler, CC_CMD_IMHEIGHT}, - {chkcc, nameprefixhandler, CC_CMD_FILENAMEPREFIX}, - {chkcc, rewritefilehandler, CC_CMD_REWRITE}, {chkcc, _8bithandler, CC_CMD_8BIT}, {chkcc, fastspdhandler, CC_CMD_FASTSPD}, {chkcc, darkhandler, CC_CMD_DARK}, @@ -1094,8 +1006,6 @@ static cc_handleritem items[] = { {NULL, FITSparhandler, CC_CMD_OBJECT}, {NULL, FITSparhandler, CC_CMD_PROGRAM}, {NULL, FITSparhandler, CC_CMD_OBJTYPE}, - {NULL, FITSheaderhandler, CC_CMD_HEADERFILES}, - {NULL, lastfnamehandler, CC_CMD_LASTFNAME}, {chkfoc, foclisthandler, CC_CMD_FOCLIST}, {chkfoc, fsetNhandler, CC_CMD_FDEVNO}, {chkfoc, fgotohandler, CC_CMD_FGOTO}, @@ -1109,10 +1019,25 @@ static cc_handleritem items[] = { #define STRBUFSZ (255) // send image as raw data -static void sendimage(int client){ - if(ima->h < 1 || ima->w < 1) return; - cc_senddata(client, ima, sizeof(cc_IMG)); - cc_senddata(client, ima->data, ima->bytelen); +static void *sendimage(void *C){ + if(!C || !ima || !ima->data) return NULL; + int client = *(int*)C; + if(ima->h < 1 || ima->w < 1) return NULL; + DBG("client fd: %d", client); + do{ + // send image body + if(!cc_senddata(client, ima, sizeof(cc_IMG))) break; + // send image itself (client can close socket if don't need image data) + if(!cc_senddata(client, ima->data, ima->bytelen)) break; + // send FITS header (client can close socket if don't need it) + for(size_t i = 0; i < ima->headerstrings; ++i){ // send header + if(!cc_senddata(client, &ima->fitsheader[i], FLEN_CARD)) break; + } + }while(0); + close(client); + TIMESTAMP("Image sent"); + DBG("%d closed", client); + return NULL; } void server(int sock, int imsock){ @@ -1157,7 +1082,7 @@ void server(int sock, int imsock){ poll_set[1].events = POLLIN; while(1){ poll(poll_set, nfd, 1); // max timeout - 1ms - //if(imsock > -1 && cc_canberead(imsock) > 0){ + //if(imsock > -1 && sl_canread(imsock) > 0){ if(imsock > -1 && (poll_set[1].revents & POLLIN)){ //uint8_t buf[32]; //int l = read(imsock, buf, 32); @@ -1166,13 +1091,23 @@ void server(int sock, int imsock){ socklen_t len = sizeof(addr); int client = accept(imsock, (struct sockaddr*)&addr, &len); DBG("client=%d", client); + // sending image could be a very long operation -> run it in separate thread if(client > -1){ - DBG("client fd: %d", client); - sendimage(client); - close(client); - DBG("%d closed", client); + pthread_t sendthread; + if(pthread_create(&sendthread, NULL, sendimage, (void*)&client)){ + WARN("pthread_create()"); + LOGWARN("pthread_create() error"); + close(client); + }else{ + DBG("Thread created -> detach"); + if(pthread_detach(sendthread)){ + WARN("pthread_detach()"); + LOGWARN("pthread_detach() error"); + pthread_cancel(sendthread); + close(client); + }else DBG("Thread detached"); + } }else{WARN("accept()"); DBG("disconnected");} - TIMESTAMP("Image sent"); } if(poll_set[0].revents & POLLIN){ // check main for accept() struct sockaddr_in addr; @@ -1203,11 +1138,6 @@ void server(int sock, int imsock){ TIMESTAMP("Send message that all ready"); cc_sendstrmessage(poll_set[i].fd, buff); } - if(camstate == CAMERA_FRAMERDY && (GP->outfile || GP->outfileprefix)){ // send to all last file name if file saved - snprintf(buff, PATH_MAX+31, CC_CMD_LASTFNAME "=%s", lastfile); - for(int i = 2; i < nfd; ++i) - cc_sendstrmessage(poll_set[i].fd, buff); - } camstate = CAMERA_IDLE; } // scan connections @@ -1274,7 +1204,7 @@ char *makeabspath(const char *path, int shouldbe){ } if(!realpath(path, buf)){ WARN("realpath()"); - return NULL; + LOGWARN("realpath() error for %s", path); }else ret = buf; fclose(f); if(unl) unlink(path); diff --git a/server.h b/server.h index 0a68dc3..1562b8e 100644 --- a/server.h +++ b/server.h @@ -18,6 +18,11 @@ #pragma once +#include "ccdcapture.h" + +// timeout of trying to lock mutex (if gone, force locking for server) +#define MUTEX_LOCK_TMOUT 0.5 + // pause (seconds) between temperature logging #define TLOG_PAUSE 60. @@ -25,3 +30,5 @@ void server(int fd, int imsock); char *makeabspath(const char *path, int shouldbe); +int client_lock_shm(cc_IMG *img); +void unlock_shm(cc_IMG *img);