Compare commits

...

6 Commits

Author SHA1 Message Date
92c3c54c65 Merge pull request #1 from thehanslevi/codex/readme-occurred-typo
Fix README typo
2026-06-19 08:32:08 +03:00
thehanslevi
94f1cf9656 Fix README typo 2026-06-18 21:16:03 -04:00
66e2bdfaac cont 2026-06-08 17:09:05 +03:00
f65daab527 next fixes 2026-06-04 18:24:26 +03:00
1f7aad348e fx 2026-06-02 18:31:17 +03:00
d355265995 start refactoring 2026-06-02 18:30:33 +03:00
16 changed files with 1117 additions and 1446 deletions

View File

@@ -49,7 +49,7 @@ static int campoll(cc_capture_status *st, float *remain){
if(capstat != CAPTURE_PROCESS){
if(st) *st = capstat;
if(remain) *remain = 0.;
return TRUE;
return FALSE;
}
if(sl_dtime() - texpstart > exptime){
if(st) *st = CAPTURE_READY;

View File

@@ -187,7 +187,7 @@ clients connected.
When you send a command to server you will receive:
- one of answers - "OK" (all OK), "BUSY" (can't run setter because camera is busy), "FAIL" (some error
occured), "BADKEY" (wrong key name) or "BADVAL" (wrong key's value) - for procedures and setters
occurred), "BADKEY" (wrong key name) or "BADVAL" (wrong key's value) - for procedures and setters
(instead of "OK" you will give "parameter=value" for setter if all OK);
- "parameter=value" for getters.

View File

@@ -24,6 +24,7 @@
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/un.h> // unix socket
#include <unistd.h>
#include <usefull_macros.h>
@@ -43,6 +44,82 @@ double __t0 = 0.;
static int ntries = 2; // amount of tries to send messages controlling the answer
double answer_timeout = 0.1; // timeout of waiting answer from server (not static for client.c)
static sem_t *sem = SEM_FAILED;
// client-side SHM lock
int cc_lock_shm(int isserver){
if(sem == SEM_FAILED){
DBG("Can't lock NULL");
return FALSE;
}
struct timespec ts = {.tv_sec = 0, .tv_nsec = 10000000};
DBG("Try to lock");
if(isserver){
int locked = TRUE;
while(sem_timedwait(sem, &ts) && locked){
switch(errno){
case EINTR:
DBG("Interrupt -> try to lock again");
break;
default: // timeout or other error -> force locking
DBG("Error locking -> force unlock");
locked = FALSE;
}
}
if(locked){
double t0 = sl_dtime();
while(sem_trywait(sem) && sl_dtime() - t0 < 0.1) sem_post(sem); // force locking
}
}else{
if(sem_timedwait(sem, &ts)){
DBG("Image semaphore is locked too long by other side");
return FALSE; // can't lock
}
}
DBG("Semaphore locked");
return TRUE;
}
void cc_unlock_shm(){
if(sem == SEM_FAILED){
DBG("Can't unlock NULL");
return;
}
if(sem_post(sem)){
switch(errno){
case EOVERFLOW: // already unlocked
break;
default: // not a valid? or other?
WARN("Can't unlock image semaphore");
LOGERR("Can't unlock image semaphore");
return;
}
}
DBG("Semaphore unlocked");
}
void cc_init_sem(int isserver){
if(sem != SEM_FAILED) return;
umask(0); // for read-write semaphore
// create samaphore if no
if(isserver){
sem = sem_open(SEM_NAME, O_CREAT, 0666, 1);
}else{
sem = sem_open(SEM_NAME, 0);
}
if(sem == SEM_FAILED){
LOGERR("sem_open failed: %s", strerror(errno));
}
}
void cc_remove_sem(){
if(sem == SEM_FAILED) return;
sem_close(sem);
DBG("semaphore closed\n");
if(-1 == sem_unlink(SEM_NAME))
LOGERR("Can't delete semaphore");
}
/**
* @brief cc_open_socket - create socket and open it
* @param isserver - TRUE for server, FALSE for client
@@ -134,15 +211,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 +236,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 +322,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)
@@ -268,7 +330,7 @@ int cc_canberead(int fd){
cc_IMG *cc_getshm(key_t key, size_t imsize){
size_t shmsize = sizeof(cc_IMG) + imsize;
shmsize = 1024 * (1 + shmsize / 1024);
DBG("Allocate %zd bytes in shared memory", shmsize);
DBG("Shared memory; sizeof(cc_IMG)=%zd, imsize=%zd", sizeof(cc_IMG), imsize);
int shmid = -1;
int flags = (imsize) ? IPC_CREAT | 0666 : 0;
shmid = shmget(key, 0, flags);
@@ -287,9 +349,15 @@ cc_IMG *cc_getshm(key_t key, size_t imsize){
WARN("Can't create shared memory segment %d", key);
return NULL;
}
}else{
#ifdef EBUG
struct shmid_ds buf;
if(shmctl(shmid, IPC_STAT, &buf)) WARNX("Can't get SHM data");
else DBG("SHM size = %zd", buf.shm_segsz);
#endif
}
flags = (imsize) ? 0 : SHM_RDONLY; // client opens memory in readonly mode
cc_IMG *ptr = shmat(shmid, NULL, flags);
cc_IMG *ptr = shmat(shmid, NULL, 0);
if(ptr == (void*)-1){
if(imsize) WARN("Can't attach SHM segment %d", key);
return NULL;
@@ -453,8 +521,17 @@ 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 == EINTR){
DBG("errno=%d, '%s'", errno, strerror(errno));
continue;
}
goto ret; // EAGAIN or other error -> client disconnected
}else break;
}while(1);
DBG("got %zd bytes", rd);
if(rd) buf->buflen += rd;
ret = TRUE;
@@ -470,7 +547,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 +625,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 +728,60 @@ 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;
if(l < FLEN_CARD) 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 +817,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;

View File

@@ -20,14 +20,21 @@
#include <fitsio.h> // FLEN_CARD
#include <pthread.h>
#include <semaphore.h>
#include <stdint.h>
#include <stdlib.h> // for size_t
// max strings in header
#define FITS_HEADER_STRINGS_MAX (1000)
// magic to mark our SHM
#define CC_SHM_MAGIC (0xdeadbeef)
// semaphore for SHM protection
#define SEM_NAME "ccdcapture"
// base image parameters - sent by socket and stored in shared memory
typedef struct __attribute__((packed, aligned(4))){
typedef struct __attribute__((packed)){
uint32_t MAGICK; // magick (DEADBEEF) - to mark our shm
double timestamp; // timestamp of image taken
uint8_t bitpix; // bits per pixel (8 or 16)
@@ -39,6 +46,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{
@@ -192,9 +201,11 @@ typedef struct{
// wait for mutex locking
#define CC_BUSY_TIMEOUT (1.0)
// wait for exposition ends (between subsequent check calls)
#define CC_WAIT_TIMEOUT (2.0)
#define CC_WAIT_TIMEOUT (15.0)
// client will disconnect after this time from last server message
#define CC_CLIENT_TIMEOUT (3.0)
#define CC_CLIENT_TIMEOUT (30.0)
// minimal sleep (us) time when client waits for exp end
#define CC_IMWAIT_SLEEP (1000)
// fd - socket fd to send private messages, key, val - key and its value
typedef cc_hresult (*cc_mesghandler)(int fd, const char *key, const char *val);
@@ -215,7 +226,6 @@ typedef enum{
} cc_camera_state;
// common information about everything
#define CC_CMD_INFO "info"
#define CC_CMD_HELP "help"
// restart server
#define CC_CMD_RESTART "restartTheServer"
@@ -226,19 +236,17 @@ typedef enum{
#define CC_CMD_SHMEMKEY "shmemkey"
// CCD/CMOS
#define CC_CMD_IMNUMBER "imnumber"
#define CC_CMD_PLUGINCMD "plugincmd"
#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"
#define CC_CMD_CAMFANSPD "ccdfanspeed"
#define CC_CMD_CAMFANSPD "camfanspeed"
#define CC_CMD_CAMFLAGS "camflags"
#define CC_CMD_SHUTTER "shutter"
#define CC_CMD_CONFIO "confio"
#define CC_CMD_IO "io"
@@ -250,7 +258,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,17 +270,21 @@ 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"
#define CC_CMD_FDEVNO "focdevno"
#define CC_CMD_FGOTO "focpos"
#define CC_CMD_FMINPOS "focminpos"
#define CC_CMD_FMAXPOS "focmaxpos"
#define CC_CMD_FTEMP "foctemp"
// wheel
#define CC_CMD_WLIST "wlist"
#define CC_CMD_WDEVNO "wdevno"
#define CC_CMD_WPOS "wpos"
#define CC_CMD_WMAXPOS "wmaxpos"
#define CC_CMD_WTEMP "wtemp"
typedef enum{ // parameter type
CC_PAR_NONE, // no parameter
@@ -328,12 +340,16 @@ 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);
void cc_init_sem(int isserver);
int cc_lock_shm(int isserver);
void cc_unlock_shm();
void cc_remove_sem();

View File

@@ -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);
@@ -377,11 +384,11 @@ void focusers(){
if(num < 0) num = 0;
if(num > focuser->Ndevices - 1){
WARNX(_("Found %d focusers, you point number %d"), focuser->Ndevices, num);
return;
goto retn;
}
if(!focuser->setDevNo(num)){
WARNX(_("Can't set active focuser number"));
return;
goto retn;
}
char buf[BUFSIZ];
if(focuser->getModelName(buf, BUFSIZ)){
@@ -395,18 +402,18 @@ void focusers(){
float minpos, maxpos, curpos;
if(!focuser->getMinPos(&minpos) || !focuser->getMaxPos(&maxpos)){
WARNX(_("Can't get focuser limit positions"));
return;
goto retn;
}
verbose(1, "FOCMINPOS=%g", minpos);
verbose(1, "FOCMAXPOS=%g", maxpos);
DBG("FOCMINPOS=%g, FOCMAXPOS=%g", minpos, maxpos);
if(!focuser->getPos(&curpos)){
WARNX(_("Can't get current focuser position"));
return;
goto retn;
}
verbose(1, "FOCPOS=%g", curpos);
DBG("Curpos = %g", curpos);
if(isnan(GP->gotopos) && isnan(GP->addsteps)) return; // no focuser commands
if(isnan(GP->gotopos) && isnan(GP->addsteps)) goto retn; // no focuser commands
float tagpos = 0.;
if(!isnan(GP->gotopos)){ // set absolute position
tagpos = GP->gotopos;
@@ -416,13 +423,15 @@ void focusers(){
DBG("tagpos: %g", tagpos);
if(tagpos < minpos || tagpos > maxpos){
WARNX(_("Can't set position %g: out of limits [%g, %g]"), tagpos, minpos, maxpos);
return;
goto retn;
}
if(tagpos - minpos < __FLT_EPSILON__){
if(!focuser->home(GP->async)) WARNX(_("Can't home focuser"));
}else{
if(!focuser->setAbsPos(GP->async, tagpos)) WARNX(_("Can't set position %g"), tagpos);
}
retn:
focclose();
}
cc_Wheel *startWheel(){
@@ -465,11 +474,11 @@ void wheels(){
if(num < 0) num = 0;
if(num > wheel->Ndevices - 1){
WARNX(_("Found %d wheels, you point number %d"), wheel->Ndevices, num);
return;
goto retn;
}
if(!wheel->setDevNo(num)){
WARNX(_("Can't set active wheel number"));
return;
goto retn;
}
char buf[BUFSIZ];
if(wheel->getModelName(buf, BUFSIZ)){
@@ -485,17 +494,19 @@ void wheels(){
}else WARNX("Can't get current wheel position");
if(!wheel->getMaxPos(&maxpos)){
WARNX(_("Can't get max wheel position"));
return;
goto retn;
}
verbose(1, "WHEELMAXPOS=%d", maxpos);
pos = GP->setwheel;
if(pos == -1) return; // no wheel commands
if(pos == -1) goto retn; // no wheel commands
if(pos < 0 || pos > maxpos){
WARNX(_("Wheel position should be from 0 to %d"), maxpos);
return;
goto retn;
}
if(!wheel->setPos(pos))
WARNX(_("Can't set wheel position %d"), pos);
retn:
closewheel();
}
/*
static void closeall(){
@@ -916,6 +927,7 @@ int start_socket(int isserver){
}
if(isserver){
imsock = cc_open_socket(TRUE, GP->imageport, 2); // image socket should be networked
DBG("imsock=%d, image port=%s", imsock, GP->imageport);
server(sock, imsock);
}else{
#ifdef IMAGEVIEW

View File

@@ -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();

512
client.c
View File

@@ -37,24 +37,26 @@
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)
#define SENDMSG(...) do{DBG("SENDMSG"); snprintf(sendbuf, BUFSIZ-1, __VA_ARGS__); verbose(2, "\t> %s", sendbuf); if(!cc_sendstrmessage(sock, sendbuf)) ERRX("Server disconnected"); while(getans(sock, NULL));} while(0)
// send message and wait answer starting with 'cmd'
#define SENDMSGW(cmd, ...) do{DBG("SENDMSGW"); snprintf(sendbuf, BUFSIZ-1, cmd __VA_ARGS__); verbose(2, "\t> %s", sendbuf); cc_sendstrmessage(sock, sendbuf);}while(!getans(sock, cmd))
#define SENDMSGW(cmd, ...) do{DBG("SENDMSGW"); snprintf(sendbuf, BUFSIZ-1, cmd __VA_ARGS__); verbose(2, "\t> %s", sendbuf); if(!cc_sendstrmessage(sock, sendbuf)) ERRX("Server disconnected");}while(!getans(sock, cmd))
// send command and wait for answer on it
#define SENDCMDW(cmd) do{DBG("SENDCMDW"); strncpy(sendbuf, cmd, BUFSIZ-1); verbose(2, "\t> %s", sendbuf); cc_sendstrmessage(sock, sendbuf);}while(!getans(sock, cmd))
#define SENDCMDW(cmd) do{DBG("SENDCMDW"); strncpy(sendbuf, cmd, BUFSIZ-1); verbose(2, "\t> %s", sendbuf); if(!cc_sendstrmessage(sock, sendbuf)) ERRX("Server disconnected");}while(!getans(sock, cmd))
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
static uint8_t *imbuf = NULL; // we can't use shmima->data as it belongs to server, so we use `imbuf` and set ima.data = imbuf
static int current_image_number = -1; // for net-parser - last number of exposed image
#if 0
// read message from queue or file descriptor
static char *readmsg(int fd){
static cc_strbuff *buf = NULL;
@@ -70,65 +72,96 @@ 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");
}
return NULL;
}
#endif
#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)){
verbose(1, "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("Current state: %d", atomic_load(&expstate));
return CC_RESULT_SILENCE;
}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_SILENCE;
}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_SILENCE;
}else if(0 == CMP_ANS(CC_CMD_IMNUMBER, ans)){
current_image_number = atoi(val);
}
//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
// if msg != NULL - wait for it in answer
static int getans(int sock, const char *msg){
double t0 = sl_dtime();
char buf[BUFSIZ+1];
int idx = 0;
char *ans = NULL;
while(sl_dtime() - t0 < answer_timeout){
char *s = readmsg(sock);
if(!s) continue;
TIMESTAMP("GetAns(%s)", msg);
double tmout = answer_timeout + 5.; // make first timeout larger for slow networks
// TODO: increase first timeout up to 15-30s (add key?)
cc_hresult res = CC_RESULT_FAIL;
while(sl_dtime() - t0 < tmout){
ans = NULL;
if(1 == sl_canread(sock)){
ssize_t got = read(sock, buf+idx, BUFSIZ-idx);
if(got > 0){
idx += got;
buf[idx] = 0;
char *nl = strchr(buf, '\n');
if(nl){
*nl = 0;
ans = buf;
DBG("got '%s'", ans);
}
}
}
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(msg){
if(res != CC_RESULT_SILENCE || strncmp(ans, msg, strlen(msg))) continue;
else res = CC_RESULT_OK;
}
DBG("Got answer -> break");
break;
}
return ((ans) ? TRUE : FALSE);
TIMESTAMP("GetAns(%s), ans: '%s', result: %d", msg, ans, res);
if(!ans) DBG("Got no answer from server; result=%d", res);
if(res == CC_RESULT_OK) return TRUE;
return FALSE;
}
/**
@@ -149,16 +182,35 @@ static void send_headers(int sock){
DBG("infty=%d", GP->infty);
if(GP->infty > -1) SENDMSGW(CC_CMD_INFTY, "=%d", GP->infty);
// common information
SENDMSG(CC_CMD_INFO);
if(GP->listdevices) SENDCMDW(CC_CMD_CAMLIST);
if(GP->camdevno > -1) SENDMSGW(CC_CMD_CAMDEVNO, "=%d", GP->camdevno);
if(GP->info){
SENDCMDW(CC_CMD_HBIN);
SENDCMDW(CC_CMD_VBIN);
SENDCMDW(CC_CMD_CAMTEMPER);
SENDCMDW(CC_CMD_EXPOSITION);
SENDCMDW(CC_CMD_EXPSTATE);
}
// focuser
if(GP->listdevices) SENDMSG(CC_CMD_FOCLIST);
if(GP->focdevno > -1) SENDMSG(CC_CMD_FDEVNO "=%d", GP->focdevno);
if(GP->info){
SENDCMDW(CC_CMD_FGOTO);
SENDCMDW(CC_CMD_FMINPOS);
SENDCMDW(CC_CMD_FMAXPOS);
SENDCMDW(CC_CMD_FTEMP);
}
if(!isnan(GP->gotopos)){
SENDMSGW(CC_CMD_FGOTO, "=%g", GP->gotopos);
}
// wheel
if(GP->listdevices) SENDCMDW(CC_CMD_WLIST);
if(GP->whldevno > -1) SENDMSGW(CC_CMD_WDEVNO, "=%d", GP->whldevno);
if(GP->info){
SENDCMDW(CC_CMD_WPOS);
SENDCMDW(CC_CMD_WMAXPOS);
SENDCMDW(CC_CMD_WTEMP);
}
if(GP->setwheel > -1) SENDMSGW(CC_CMD_WPOS, "=%d", GP->setwheel);
DBG("nxt");
// CCD/CMOS
@@ -181,8 +233,6 @@ static void send_headers(int sock){
SENDMSGW(CC_CMD_FRAMEFORMAT, "=%d,%d,%d,%d", GP->X0, GP->Y0, GP->X1, GP->Y1);
}
if(GP->cancelexpose) SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_IDLE);
if(GP->listdevices) SENDCMDW(CC_CMD_CAMLIST);
if(GP->camdevno > -1) SENDMSGW(CC_CMD_CAMDEVNO, "=%d", GP->camdevno);
if(GP->hbin) SENDMSGW(CC_CMD_HBIN, "=%d", GP->hbin);
if(GP->vbin) SENDMSGW(CC_CMD_VBIN, "=%d", GP->vbin);
if(!isnan(GP->temperature)) SENDMSGW(CC_CMD_CAMTEMPER, "=%g", GP->temperature);
@@ -200,16 +250,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 +259,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 +268,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,16 +284,35 @@ 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
DBG("Try to read from SHM");
double t0 = sl_dtime();
while(sl_dtime() - t0 < MUTEX_LOCK_TMOUT){
if(cc_lock_shm(FALSE)){
DBG("Locked");
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);
if(imsock < 0){
DBG("Open socket @ %s", GP->imageport);
imsock = cc_open_socket(FALSE, GP->imageport, TRUE);
}
if(imsock < 0) ERRX("getimage(): can't open image transport socket");
// get image size
if(!readNbytes(imsock, sizeof(cc_IMG), (uint8_t*)&ima)){
@@ -361,6 +320,10 @@ static void getimage(){
goto eofg;
}
}
if(ima.MAGICK != CC_SHM_MAGIC){
WARNX("Wrong image: bad magick");
goto eofg;
}
if(ima.bytelen < 1){
WARNX("Wrong image size");
goto eofg;
@@ -376,82 +339,256 @@ static void getimage(){
ima.data = imbuf; // renew this value each time after getting `ima` from server
TIMESTAMP("Start of data read");
if(shmima){
uint8_t *datastart = (uint8_t*)shmima + sizeof(cc_IMG);
uint8_t *datastart = ((uint8_t*)shmima) + sizeof(cc_IMG);
DBG("first image byte: %d", *datastart);
memcpy(imbuf, datastart, ima.bytelen);
TIMESTAMP("Got by shared memory");
if(!askheader){
cc_unlock_shm();
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); // reopen in next time in case of error
if(shmlocked) cc_unlock_shm();
return ret;
}
static void *grabnext(void _U_ *arg){ // daemon grabbing images through the net
// get number of current image; return number or -1 if got error/timeout
static int curImNo(int sock){
if(shmima){
if(!cc_lock_shm(FALSE)) return -1;
int CurNo = shmima->imnumber;
cc_unlock_shm();
return CurNo;
}
// no shared memory: try to get number over TCP
SENDCMDW(CC_CMD_IMNUMBER);
return current_image_number;
}
void client(int sock){
if(sock < 0) ERRX("Can't run without command socket");
if(!GP->forceimsock && !shmima){ // init shm buffer if user don't ask to force workign through image socket
shmima = cc_getshm(GP->shmkey, 0); // try to init client shm
cc_init_sem(FALSE);
DBG("Got access to shared memory: %s", shmima ? "OK" : "FAIL");
}
if(GP->restart){
SENDCMDW(CC_CMD_RESTART);
return;
}
TIMEINIT();
send_headers(sock);
TIMESTAMP("Got headers");
double t0 = sl_dtime(), tw, tstart;
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;
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); // call to start capture
} else return; // just send headers and exit
double timeout = CC_CLIENT_TIMEOUT;
verbose(1, "Exposing frame 1...");
atomic_store(&expstate, CAMERA_CAPTURE); // could be changed earlier
DBG("Current state: %d", atomic_load(&expstate));
verbose(2, "Wait for exposition end");
t0 = sl_dtime();
tw = tstart = t0;
int lastImNo = curImNo(sock);
while(sl_dtime() - t0 < timeout){
if(sl_dtime() - tw > CC_WAIT_TIMEOUT){
SENDCMDW(CC_CMD_TREMAIN); // get remained time
tw = sl_dtime();
}
if(sl_dtime() - tstart < GP->exptime){
t0 = sl_dtime(); // refresh timeout until exp not ends
continue;
}else{
SENDCMDW(CC_CMD_EXPSTATE);
}
int curst = atomic_load(&expstate);
DBG("Current state: %d", curst);
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);
tstart = sl_dtime();
}
continue;
}
if(curst == CAMERA_FRAMERDY){
atomic_store(&expstate, CAMERA_IDLE);
int cur = curImNo(sock);
DBG("Current state: %d, imno: %d", atomic_load(&expstate), cur);
if(Nremain > 1){ // start next capture
verbose(1, "Exposing frame %d...", nframe);
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
tstart = sl_dtime();
}
int failed = TRUE;
if(lastImNo < cur){
lastImNo = cur;
verbose(2, "Frame ready, try to grab");
if(!getimage(TRUE)){
WARNX("Can't get next image");
}else{
if(saveFITS(&ima, &lastfilename)){
--Nremain;
++nframe;
failed = FALSE;
}
}
}else verbose(2, "Got already saved image, wait next");
if(failed && Nremain == 1){ // last image -> should re-expose
verbose(1, "Exposing frame %d...", nframe);
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
tstart = sl_dtime();
}
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{
DBG("All images saved -> exit");
break;
}
}
}
if(Nremain > 0) 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
cc_init_sem(FALSE);
}
}
// grab image for active viewer
static void *grabnext(void _U_ *arg){
FNAME();
if(controlfd < 0) return NULL;
int sock = controlfd;
int lastImNo = curImNo(sock);
while(1){
if(!getWin()) exit(1);
TIMESTAMP("End of cycle, start new");
expstate = CAMERA_CAPTURE;
atomic_store(&expstate, CAMERA_CAPTURE);
DBG("Current state: %d", atomic_load(&expstate));
TIMEINIT();
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); // start capture
double timeout = GP->exptime + CC_CLIENT_TIMEOUT, t0 = sl_dtime();
useconds_t sleept = 500000; // 0.5s
if(GP->exptime < 0.5){
sleept = (useconds_t)(GP->exptime * 500000.);
if(sleept < 1000) sleept = 1000;
sleept = (useconds_t)(GP->exptime * 250000.); // a quater of exposition time
if(sleept < CC_IMWAIT_SLEEP) sleept = CC_IMWAIT_SLEEP;
}
// double exptime = GP->exptime;
TIMESTAMP("Wait for exposition ends (%g s), sleep for %dus", timeout, sleept);
int curst = CAMERA_CAPTURE;
while(sl_dtime() - t0 < timeout){
TIMESTAMP("Wait for exposition ends (%u us)", sleept);
DBG("start sleep for %dus", sleept);
usleep(sleept);
TIMESTAMP("check answer");
// getans(sock, NULL);
//TIMESTAMP("EXPSTATE ===> %d", expstate);
if(expstate != CAMERA_CAPTURE) break;
if(sl_dtime() - t0 < GP->exptime + 0.5) sleept = 1000;
SENDCMDW(CC_CMD_EXPSTATE);
curst = atomic_load(&expstate);
if(curst != CAMERA_CAPTURE) break;
if(sl_dtime() - t0 > GP->exptime && sleept != CC_IMWAIT_SLEEP){
DBG("Set sleeping time to %dus", sleept);
sleept = CC_IMWAIT_SLEEP;
}
}
if(sl_dtime() - t0 >= timeout || expstate != CAMERA_FRAMERDY){
WARNX("Image wasn't received");
int cur = curImNo(sock);
if(sl_dtime() - t0 >= timeout || curst != CAMERA_FRAMERDY || cur <= lastImNo){
WARNX("Image wasn't received, state: %d, waiting: %g, lastNo: %d, curNo: %d (timeout: %g)", curst, sl_dtime() - t0, lastImNo, cur, timeout);
continue;
}
TIMESTAMP("Frame ready");
getimage();
lastImNo = cur;
TIMESTAMP("Frame ready (%d from server's start)", cur);
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;
int lastImNo = curImNo(sock);
double t0 = sl_dtime();
while(1){
if(!getWin()) exit(1);
getans(sock, NULL);
if(expstate != CAMERA_FRAMERDY){
usleep(1000);
double tcur = sl_dtime();
if(tcur - t0 >= CC_WAIT_TIMEOUT){
SENDCMDW(CC_CMD_EXPSTATE); // `ping` server to know if it disconnected
t0 = tcur;
}
int cur = curImNo(sock);
if(cur <= lastImNo){
usleep(CC_IMWAIT_SLEEP);
continue;
}
TIMESTAMP("End of cycle, start new");
lastImNo = cur;
TIMESTAMP("End of cycle #%d, start new", cur);
TIMEINIT();
getimage();
expstate = CAMERA_IDLE;
getimage(FALSE);
atomic_store(&expstate, CAMERA_IDLE);
DBG("Current state: %d", atomic_load(&expstate));
}
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 +621,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;

View File

@@ -56,7 +56,7 @@ sl_option_t cmdlnopts[] = {
{"focdevno",NEED_ARG, NULL, NA, arg_int, APTR(&G.focdevno), N_("focuser device number (if many: 0, 1, 2 etc)")},
{"help", NO_ARGS, &help, 1, arg_none, NULL, N_("show this help")},
{"rewrite", NO_ARGS, &G.rewrite,1, arg_none, NULL, N_("rewrite output file if exists")},
{"verbose", NO_ARGS, NULL, 'V', arg_none, APTR(&G.verbose), N_("verbose level (-V - messages, -VV - debug, -VVV - all shit)")},
{"verbose", NO_ARGS, NULL, 'V', arg_none, APTR(&G.verbose), N_("verbose level (-V - main messages, -VV - secondary messages, -VVV - debug)")},
{"dark", NO_ARGS, NULL, 'd', arg_int, APTR(&G.dark), N_("not open shutter, when exposing (\"dark frames\")")},
{"8bit", NO_ARGS, NULL, '8', arg_int, APTR(&G._8bit), N_("run in 8-bit mode")},
{"fast", NO_ARGS, NULL, 'f', arg_none, APTR(&G.fast), N_("fast readout mode")},
@@ -71,7 +71,6 @@ sl_option_t cmdlnopts[] = {
{"prog-id", NEED_ARG, NULL, 'P', arg_string, APTR(&G.prog_id), N_("observing program name")},
{"addrec", MULT_PAR, NULL, 'r', arg_string, APTR(&G.addhdr), N_("add records to header from given file[s]")},
{"outfile", NEED_ARG, NULL, 'o', arg_string, APTR(&G.outfile), N_("output file name")},
{"wait", NO_ARGS, &G.waitexpend,1,arg_none, NULL, N_("wait while exposition ends")},
{"nflushes",NEED_ARG, NULL, 'l', arg_int, APTR(&G.nflushes), N_("N flushes before exposing (default: 1)")},
{"hbin", NEED_ARG, NULL, 'h', arg_int, APTR(&G.hbin), N_("horizontal binning to N pixels")},
@@ -111,6 +110,7 @@ sl_option_t cmdlnopts[] = {
{"viewer", NO_ARGS, &G.viewer,1, arg_none, NULL, N_("passive viewer (only get last images)")},
{"restart", NO_ARGS, &G.restart,1, arg_none, NULL, N_("restart image server")},
{"timeout", NEED_ARG, NULL, '0', arg_double, APTR(&G.anstmout), N_("network answer timeout (default: 0.1s)")},
{"info", NO_ARGS, &G.info, 1, arg_none, NULL, N_("get base information about connected hardware (also increasing text messages level to 2)")},
{"shmkey", NEED_ARG, NULL, 'k', arg_int, APTR(&G.shmkey), N_("shared memory (with image data) key (default: 7777777)")},
{"forceimsock",NO_ARGS, &G.forceimsock,1, arg_none, NULL, N_("force using image through socket transition even if can use SHM")},

View File

@@ -42,9 +42,9 @@ typedef struct{
char **addhdr; // list of files from which to add header records
char **plugincmd; // plugin commands
int restart; // restart server
int waitexpend; // wait while exposition ends
int cancelexpose; // cancel exp (for Grasshopper - forbid forever)
int client; // run as client
int info; // show main information about camera etc. in client's terminal
int viewer; // passive client (only get last images)
int listdevices; // list connected devices
int fanspeed; // fan speed: 0-2

Binary file not shown.

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-18 15:56+0300\n"
"POT-Creation-Date: 2026-06-08 17:06+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -62,7 +62,8 @@ msgid "rewrite output file if exists"
msgstr ""
#: cmdlnopts.c:59
msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)"
msgid ""
"verbose level (-V - main messages, -VV - secondary messages, -VVV - debug)"
msgstr ""
#: cmdlnopts.c:60
@@ -117,142 +118,144 @@ msgstr ""
msgid "output file name"
msgstr ""
#: cmdlnopts.c:74
msgid "wait while exposition ends"
msgstr ""
#: cmdlnopts.c:76
#: cmdlnopts.c:75
msgid "N flushes before exposing (default: 1)"
msgstr ""
#: cmdlnopts.c:77
#: cmdlnopts.c:76
msgid "horizontal binning to N pixels"
msgstr ""
#: cmdlnopts.c:78
#: cmdlnopts.c:77
msgid "vertical binning to N pixels"
msgstr ""
#: cmdlnopts.c:79
#: cmdlnopts.c:78
msgid "make series of N frames"
msgstr ""
#: cmdlnopts.c:80
#: cmdlnopts.c:79
msgid "make pause for N seconds between expositions"
msgstr ""
#: cmdlnopts.c:81
#: cmdlnopts.c:80
msgid "set exposure time to given value (seconds!)"
msgstr ""
#: cmdlnopts.c:82
#: cmdlnopts.c:81
msgid "cancel current exposition"
msgstr ""
#: cmdlnopts.c:83
#: cmdlnopts.c:82
msgid ""
"absolute (not divided by binning!) frame X0 coordinate (-1 - all with "
"overscan)"
msgstr ""
#: cmdlnopts.c:84
#: cmdlnopts.c:83
msgid "absolute frame Y0 coordinate (-1 - all with overscan)"
msgstr ""
#: cmdlnopts.c:85
#: cmdlnopts.c:84
msgid "absolute frame X1 coordinate (-1 - all with overscan)"
msgstr ""
#: cmdlnopts.c:86
#: cmdlnopts.c:85
msgid "absolute frame Y1 coordinate (-1 - all with overscan)"
msgstr ""
#: cmdlnopts.c:88
#: cmdlnopts.c:87
msgid "open shutter"
msgstr ""
#: cmdlnopts.c:89
#: cmdlnopts.c:88
msgid "close shutter"
msgstr ""
#: cmdlnopts.c:90
#: cmdlnopts.c:89
msgid "run exposition on LOW @ pin5 I/O port"
msgstr ""
#: cmdlnopts.c:91
#: cmdlnopts.c:90
msgid "run exposition on HIGH @ pin5 I/O port"
msgstr ""
#: cmdlnopts.c:92
#: cmdlnopts.c:91
msgid "get value of I/O port pins"
msgstr ""
#: cmdlnopts.c:93
#: cmdlnopts.c:92
msgid "move stepper motor asynchronous"
msgstr ""
#: cmdlnopts.c:95
#: cmdlnopts.c:94
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
msgstr ""
#: cmdlnopts.c:96
#: cmdlnopts.c:95
msgid ""
"configure I/O port pins to given value (decimal number, pin1 is LSB, 1 == "
"output, 0 == input)"
msgstr ""
#: cmdlnopts.c:98
#: cmdlnopts.c:97
msgid "move focuser to absolute position, mm"
msgstr ""
#: cmdlnopts.c:99
#: cmdlnopts.c:98
msgid "move focuser to relative position, mm (only for standalone)"
msgstr ""
#: cmdlnopts.c:101
#: cmdlnopts.c:100
msgid "set wheel position"
msgstr ""
#: cmdlnopts.c:103
#: cmdlnopts.c:102
msgid "CMOS gain level"
msgstr ""
#: cmdlnopts.c:104
#: cmdlnopts.c:103
msgid "CMOS brightness level"
msgstr ""
#: cmdlnopts.c:106
#: cmdlnopts.c:105
msgid "logging file name (if run as server)"
msgstr ""
#: cmdlnopts.c:107
#: cmdlnopts.c:106
msgid "UNIX socket name (command socket)"
msgstr ""
#: cmdlnopts.c:108
#: cmdlnopts.c:107
msgid "local INET command socket port"
msgstr ""
#: cmdlnopts.c:109
#: cmdlnopts.c:108
msgid "INET image socket port"
msgstr ""
#: cmdlnopts.c:110
#: cmdlnopts.c:109
msgid "run as client"
msgstr ""
#: cmdlnopts.c:111
#: cmdlnopts.c:110
msgid "passive viewer (only get last images)"
msgstr ""
#: cmdlnopts.c:112
#: cmdlnopts.c:111
msgid "restart image server"
msgstr ""
#: cmdlnopts.c:113
#: cmdlnopts.c:112
msgid "network answer timeout (default: 0.1s)"
msgstr ""
#: cmdlnopts.c:113
msgid ""
"get base information about connected hardware (also increasing text messages "
"level to 2)"
msgstr ""
#: cmdlnopts.c:115
msgid "shared memory (with image data) key (default: 7777777)"
msgstr ""
@@ -269,326 +272,352 @@ msgstr ""
msgid "Display image in OpenGL window"
msgstr ""
#: ccdfunc.c:198
msgid "Camera device unknown"
msgstr ""
#: ccdfunc.c:221
#: ccdfunc.c:216
#, c-format
msgid "Can't save file with prefix %s"
msgstr ""
#: ccdfunc.c:269
#: ccdfunc.c:276
#, c-format
msgid "File saved as '%s'"
msgstr ""
#: ccdfunc.c:278
#: ccdfunc.c:285
msgid "Error saving file"
msgstr ""
#: ccdfunc.c:333
#: ccdfunc.c:340
#, c-format
msgid "Image stat:\n"
msgstr ""
#: ccdfunc.c:342
#: ccdfunc.c:349
msgid "Focuser device not pointed"
msgstr ""
#: ccdfunc.c:349
#: ccdfunc.c:356
msgid "No focusers found"
msgstr ""
#: ccdfunc.c:379
#: ccdfunc.c:386
#, c-format
msgid "Found %d focusers, you point number %d"
msgstr ""
#: ccdfunc.c:383
#: ccdfunc.c:390
msgid "Can't set active focuser number"
msgstr ""
#: ccdfunc.c:397
#: ccdfunc.c:404
msgid "Can't get focuser limit positions"
msgstr ""
#: ccdfunc.c:404
#: ccdfunc.c:411
msgid "Can't get current focuser position"
msgstr ""
#: ccdfunc.c:418
#: ccdfunc.c:425
#, c-format
msgid "Can't set position %g: out of limits [%g, %g]"
msgstr ""
#: ccdfunc.c:422
#: ccdfunc.c:429
msgid "Can't home focuser"
msgstr ""
#: ccdfunc.c:424
#: ccdfunc.c:431
#, c-format
msgid "Can't set position %g"
msgstr ""
#: ccdfunc.c:430
#: ccdfunc.c:439
msgid "Wheel device not pointed"
msgstr ""
#: ccdfunc.c:437
#: ccdfunc.c:446
msgid "No wheels found"
msgstr ""
#: ccdfunc.c:467
#: ccdfunc.c:476
#, c-format
msgid "Found %d wheels, you point number %d"
msgstr ""
#: ccdfunc.c:471
#: ccdfunc.c:480
msgid "Can't set active wheel number"
msgstr ""
#: ccdfunc.c:487
#: ccdfunc.c:496
msgid "Can't get max wheel position"
msgstr ""
#: ccdfunc.c:494
#: ccdfunc.c:503
#, c-format
msgid "Wheel position should be from 0 to %d"
msgstr ""
#: ccdfunc.c:498
#: ccdfunc.c:507
#, c-format
msgid "Can't set wheel position %d"
msgstr ""
#: ccdfunc.c:511
#: ccdfunc.c:522
msgid "Camera plugin have no capture polling funtion."
msgstr ""
#: ccdfunc.c:517
#: ccdfunc.c:528
#, c-format
msgid "%.1f seconds till exposition ends"
msgstr ""
#: ccdfunc.c:532
#: ccdfunc.c:543
msgid "Camera device not pointed"
msgstr ""
#: ccdfunc.c:539 ccdfunc.c:540
#: ccdfunc.c:550 ccdfunc.c:551
msgid "No cameras found"
msgstr ""
#: ccdfunc.c:560
#: ccdfunc.c:571
msgid "Camera plugin have no model name getter"
msgstr ""
#: ccdfunc.c:571
#: ccdfunc.c:582
#, c-format
msgid "Found %d cameras, you point number %d"
msgstr ""
#: ccdfunc.c:575
#: ccdfunc.c:586
msgid "Can't set active camera number"
msgstr ""
#: ccdfunc.c:581
#: ccdfunc.c:592
msgid "Camera plugin have no custom commands"
msgstr ""
#: ccdfunc.c:606
#: ccdfunc.c:617
msgid "Camera plugin have no fun speed setter"
msgstr ""
#: ccdfunc.c:609
#: ccdfunc.c:620
msgid "Can't set fan speed"
msgstr ""
#: ccdfunc.c:610
#: ccdfunc.c:621
#, c-format
msgid "Set fan speed to %d"
msgstr ""
#: ccdfunc.c:615
#: ccdfunc.c:626
#, c-format
msgid "Camera model: %s"
msgstr ""
#: ccdfunc.c:616
#: ccdfunc.c:627
#, c-format
msgid "Pixel size: %g x %g"
msgstr ""
#: ccdfunc.c:622
#: ccdfunc.c:633
#, c-format
msgid "Full array: %s"
msgstr ""
#: ccdfunc.c:625
#: ccdfunc.c:636
#, c-format
msgid "Field of view: %s"
msgstr ""
#: ccdfunc.c:628
#: ccdfunc.c:639
#, c-format
msgid "Current format: %s"
msgstr ""
#: ccdfunc.c:630
#: ccdfunc.c:641
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 set T to %g degC"
msgstr ""
#: ccdfunc.c:651
#, c-format
msgid "Shutter command: %s\n"
msgstr ""
#: ccdfunc.c:653
#, c-format
msgid "Can't run shutter command %s (unsupported?)"
msgstr ""
#: ccdfunc.c:645
#: ccdfunc.c:656
#, c-format
msgid "Try to configure I/O port as %d"
msgstr ""
#: ccdfunc.c:647
#: ccdfunc.c:658
msgid "Can't configure (unsupported?)"
msgstr ""
#: ccdfunc.c:654
#: ccdfunc.c:665
msgid "Can't get IOport state (unsupported?)"
msgstr ""
#: ccdfunc.c:657
#: ccdfunc.c:668
#, c-format
msgid "Try to write %d to I/O port"
msgstr ""
#: ccdfunc.c:659
#: ccdfunc.c:670
msgid "Can't set IOport"
msgstr ""
#: ccdfunc.c:666
#: ccdfunc.c:677
#, c-format
msgid "Set gain to %g"
msgstr ""
#: ccdfunc.c:667
#: ccdfunc.c:678
#, c-format
msgid "Can't set gain to %g"
msgstr ""
#: ccdfunc.c:672
#: ccdfunc.c:683
#, c-format
msgid "Set brightness to %g"
msgstr ""
#: ccdfunc.c:673
#: ccdfunc.c:684
#, c-format
msgid "Can't set brightness to %g"
msgstr ""
#: ccdfunc.c:679 server.c:284
#: ccdfunc.c:690 server.c:330
#, c-format
msgid "Can't set binning %dx%d"
msgstr ""
#: ccdfunc.c:691 server.c:285
#: ccdfunc.c:702 server.c:331
msgid "Can't set given geometry"
msgstr ""
#: ccdfunc.c:695
#: ccdfunc.c:706
#, c-format
msgid "Can't set %d flushes"
msgstr ""
#: ccdfunc.c:698
#: ccdfunc.c:709
msgid "Camera plugin have no exposition setter"
msgstr ""
#: ccdfunc.c:700
#: ccdfunc.c:711
#, c-format
msgid "Can't set exposure time to %f seconds"
msgstr ""
#: ccdfunc.c:703
#: ccdfunc.c:714
msgid "Can't change frame type"
msgstr ""
#: ccdfunc.c:706
#: ccdfunc.c:717
msgid "Can't set bit depth"
msgstr ""
#: ccdfunc.c:708
#: ccdfunc.c:719
msgid "Can't set readout speed"
msgstr ""
#: ccdfunc.c:709
#: ccdfunc.c:720
#, c-format
msgid "Readout mode: %s"
msgstr ""
#: ccdfunc.c:710
#: ccdfunc.c:721
msgid "Only show statistics"
msgstr ""
#: ccdfunc.c:713
#: ccdfunc.c:724
msgid "Can't get current binning"
msgstr ""
#: ccdfunc.c:738
#: ccdfunc.c:749
#, c-format
msgid "Capture frame %d"
msgstr ""
#: ccdfunc.c:739 ccdfunc.c:816 server.c:153 server.c:154
#: ccdfunc.c:750 ccdfunc.c:827 server.c:194 server.c:195
msgid "Camera plugin have no function `start exposition`"
msgstr ""
#: ccdfunc.c:741 ccdfunc.c:818 server.c:159 server.c:160
#: ccdfunc.c:752 ccdfunc.c:829 server.c:200 server.c:201
msgid "Can't start exposition"
msgstr ""
#: ccdfunc.c:746
#: ccdfunc.c:757
msgid "Can't capture image"
msgstr ""
#: ccdfunc.c:749
#: ccdfunc.c:760
msgid "Read grabbed image"
msgstr ""
#: ccdfunc.c:751 ccdfunc.c:831 server.c:177 server.c:178
#: ccdfunc.c:762 ccdfunc.c:842 server.c:218 server.c:219
msgid "Camera plugin have no function `capture`"
msgstr ""
#: ccdfunc.c:753 ccdfunc.c:832
#: ccdfunc.c:764 ccdfunc.c:843
msgid "Can't grab image"
msgstr ""
#: ccdfunc.c:767 client.c:289
#: ccdfunc.c:778 client.c:491
#, c-format
msgid "%d seconds till pause ends\n"
msgstr ""
#: ccdfunc.c:829
#: ccdfunc.c:840
msgid "Some error when capture"
msgstr ""
#: server.c:205
#: server.c:247
msgid "No camera device"
msgstr ""
#: client.c:275
#: client.c:449
msgid "Can't make exposition"
msgstr ""
#: client.c:305
#: client.c:503
msgid "Server timeout"
msgstr ""
#: imageview.c:51
msgid "Already initialized!"
msgstr ""
#: imageview.c:312
msgid "Can't init mutex!"
msgstr ""
#: imageview.c:425
#, c-format
msgid "Histogram conversion: %s"
msgstr ""
#: imageview.c:704
msgid "Can't open OpenGL window, image preview will be inaccessible"
msgstr ""
#: imageview.c:746
#, c-format
msgid "Equalization of histogram: %s"
msgstr ""
#: imageview.c:746
msgid "on"
msgstr ""
#: imageview.c:746
msgid "off"
msgstr ""

View File

@@ -7,7 +7,7 @@
msgid ""
msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-18 15:55+0300\n"
"POT-Creation-Date: 2026-06-08 16:46+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -16,217 +16,225 @@ msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Content-Type: text/plain; charset=koi8-r\n"
"Content-Transfer-Encoding: 8bit\n"
#: ccdfunc.c:517
#: ccdfunc.c:528
#, c-format
msgid "%.1f seconds till exposition ends"
msgstr "%.1f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ"
#: ccdfunc.c:767 client.c:289
#: ccdfunc.c:778 client.c:491
#, c-format
msgid "%d seconds till pause ends\n"
msgstr "%d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n"
#: cmdlnopts.c:104
#: imageview.c:51
msgid "Already initialized!"
msgstr "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!"
#: cmdlnopts.c:103
msgid "CMOS brightness level"
msgstr "ÕÒÏ×ÅÎØ ÑÒËÏÓÔÉ CMOS"
#: cmdlnopts.c:103
#: cmdlnopts.c:102
msgid "CMOS gain level"
msgstr "ÕÒÏ×ÅÎØ Gain CMOS"
#: ccdfunc.c:532
#: ccdfunc.c:543
msgid "Camera device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÐÏÄËÌÀÞÅÎÏ"
#: ccdfunc.c:198
msgid "Camera device unknown"
msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÏÐÏÚÎÁÎÏ"
#: ccdfunc.c:615
#: ccdfunc.c:626
#, c-format
msgid "Camera model: %s"
msgstr "íÏÄÅÌØ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ: %s"
#: ccdfunc.c:511
#: ccdfunc.c:522
#, fuzzy
msgid "Camera plugin have no capture polling funtion."
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:581
#: ccdfunc.c:592
msgid "Camera plugin have no custom commands"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:698
#: ccdfunc.c:709
#, fuzzy
msgid "Camera plugin have no exposition setter"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:606
#: ccdfunc.c:617
#, fuzzy
msgid "Camera plugin have no fun speed setter"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:751 ccdfunc.c:831 server.c:177 server.c:178
#: ccdfunc.c:762 ccdfunc.c:842 server.c:218 server.c:219
#, fuzzy
msgid "Camera plugin have no function `capture`"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:739 ccdfunc.c:816 server.c:153 server.c:154
#: ccdfunc.c:750 ccdfunc.c:827 server.c:194 server.c:195
#, fuzzy
msgid "Camera plugin have no function `start exposition`"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:560
#: ccdfunc.c:571
#, fuzzy
msgid "Camera plugin have no model name getter"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:630
#: ccdfunc.c:641
#, fuzzy
msgid "Camera plugin have no temperature setter"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:746
#: ccdfunc.c:757
msgid "Can't capture image"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:703
#: ccdfunc.c:714
msgid "Can't change frame type"
msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÔÉÐ ËÁÄÒÁ"
#: ccdfunc.c:647
#: ccdfunc.c:658
msgid "Can't configure (unsupported?)"
msgstr "îÅ ÍÏÇÕ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ (ÏÐÃÉÑ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#: ccdfunc.c:654
#: ccdfunc.c:665
msgid "Can't get IOport state (unsupported?)"
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÓÏÓÔÏÑÎÉÅ ÐÏÒÔÁ I/O (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#: ccdfunc.c:713
#: ccdfunc.c:724
msgid "Can't get current binning"
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÔÅËÕÝÅÅ ÚÎÁÞÅÎÉÅ ÂÉÎÎÉÎÇÁ"
#: ccdfunc.c:404
#: ccdfunc.c:411
msgid "Can't get current focuser position"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÔÅËÕÝÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:397
#: ccdfunc.c:404
msgid "Can't get focuser limit positions"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:487
#: ccdfunc.c:496
msgid "Can't get max wheel position"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ËÏÌÅÓÁ"
#: ccdfunc.c:753 ccdfunc.c:832
#: ccdfunc.c:764 ccdfunc.c:843
msgid "Can't grab image"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:422
#: ccdfunc.c:429
msgid "Can't home focuser"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÆÏËÕÓÅÒ × ÎÕÌØ"
#: client.c:275
#: imageview.c:312
msgid "Can't init mutex!"
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
#: client.c:449
msgid "Can't make exposition"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ÜËÓÐÏÚÉÃÉÀ"
#: ccdfunc.c:642
#: imageview.c:704
msgid "Can't open OpenGL window, image preview will be inaccessible"
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÏËÎÏ OpenGL, ÏÔÏÂÒÁÖÅÎÉÅ ÂÕÄÅÔ ÎÅÄÏÓÔÕÐÎÏ"
#: ccdfunc.c:653
#, c-format
msgid "Can't run shutter command %s (unsupported?)"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ËÏÍÁÎÄÕ ÚÁÔ×ÏÒÁ %s (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#: ccdfunc.c:221
#: ccdfunc.c:216
#, c-format
msgid "Can't save file with prefix %s"
msgstr "îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ Ó ÐÒÅÆÉËÓÏÍ %s"
#: ccdfunc.c:695
#: ccdfunc.c:706
#, c-format
msgid "Can't set %d flushes"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ %d ÓÂÒÏÓÏ×"
#: ccdfunc.c:659
#: ccdfunc.c:670
msgid "Can't set IOport"
msgstr "îÅ ÍÏÇÕ ÐÏÍÅÎÑÔØ ÚÎÁÞÅÎÉÑ ÐÏÒÔÁ I/O"
#: ccdfunc.c:631
#: ccdfunc.c:642
#, c-format
msgid "Can't set T to %g degC"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ × %g ÇÒÁÄã"
#: ccdfunc.c:575
#: ccdfunc.c:586
msgid "Can't set active camera number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÊ ËÁÍÅÒÙ"
#: ccdfunc.c:383
#: ccdfunc.c:390
msgid "Can't set active focuser number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:471
#: ccdfunc.c:480
msgid "Can't set active wheel number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ"
#: ccdfunc.c:679 server.c:284
#: ccdfunc.c:690 server.c:330
#, c-format
msgid "Can't set binning %dx%d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d"
#: ccdfunc.c:706
#: ccdfunc.c:717
msgid "Can't set bit depth"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÒÁÚÒÑÄÎÏÓÔØ áãð"
#: ccdfunc.c:673
#: ccdfunc.c:684
#, c-format
msgid "Can't set brightness to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
#: ccdfunc.c:700
#: ccdfunc.c:711
#, c-format
msgid "Can't set exposure time to %f seconds"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÜËÓÐÏÚÉÃÉÀ × %f ÓÅËÕÎÄ"
#: ccdfunc.c:609
#: ccdfunc.c:620
msgid "Can't set fan speed"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ×"
#: ccdfunc.c:667
#: ccdfunc.c:678
#, c-format
msgid "Can't set gain to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
#: ccdfunc.c:691 server.c:285
#: ccdfunc.c:702 server.c:331
msgid "Can't set given geometry"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ"
#: ccdfunc.c:424
#: ccdfunc.c:431
#, c-format
msgid "Can't set position %g"
msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÐÏÚÉÃÉÀ ÎÁ %g"
#: ccdfunc.c:418
#: ccdfunc.c:425
#, c-format
msgid "Can't set position %g: out of limits [%g, %g]"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÚÉÃÉÀ %g: ×ÎÅ ÐÒÅÄÅÌÏ× [%g, %g]"
#: ccdfunc.c:708
#: ccdfunc.c:719
msgid "Can't set readout speed"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ÓÞÉÔÙ×ÁÎÉÑ"
#: ccdfunc.c:498
#: ccdfunc.c:507
#, c-format
msgid "Can't set wheel position %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ %d"
#: ccdfunc.c:741 ccdfunc.c:818 server.c:159 server.c:160
#: ccdfunc.c:752 ccdfunc.c:829 server.c:200 server.c:201
msgid "Can't start exposition"
msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ"
#: ccdfunc.c:738
#: ccdfunc.c:749
#, c-format
msgid "Capture frame %d"
msgstr "úÁÈ×ÁÔ ËÁÄÒÁ %d"
#: ccdfunc.c:628
#: ccdfunc.c:639
#, c-format
msgid "Current format: %s"
msgstr "ôÅËÕÝÉÊ ÆÏÒÍÁÔ: %s"
@@ -235,157 +243,167 @@ msgstr "
msgid "Display image in OpenGL window"
msgstr "ÏÔÏÂÒÁÖÅÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ × ÏËÎÅ OpenGL"
#: ccdfunc.c:278
#: imageview.c:746
#, c-format
msgid "Equalization of histogram: %s"
msgstr "üË×ÁÌÉÚÁÃÉÑ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
#: ccdfunc.c:285
msgid "Error saving file"
msgstr "ïÛÉÂËÁ ÓÏÈÒÁÎÅÎÉÑ ÆÁÊÌÁ"
#: ccdfunc.c:625
#: ccdfunc.c:636
#, c-format
msgid "Field of view: %s"
msgstr "ðÏÌÅ ÚÒÅÎÉÑ: %s"
#: ccdfunc.c:269
#: ccdfunc.c:276
#, c-format
msgid "File saved as '%s'"
msgstr "æÁÊÌ ÓÏÈÒÁÎÅÎ ËÁË '%s'"
#: ccdfunc.c:342
#: ccdfunc.c:349
msgid "Focuser device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï ÆÏËÕÓÅÒÁ ÎÅ ÕËÁÚÁÎÏ"
#: ccdfunc.c:571
#: ccdfunc.c:582
#, c-format
msgid "Found %d cameras, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÁÍÅÒ, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:379
#: ccdfunc.c:386
#, c-format
msgid "Found %d focusers, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ÆÏËÕÓÅÒÏ×, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:467
#: ccdfunc.c:476
#, c-format
msgid "Found %d wheels, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÏÌÅÓ, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:622
#: ccdfunc.c:633
#, c-format
msgid "Full array: %s"
msgstr "ðÏÌÎÙÊ ÆÏÒÍÁÔ: %s"
#: cmdlnopts.c:109
#: imageview.c:425
#, c-format
msgid "Histogram conversion: %s"
msgstr "ðÒÅÏÂÒÁÚÏ×ÁÎÉÅ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
#: cmdlnopts.c:108
msgid "INET image socket port"
msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ ÐÅÒÅÄÁÞÉ ÉÚÏÂÒÁÖÅÎÉÑ"
#: ccdfunc.c:333
#: ccdfunc.c:340
#, c-format
msgid "Image stat:\n"
msgstr "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ: \n"
#: cmdlnopts.c:76
#: cmdlnopts.c:75
msgid "N flushes before exposing (default: 1)"
msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)"
#: server.c:205
#: server.c:247
msgid "No camera device"
msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ"
#: ccdfunc.c:539 ccdfunc.c:540
#: ccdfunc.c:550 ccdfunc.c:551
msgid "No cameras found"
msgstr "ëÁÍÅÒ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:349
#: ccdfunc.c:356
msgid "No focusers found"
msgstr "æÏËÕÓÅÒÏ× ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:437
#: ccdfunc.c:446
msgid "No wheels found"
msgstr "ôÕÒÅÌÅÊ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:710
#: ccdfunc.c:721
msgid "Only show statistics"
msgstr "ôÏÌØËÏ ÏÔÏÂÒÁÚÉÔØ ÓÔÁÔÉÓÔÉËÕ"
#: ccdfunc.c:616
#: ccdfunc.c:627
#, c-format
msgid "Pixel size: %g x %g"
msgstr "òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g"
#: ccdfunc.c:749
#: ccdfunc.c:760
msgid "Read grabbed image"
msgstr "óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ"
#: ccdfunc.c:709
#: ccdfunc.c:720
#, c-format
msgid "Readout mode: %s"
msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s"
#: client.c:305
#: client.c:503
msgid "Server timeout"
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
#: ccdfunc.c:672
#: ccdfunc.c:683
#, c-format
msgid "Set brightness to %g"
msgstr "õÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
#: ccdfunc.c:610
#: ccdfunc.c:621
#, c-format
msgid "Set fan speed to %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ× × %d"
#: ccdfunc.c:666
#: ccdfunc.c:677
#, c-format
msgid "Set gain to %g"
msgstr "õÓÔÁÎÏ×ÉÔØ Gain × %g"
#: ccdfunc.c:640
#: ccdfunc.c:651
#, c-format
msgid "Shutter command: %s\n"
msgstr "ëÏÍÁÎÄÁ ÚÁÔ×ÏÒÁ: %s\n"
#: ccdfunc.c:829
#: ccdfunc.c:840
msgid "Some error when capture"
msgstr "ïÛÉÂËÁ ÐÒÉ ÚÁÈ×ÁÔÅ"
#: ccdfunc.c:645
#: ccdfunc.c:656
#, c-format
msgid "Try to configure I/O port as %d"
msgstr "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d"
#: ccdfunc.c:657
#: ccdfunc.c:668
#, c-format
msgid "Try to write %d to I/O port"
msgstr "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O"
#: cmdlnopts.c:107
#: cmdlnopts.c:106
msgid "UNIX socket name (command socket)"
msgstr "ÉÍÑ UNIX-ÓÏËÅÔÁ"
#: ccdfunc.c:430
#: ccdfunc.c:439
msgid "Wheel device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï ÔÕÒÅÌÉ ÎÅ ÕËÁÚÁÎÏ"
#: ccdfunc.c:494
#: ccdfunc.c:503
#, c-format
msgid "Wheel position should be from 0 to %d"
msgstr "ðÏÚÉÃÉÑ ËÏÌÅÓÁ ÄÏÌÖÎÁ ÂÙÔØ ÏÔ 0 ÄÏ %d"
#: cmdlnopts.c:83
#: cmdlnopts.c:82
msgid "absolute (not divided by binning!) frame X0 coordinate (-1 - all "
"with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ (ÎÅ ÄÅÌÅÎÎÁÑ ÎÁ ÂÉÎÎÉÎÇ!) ËÏÏÒÄÉÎÁÔÁ X0 (-1 - ×ËÌÀÞÁÑ "
"Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:85
#: cmdlnopts.c:84
msgid "absolute frame X1 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ X1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:84
#: cmdlnopts.c:83
msgid "absolute frame Y0 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ Y0 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:86
#: cmdlnopts.c:85
msgid "absolute frame Y1 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ Y1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
@@ -401,11 +419,11 @@ msgstr "
msgid "camera device plugin (e.g. devfli.so)"
msgstr "ÐÌÁÇÉÎ ËÁÍÅÒÙ (ÎÁÐÒÉÍÅÒ, devfli.so)"
#: cmdlnopts.c:82
#: cmdlnopts.c:81
msgid "cancel current exposition"
msgstr "ÏÔÍÅÎÁ ÔÅËÕÝÅÊ ÜËÓÐÏÚÉÃÉÉ"
#: cmdlnopts.c:89
#: cmdlnopts.c:88
msgid "close shutter"
msgstr "ÚÁËÒÙÔØ ÚÁÔ×ÏÒ"
@@ -413,7 +431,7 @@ msgstr "
msgid "common device plugin (e.g devfli.so)"
msgstr "ÏÂÝÉÊ ÐÌÁÇÉÎ ÄÌÑ ×ÓÅÈ ÕÓÔÒÏÊÓÔ× (ÎÁÐÒÉÍÅÒ, devfli.so)"
#: cmdlnopts.c:96
#: cmdlnopts.c:95
msgid "configure I/O port pins to given value (decimal number, pin1 is LSB, "
"1 == output, 0 == input)"
msgstr "ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O × ÚÁÄÁÎÎÏÅ ÓÏÓÔÏÑÎÉÅ (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, "
@@ -444,11 +462,16 @@ msgid "force using image through socket transition even if can use SHM"
msgstr "ÐÒÉÎÕÄÉÔÅÌØÎÏ ÂÒÁÔØ ÉÚÏÂÒÁÖÅÎÉÑ ÉÚ ÓÏËÅÔÁ ÄÁÖÅ ÅÓÌÉ ×ÏÚÍÏÖÎÏ "
"ÐÏÌØÚÏ×ÁÔØÓÑ ÒÁÚÄÅÌÑÅÍÏÊ ÐÁÍÑÔØÀ"
#: cmdlnopts.c:92
#: cmdlnopts.c:113
msgid "get base information about connected hardware (also increasing text "
"messages level to 2)"
msgstr ""
#: cmdlnopts.c:91
msgid "get value of I/O port pins"
msgstr "ÐÏÌÕÞÉÔØ ÚÎÁÞÅÎÉÅ ÐÏÒÔÁ I/O"
#: cmdlnopts.c:77
#: cmdlnopts.c:76
msgid "horizontal binning to N pixels"
msgstr "ÇÏÒÉÚÏÎÔÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ"
@@ -460,36 +483,36 @@ msgstr "
msgid "list connected devices"
msgstr "ÓÐÉÓÏË ÐÏÄËÌÀÞÅÎÎÙÈ ÕÓÔÒÏÊÓÔ×"
#: cmdlnopts.c:108
#: cmdlnopts.c:107
msgid "local INET command socket port"
msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ"
#: cmdlnopts.c:106
#: cmdlnopts.c:105
msgid "logging file name (if run as server)"
msgstr "ÉÍÑ ÆÁÊÌÁ ÌÏÇÇÉÒÏ×ÁÎÉÑ (ÅÓÌÉ ÚÁÐÕÝÅÎ ÓÅÒ×ÅÒ)"
#: cmdlnopts.c:80
#: cmdlnopts.c:79
msgid "make pause for N seconds between expositions"
msgstr "ÐÁÕÚÁ × N ÓÅËÕÎÄ ÍÅÖÄÕ ÜËÓÐÏÚÉÃÉÑÍÉ"
#: cmdlnopts.c:79
#: cmdlnopts.c:78
msgid "make series of N frames"
msgstr "ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ ÉÚ N ËÁÄÒÏ×"
#: cmdlnopts.c:98
#: cmdlnopts.c:97
msgid "move focuser to absolute position, mm"
msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÁÂÓÏÌÀÔÎÏÅ ÐÏÌÏÖÅÎÉÅ, ÍÍ"
#: cmdlnopts.c:99
#: cmdlnopts.c:98
msgid "move focuser to relative position, mm (only for standalone)"
msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÏÔÎÏÓÉÔÅÌØÎÏÅ ÐÏÌÏÖÅÎÉÅ, ÍÍ (ÎÅ ÄÌÑ ÓÅÒ×ÅÒ/"
"ËÌÉÅÎÔ)"
#: cmdlnopts.c:93
#: cmdlnopts.c:92
msgid "move stepper motor asynchronous"
msgstr "ÁÓÉÎÈÒÏÎÎÏÅ Ä×ÉÖÅÎÉÅ ÛÁÇÏ×ÏÇÏ Ä×ÉÇÁÔÅÌÑ"
#: cmdlnopts.c:113
#: cmdlnopts.c:112
msgid "network answer timeout (default: 0.1s)"
msgstr ""
@@ -513,7 +536,15 @@ msgstr "
msgid "observing program name"
msgstr "ÎÁÚ×ÁÎÉÅ ÐÒÏÇÒÁÍÍÙ"
#: cmdlnopts.c:88
#: imageview.c:746
msgid "off"
msgstr "×ÙËÌ"
#: imageview.c:746
msgid "on"
msgstr "×ËÌ"
#: cmdlnopts.c:87
msgid "open shutter"
msgstr "ÏÔËÒÙÔØ ÚÁÔ×ÏÒ"
@@ -521,7 +552,7 @@ msgstr "
msgid "output file name"
msgstr "ÉÍÑ ÆÁÊÌÁ"
#: cmdlnopts.c:111
#: cmdlnopts.c:110
msgid "passive viewer (only get last images)"
msgstr "ÐÁÓÓÉ×ÎÙÊ ÐÒÏÓÍÏÔÒ (ÔÏÌØËÏ ÐÏÓÌÅÄÎÉÅ ËÁÄÒÙ)"
@@ -529,7 +560,7 @@ msgstr "
msgid "program author"
msgstr "Á×ÔÏÒ ÐÒÏÇÒÁÍÍÙ"
#: cmdlnopts.c:112
#: cmdlnopts.c:111
msgid "restart image server"
msgstr "ÐÅÒÅÚÁÐÕÓË ÓÅÒ×ÅÒÁ"
@@ -537,15 +568,15 @@ msgstr "
msgid "rewrite output file if exists"
msgstr "ÐÅÒÅÚÁÐÉÓØ ×ÙÈÏÄÎÏÇÏ ÆÁÊÌÁ"
#: cmdlnopts.c:110
#: cmdlnopts.c:109
msgid "run as client"
msgstr "ÚÁÐÕÓÔÉÔØ ËÌÉÅÎÔ"
#: cmdlnopts.c:91
#: cmdlnopts.c:90
msgid "run exposition on HIGH @ pin5 I/O port"
msgstr "ÚÁÐÕÓË ÜËÓÐÏÚÉÃÉÉ ÐÏ ÷ùóïëïíõ ÓÉÇÎÁÌÕ ÎÁ ËÏÎÔÁËÔÅ 5 ÐÏÒÔÁ I/O"
#: cmdlnopts.c:90
#: cmdlnopts.c:89
msgid "run exposition on LOW @ pin5 I/O port"
msgstr "ÚÁÐÕÓË ÜËÓÐÏÚÉÃÉÉ ÐÏ îéúëïíõ ÓÉÇÎÁÌÕ ÎÁ ËÏÎÔÁËÔÅ 5 ÐÏÒÔÁ I/O"
@@ -557,11 +588,11 @@ msgstr "8-
msgid "set CCD temperature to given value (degr C)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ (ÇÒÁÄã)"
#: cmdlnopts.c:95
#: cmdlnopts.c:94
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÏÒÔ I/O (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, pin1 - ÍÌÁÄÛÉÊ ÂÉÔ)"
#: cmdlnopts.c:81
#: cmdlnopts.c:80
msgid "set exposure time to given value (seconds!)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ×ÒÅÍÑ ÜËÓÐÏÚÉÃÉÉ (ÓÅËÕÎÄÙ!)"
@@ -569,7 +600,7 @@ msgstr "
msgid "set fan speed (0 - off, 1 - low, 2 - high)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÁ (0 - ×ÙËÌ, 1 - ÎÉÚËÁÑ, 2 - ×ÙÓÏËÁÑ)"
#: cmdlnopts.c:101
#: cmdlnopts.c:100
msgid "set wheel position"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ"
@@ -586,40 +617,21 @@ 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)"
#, fuzzy
msgid "verbose level (-V - main messages, -VV - secondary messages, -VVV - "
"debug)"
msgstr "ÕÒÏ×ÅÎØ ÂÏÌÔÌÉ×ÏÓÔÉ (-V - ÓÏÏÂÝÅÎÉÑ, -VV - ÏÔÌÁÄËÁ, -VVV - ×ÓÅ)"
#: cmdlnopts.c:78
#: cmdlnopts.c:77
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 "Camera device unknown"
#~ 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 "×ËÌ"
#~ msgid "wait while exposition ends"
#~ msgstr "ÖÄÁÔØ, ÐÏËÁ ÎÅ ËÏÎÞÉÔÓÑ ÜËÓÐÏÚÉÃÉÑ"

View File

@@ -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 <EMAIL@ADDRESS>, 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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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)"

9
main.c
View File

@@ -34,6 +34,7 @@
#ifdef IMAGEVIEW
#include "imageview.h"
#endif
#include "server.h"
#include "socket.h"
static int isserver = FALSE;
@@ -56,6 +57,7 @@ void signals(int signo){
if(signo) WARNX("Get signal %d - exit", signo);
if(!GP->client){
DBG("Cancel capturing and close all");
stop_server();
camstop();
closewheel();
focclose();
@@ -107,11 +109,14 @@ int main(int argc, char **argv){
if(!GP->client) isserver = TRUE;
}
if(GP->path && !GP->client) isserver = TRUE;
if(!GP->path && !GP->port){
WARNX("Point one of options: `port` or `path` for command socket");
}
if((isserver || GP->client) && !GP->imageport){
GP->imageport = MALLOC(char, 32);
if(!GP->port) sprintf(GP->imageport, "12345");
else snprintf(GP->imageport, 31, "%d", 1+atoi(GP->port));
verbose(1, "Set image port to %s", GP->imageport);
printf("Set image port to %s\n", GP->imageport);
}
if(GP->client && (GP->commondev || GP->focuserdev || GP->cameradev || GP->wheeldev))
ERRX("Can't be client and standalone in same time!");
@@ -123,12 +128,14 @@ int main(int argc, char **argv){
OPENLOG(GP->logfile, lvl, 1);
if(!sl_globlog) WARNX("Can't create log file");
}
if(GP->info && GP->verbose < 2) GP->verbose = 2; // increase verbose messages level for `info`
signal(SIGINT, signals);
signal(SIGQUIT, signals);
signal(SIGABRT, signals);
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;

553
server.c
View File

@@ -16,13 +16,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdatomic.h>
#include <fcntl.h>
#include <netdb.h>
#include <pthread.h>
#include <poll.h>
#include <stdatomic.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <usefull_macros.h>
#include "ccdfunc.h"
@@ -38,15 +41,15 @@ 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;
static int isrunning = 1;
typedef struct{
const char *key;
@@ -55,36 +58,36 @@ typedef struct{
// cat | awk '{print "{ " $3 ", \"\" }," }' | sort
strpair allcommands[] = {
{ CC_CMD_8BIT, "run in 8 bit mode instead of 16 bit" },
{ CC_CMD_AUTHOR, "FITS 'AUTHOR' field" },
{ CC_CMD_BRIGHTNESS, "camera brightness" },
{ CC_CMD_CAMDEVNO, "camera device number" },
{ CC_CMD_CAMFLAGS, "get camflags (bits: 0-start capture, 1-cancel, 2-restart server"},
{ CC_CMD_CAMLIST, "list all connected cameras" },
{ CC_CMD_CAMFANSPD, "fan speed of camera" },
{ CC_CMD_CONFIO, "camera IO configuration" },
{ CC_CMD_DARK, "don't open shutter @ exposure" },
{ CC_CMD_EXPSTATE, "get exposition state (0: cancel, 1: capturing, 2: frame ready, 3: error) "
"or set (0: cancel, 1: start exp)\n also get camflags (bits: 0-start capture, 1-cancel, 2-restart server" },
"or set (0: cancel, 1: start exp)\n" },
{ 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_FMAXPOS, "get maximal focuser position"},
{ CC_CMD_FMINPOS, "get minimal focuser position"},
{ CC_CMD_FGOTO, "focuser position" },
{ CC_CMD_FTEMP, "get focuser body temperature"},
{ CC_CMD_FRAMEFORMAT, "camera frame format (X0,Y0,X1,Y1)" },
{ 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_IMNUMBER, "grabbed image number from server start"},
{ CC_CMD_IMWIDTH, "last image width" },
{ CC_CMD_INFO, "connected devices state" },
{ 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_8BIT, "run in 8 bit mode instead of 16 bit" },
{ CC_CMD_FRAMEMAX, "camera maximal available format" },
{ CC_CMD_NFLUSHES, "camera number of preflushes" },
{ CC_CMD_OBJECT, "FITS 'OBJECT' field" },
@@ -93,7 +96,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" },
@@ -101,7 +103,9 @@ strpair allcommands[] = {
{ CC_CMD_VBIN, "vertical binning" },
{ CC_CMD_WDEVNO, "wheel device number" },
{ CC_CMD_WLIST, "list all connected wheels" },
{ CC_CMD_WMAXPOS, "get maximap wheel position"},
{ CC_CMD_WPOS, "wheel position" },
{ CC_CMD_WTEMP, "get wheel body temperature"},
{NULL, NULL},
};
@@ -113,21 +117,55 @@ static int lock(){
//DBG("\n\nAlready locked");
return FALSE;
}
//DBG("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");
}
//DBG("UNLOCK()");
}
static cc_IMG *ima = NULL;
// cleanup semaphore, stop server processes
void stop_server(){
isrunning = 0;
double t0 = sl_dtime();
// wait no more than 1s for graceful closing
while(sl_dtime() - t0 < 1.){
if(isrunning == -1) break;
usleep(1000);
}
// destroy semaphore
cc_remove_sem();
}
static void fixima(){
FNAME();
if(!camera) return;
double t0 = sl_dtime();
int locked = FALSE;
TIMESTAMP("Lock socket");
// lock socket operations
while(!(locked = lock()) && sl_dtime() - t0 < 0.5) usleep(1000);
if(!locked){
DBG("Still locked from outside -> unlock/lock");
while(!lock()) unlock(); // force unlocking if can't do this gracefully
}else DBG("LOCK takes %gs", sl_dtime()-t0);
int raw_width = curformat.w / GP->hbin, raw_height = curformat.h / GP->vbin;
TIMESTAMP("Check SHM image");
// allocate memory for largest possible image
if(!ima) ima = cc_getshm(GP->shmkey, camera->array.h * camera->array.w * 2);
if(!ima) ERRX("Can't allocate memory for image");
if(!ima){
ima = cc_getshm(GP->shmkey, camera->array.h * camera->array.w * 2);
if(!ima) ERR("Can't allocate memory for image");
// init shared semaphore
cc_init_sem(TRUE);
}
TIMESTAMP("Lock SHM image");
cc_lock_shm(TRUE);
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 +178,9 @@ 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);
cc_unlock_shm();
unlock();
TIMESTAMP("All OK");
}
// functions for processCAM finite state machine
@@ -169,8 +210,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,19 +220,20 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends
camstate = CAMERA_ERROR;
return;
}
cc_lock_shm(TRUE);
if(!camera->capture(ima)){
LOGERR("Can't capture image");
camstate = CAMERA_ERROR;
return;
}else{
TIMESTAMP("Fill FITS header");
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");
}
cc_unlock_shm();
TIMESTAMP("Captured and unlocked");
}
camstate = CAMERA_FRAMERDY;
}
@@ -205,12 +247,21 @@ static void* processCAM(_U_ void *d){
ERRX(_("No camera device"));
}
double logt = 0;
while(1){
#ifdef EBUG
double T = sl_dtime();
#endif
while(isrunning){
if(camflags & FLAG_RESTARTSERVER){
LOGERR("User asks to restart");
signals(1);
}
usleep(100);
#ifdef EBUG
if(sl_dtime() - T > 5.){
T = sl_dtime();
printf("\t\t\tprocessCAM(), 5 seconds\n");
}
#endif
usleep(1000);
if(tremain < 0.5 && tremain > 0.) usleep(tremain*1e6);
if(lock()){
// log
@@ -237,22 +288,17 @@ static void* processCAM(_U_ void *d){
unlock();
continue;
}
unlock();
cc_camera_state curstate = camstate;
switch(curstate){
case CAMERA_IDLE:
cameraidlestate();
break;
case CAMERA_CAPTURE:
cameracapturestate();
break;
case CAMERA_FRAMERDY:
// do nothing: when `server` got this state it sends "expstate=2" to all clients and changes state to IDLE
break;
case CAMERA_ERROR:
// do nothing: when `server` got this state it sends "expstate=3" to all clients and changes state to IDLE
default:
cameraidlestate();
break;
}
unlock();
}
}
return NULL;
@@ -267,8 +313,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 +337,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 +349,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,9 +369,8 @@ 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];
// 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);
if(!ima) return CC_RESULT_FAIL;
snprintf(buf, 63, "%s=%d", key, (0 == strcmp(key, CC_CMD_IMHEIGHT)) ? ima->h : ima->w);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
@@ -338,7 +383,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 +396,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 +417,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){
@@ -517,19 +493,21 @@ static cc_hresult camfanhandler(int fd, _U_ const char *key, _U_ const char *val
}
const char *shutterstr[] = {"open", "close", "expose @high", "expose @low"};
static cc_hresult shutterhandler(_U_ int fd, _U_ const char *key, const char *val){
char buf[64];
if(!camera->shuttercmd) return CC_RESULT_FAIL;
if(val){
int x = atoi(val);
if(x < 0 || x >= SHUTTER_AMOUNT) return CC_RESULT_BADVAL;
int r = camera->shuttercmd((cc_shutter_op)x);
if(r){
LOGMSG("Shutter command '%s'", shutterstr[x]);
}else{
LOGWARN("Can't run shutter command '%s'", shutterstr[x]);
return CC_RESULT_FAIL;
}
if(!val) return CC_RESULT_BADVAL;
int x = atoi(val);
if(x < 0 || x >= SHUTTER_AMOUNT) return CC_RESULT_BADVAL;
int r = camera->shuttercmd((cc_shutter_op)x);
if(r){
LOGMSG("Shutter command '%s'", shutterstr[x]);
}else{
LOGWARN("Can't run shutter command '%s'", shutterstr[x]);
return CC_RESULT_FAIL;
}
return CC_RESULT_OK;
snprintf(buf, 63, "%s=%d", key, x);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult confiohandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
char buf[64];
@@ -636,29 +614,33 @@ static cc_hresult nflusheshandler(_U_ int fd, _U_ const char *key, _U_ const cha
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult expstatehandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
static cc_hresult expstatehandler(int fd, _U_ const char *key, const char *val){
char buf[64];
if(val){
int n = atoi(val);
if(n == CAMERA_IDLE){ // cancel expositions
camflags |= FLAG_CANCEL;
return CC_RESULT_OK;
}
else if(n == CAMERA_CAPTURE){ // start exposition
if(GP->exptime < 1e-9){
snprintf(buf, 63, CC_CMD_EXPOSITION "=%g", GP->exptime);
cc_sendstrmessage(fd, buf);
if(GP->exptime < 1e-9){ // need exposition time to be set
return CC_RESULT_FAIL;
}
if(camstate == CAMERA_CAPTURE){
DBG("Capture in process when user ask '%s=%s'", key, val);
return CC_RESULT_BUSY; // in progress
}
TIMESTAMP("Get FLAG_STARTCAPTURE");
TIMEINIT();
camflags |= FLAG_STARTCAPTURE;
return CC_RESULT_OK;
}
else return CC_RESULT_BADVAL;
}
snprintf(buf, 63, CC_CMD_EXPSTATE "=%d", camstate);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult camflagshandler(int fd, _U_ const char *key, _U_ const char *val){
char buf[64];
snprintf(buf, 63, "camflags=%d", camflags);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
@@ -683,6 +665,16 @@ static cc_hresult _8bithandler(int fd, _U_ const char *key, const char *val){
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult imnohandler(int fd, const char *key, const char _U_ *val){
if(!ima) return CC_RESULT_FAIL;
char buf[64];
cc_lock_shm(TRUE);
int No = ima->imnumber;
cc_unlock_shm();
snprintf(buf, 63, "%s=%d", key, No);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult fastspdhandler(int fd, _U_ const char *key, const char *val){
char buf[64];
if(!camera->setfastspeed) return CC_RESULT_FAIL;
@@ -733,77 +725,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];
@@ -813,6 +734,22 @@ static cc_hresult handler(_U_ int fd, _U_ const char *key, _U_ const char *val){
/*******************************************************************************
***************************** cc_Wheel handlers **********************************
******************************************************************************/
static cc_hresult wmaxposhandler(int fd, const char *key, _U_ const char *val){
if(wheel->Ndevices < 1) return CC_RESULT_FAIL;
char buf[64];
snprintf(buf, 63, "%s=%d", key, wmaxpos);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult wtemphandler(int fd, const char *key, _U_ const char *val){
if(wheel->Ndevices < 1 || !wheel->getTbody) return CC_RESULT_FAIL;
char buf[64];
float t;
if(!wheel->getTbody(&t)) return CC_RESULT_FAIL;
snprintf(buf, 63, "%s=%.1f", key, t);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult wlisthandler(int fd, _U_ const char *key, _U_ const char *val){
if(wheel->Ndevices < 1) return CC_RESULT_FAIL;
for(int i = 0; i < wheel->Ndevices; ++i){
@@ -822,7 +759,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 +772,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;
}
@@ -859,17 +797,42 @@ static cc_hresult wgotohandler(_U_ int fd, _U_ const char *key, _U_ const char *
/*******************************************************************************
**************************** Focuser handlers *********************************
******************************************************************************/
static cc_hresult fminposhandler(int fd, const char *key, _U_ const char *val){
if(focuser->Ndevices < 1) return CC_RESULT_FAIL;
char buf[64];
snprintf(buf, 63, "%s=%g", key, focminpos);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult fmaxposhandler(int fd, const char *key, _U_ const char *val){
if(focuser->Ndevices < 1) return CC_RESULT_FAIL;
char buf[64];
snprintf(buf, 63, "%s=%g", key, focmaxpos);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult ftemphandler(int fd, const char *key, _U_ const char *val){
if(focuser->Ndevices < 1 || !focuser->getTbody) return CC_RESULT_FAIL;
char buf[64];
float t;
if(!focuser->getTbody(&t)) return CC_RESULT_FAIL;
snprintf(buf, 63, "%s=%.1f", key, t);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult foclisthandler(int fd, _U_ const char *key, _U_ const char *val){
if(focuser->Ndevices < 1) return CC_RESULT_FAIL;
for(int i = 0; i < focuser->Ndevices; ++i){
char modname[256], buf[BUFSIZ];
if(!focuser->setDevNo(i)) continue;
if(focuser->setDevNo){
if(!focuser->setDevNo(i)) continue;
}
focuser->getModelName(modname, 255);
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) focuser->setDevNo(devno);
return CC_RESULT_SILENCE;
}
static cc_hresult fsetNhandler(int fd, _U_ const char *key, const char *val){
@@ -881,7 +844,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;
}
@@ -910,65 +873,6 @@ static cc_hresult fgotohandler(int fd, _U_ const char *key, const char *val){
**************************** Common handlers **********************************
******************************************************************************/
// information about everything
static cc_hresult infohandler(int fd, _U_ const char *key, _U_ const char *val){
char buf[BUFSIZ], buf1[256];
float f;
int i;
if(camera){
if(camera->getModelName && camera->getModelName(buf1, 255)){
snprintf(buf, BUFSIZ-1, CC_CMD_CAMLIST "='%s'", buf1);
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
}
if(wheel){
DBG("chk wheel");
if(wheel->getModelName(buf1, 255)){
snprintf(buf, BUFSIZ-1, CC_CMD_WLIST "='%s'", buf1);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
if(wheel->getTbody(&f)){
snprintf(buf, BUFSIZ-1, "wtemp=%.1f", f);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
if(wheel->getPos(&i)){
snprintf(buf, BUFSIZ-1, CC_CMD_WPOS "=%d", i);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
snprintf(buf, BUFSIZ-1, "wmaxpos=%d", wmaxpos);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
if(focuser){
DBG("Chk focuser");
if(focuser->getModelName(buf1, 255)){
snprintf(buf, BUFSIZ-1, CC_CMD_FOCLIST "='%s'", buf1);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
if(focuser->getTbody(&f)){
snprintf(buf, BUFSIZ-1, "foctemp=%.1f", f);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
snprintf(buf, BUFSIZ-1, "focminpos=%g", focminpos);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
snprintf(buf, BUFSIZ-1, "focmaxpos=%g", focmaxpos);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
if(focuser->getPos(&f)){
snprintf(buf, BUFSIZ-1, CC_CMD_FGOTO "=%g", f);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
}
DBG("EOF");
return CC_RESULT_SILENCE;
}
// show help
static cc_hresult helphandler(int fd, _U_ const char *key, _U_ const char *val){
char buf[256];
@@ -981,7 +885,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 +922,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;
}
@@ -1056,14 +966,14 @@ static cc_hresult chkfoc(char *val){
return CC_RESULT_FAIL;
}
static cc_handleritem items[] = {
{chktrue,infohandler, CC_CMD_INFO},
{NULL, helphandler, CC_CMD_HELP},
{NULL, restarthandler, CC_CMD_RESTART},
{chkcc, camlisthandler, CC_CMD_CAMLIST},
{chkcc, camflagshandler, CC_CMD_CAMFLAGS},
{chkcc, camsetNhandler, CC_CMD_CAMDEVNO},
{chkcc, camfanhandler, CC_CMD_CAMFANSPD},
{chkcc, exphandler, CC_CMD_EXPOSITION},
{chkcc, namehandler, CC_CMD_FILENAME},
{chkcc, imnohandler, CC_CMD_IMNUMBER},
{chkcc, binhandler, CC_CMD_HBIN},
{chkcc, binhandler, CC_CMD_VBIN},
{chkcc, temphandler, CC_CMD_CAMTEMPER},
@@ -1079,8 +989,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,14 +1002,17 @@ 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},
{chkfoc, fminposhandler, CC_CMD_FMINPOS},
{chkfoc, fmaxposhandler, CC_CMD_FMAXPOS},
{chkfoc, ftemphandler, CC_CMD_FTEMP},
{chkwhl, wlisthandler, CC_CMD_WLIST},
{chkwhl, wsetNhandler, CC_CMD_WDEVNO},
{chkwhl, wgotohandler, CC_CMD_WPOS},
{chkwhl, wmaxposhandler, CC_CMD_WMAXPOS},
{chkwhl, wtemphandler, CC_CMD_WTEMP},
{NULL, NULL, NULL},
};
@@ -1109,10 +1020,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){
@@ -1121,12 +1047,12 @@ void server(int sock, int imsock){
if(imsock < 0) WARNX("Server run without image transport socket");
else if(listen(imsock, CC_MAXCLIENTS) == -1){
WARN("listen()");
LOGWARN("listen()");
LOGERR("server(): error in listen() for image socket");
return;
}
if(listen(sock, CC_MAXCLIENTS) == -1){
WARN("listen()");
LOGWARN("listen()");
LOGERR("server(): error in listen() for command socket");
return;
}
// init everything
@@ -1137,11 +1063,17 @@ void server(int sock, int imsock){
wheeldevini(0);
if(startCCD()) --ctr;
camdevini(0);
if(ctr == 3) ERRX("No devices found");
if(ctr == 3){
LOGERR("server(): no devices found");
WARNX("No devices found");
}
// start camera thread
pthread_t camthread;
if(camera){
if(pthread_create(&camthread, NULL, processCAM, NULL)) ERR("pthread_create()");
if(pthread_create(&camthread, NULL, processCAM, NULL)){
WARN("pthread_create()");
LOGERR("server(): pthread_create()");
}
}
int nfd = 2; // only two listening sockets @start: command and image
struct pollfd poll_set[CC_MAXCLIENTS+2];
@@ -1155,9 +1087,18 @@ void server(int sock, int imsock){
poll_set[0].events = POLLIN;
poll_set[1].fd = imsock;
poll_set[1].events = POLLIN;
while(1){
#ifdef EBUG
double T = sl_dtime();
#endif
while(isrunning == 1){
#ifdef EBUG
if(sl_dtime() - T > 5.){
T = sl_dtime();
printf("\t\t\tserver(), 5 seconds\n");
}
#endif
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 +1107,28 @@ 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);
if(ima->imnumber == 0){
WARNX("Client wants an image, but there's no data");
close(client);
}else{
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;
@@ -1193,6 +1149,7 @@ void server(int sock, int imsock){
}
}
}
#if 0
// process some data & send messages to ALL
if(camstate == CAMERA_FRAMERDY || camstate == CAMERA_ERROR){
DBG("new image: timestamp=%.1f, num=%zd", ima->timestamp, ima->imnumber);
@@ -1203,17 +1160,14 @@ 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;
}
#endif
// scan connections
for(int fdidx = 2; fdidx < nfd; ++fdidx){
if((poll_set[fdidx].revents & POLLIN) == 0) continue;
int fd = poll_set[fdidx].fd;
DBG("Got active fd=%d", fd);
cc_strbuff *curbuff = buffers[fdidx-1];
int disconnected = 0;
if(cc_read2buf(fd, curbuff)){
@@ -1236,7 +1190,7 @@ void server(int sock, int imsock){
}
}
// check `infty`
if(camstate == CAMERA_IDLE && infty){ // start new exposition
if(camstate != CAMERA_CAPTURE && infty){ // start new exposition
// mark to start new capture in infinity loop when at least one client connected
if(nfd > 2){
camflags |= FLAG_STARTCAPTURE;
@@ -1245,10 +1199,11 @@ void server(int sock, int imsock){
}
}
}
// never reached
WARNX("SERVER STOPPED!");
camstop();
focclose();
closewheel();
closecam();
isrunning = -1;
}
/**
@@ -1274,7 +1229,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);

View File

@@ -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,4 @@
void server(int fd, int imsock);
char *makeabspath(const char *path, int shouldbe);
void stop_server();