next fixes

This commit is contained in:
2026-06-04 18:24:26 +03:00
parent 1f7aad348e
commit f65daab527
13 changed files with 475 additions and 323 deletions

View File

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

View File

@@ -24,6 +24,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/un.h> // unix socket #include <sys/un.h> // unix socket
#include <unistd.h> #include <unistd.h>
#include <usefull_macros.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 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) 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 * @brief cc_open_socket - create socket and open it
* @param isserver - TRUE for server, FALSE for client * @param isserver - TRUE for server, FALSE for client
@@ -253,7 +330,7 @@ char *cc_get_keyval(char **keyval){
cc_IMG *cc_getshm(key_t key, size_t imsize){ cc_IMG *cc_getshm(key_t key, size_t imsize){
size_t shmsize = sizeof(cc_IMG) + imsize; size_t shmsize = sizeof(cc_IMG) + imsize;
shmsize = 1024 * (1 + shmsize / 1024); 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 shmid = -1;
int flags = (imsize) ? IPC_CREAT | 0666 : 0; int flags = (imsize) ? IPC_CREAT | 0666 : 0;
shmid = shmget(key, 0, flags); shmid = shmget(key, 0, flags);
@@ -272,9 +349,15 @@ cc_IMG *cc_getshm(key_t key, size_t imsize){
WARN("Can't create shared memory segment %d", key); WARN("Can't create shared memory segment %d", key);
return NULL; 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 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(ptr == (void*)-1){
if(imsize) WARN("Can't attach SHM segment %d", key); if(imsize) WARN("Can't attach SHM segment %d", key);
return NULL; return NULL;

View File

@@ -20,6 +20,7 @@
#include <fitsio.h> // FLEN_CARD #include <fitsio.h> // FLEN_CARD
#include <pthread.h> #include <pthread.h>
#include <semaphore.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> // for size_t #include <stdlib.h> // for size_t
@@ -29,10 +30,12 @@
// magic to mark our SHM // magic to mark our SHM
#define CC_SHM_MAGIC (0xdeadbeef) #define CC_SHM_MAGIC (0xdeadbeef)
// semaphore for SHM protection
#define SEM_NAME "ccdcapture"
// base image parameters - sent by socket and stored in shared memory // base image parameters - sent by socket and stored in shared memory
typedef struct { typedef struct __attribute__((packed)){
uint32_t MAGICK; // magick (DEADBEEF) - to mark our shm uint32_t MAGICK; // magick (DEADBEEF) - to mark our shm
pthread_mutex_t mutex; // shared mutex
double timestamp; // timestamp of image taken double timestamp; // timestamp of image taken
uint8_t bitpix; // bits per pixel (8 or 16) uint8_t bitpix; // bits per pixel (8 or 16)
int w, h; // image size int w, h; // image size
@@ -221,7 +224,6 @@ typedef enum{
} cc_camera_state; } cc_camera_state;
// common information about everything // common information about everything
#define CC_CMD_INFO "info"
#define CC_CMD_HELP "help" #define CC_CMD_HELP "help"
// restart server // restart server
#define CC_CMD_RESTART "restartTheServer" #define CC_CMD_RESTART "restartTheServer"
@@ -240,7 +242,8 @@ typedef enum{
#define CC_CMD_HBIN "hbin" #define CC_CMD_HBIN "hbin"
#define CC_CMD_VBIN "vbin" #define CC_CMD_VBIN "vbin"
#define CC_CMD_CAMTEMPER "tcold" #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_SHUTTER "shutter"
#define CC_CMD_CONFIO "confio" #define CC_CMD_CONFIO "confio"
#define CC_CMD_IO "io" #define CC_CMD_IO "io"
@@ -269,11 +272,16 @@ typedef enum{
#define CC_CMD_FOCLIST "foclist" #define CC_CMD_FOCLIST "foclist"
#define CC_CMD_FDEVNO "focdevno" #define CC_CMD_FDEVNO "focdevno"
#define CC_CMD_FGOTO "focpos" #define CC_CMD_FGOTO "focpos"
#define CC_CMD_FMINPOS "focminpos"
#define CC_CMD_FMAXPOS "focmaxpos"
#define CC_CMD_FTEMP "foctemp"
// wheel // wheel
#define CC_CMD_WLIST "wlist" #define CC_CMD_WLIST "wlist"
#define CC_CMD_WDEVNO "wdevno" #define CC_CMD_WDEVNO "wdevno"
#define CC_CMD_WPOS "wpos" #define CC_CMD_WPOS "wpos"
#define CC_CMD_WMAXPOS "wmaxpos"
#define CC_CMD_WTEMP "wtemp"
typedef enum{ // parameter type typedef enum{ // parameter type
CC_PAR_NONE, // no parameter CC_PAR_NONE, // no parameter
@@ -337,3 +345,8 @@ cc_hresult cc_getfloat(int fd, cc_strbuff *cbuf, const char *cmd, float *val);
char *cc_nextkw(char *buf, char record[FLEN_CARD], int newlines); char *cc_nextkw(char *buf, char record[FLEN_CARD], int newlines);
size_t cc_kwfromfile(cc_IMG *img, char *filename); size_t cc_kwfromfile(cc_IMG *img, char *filename);
//int cc_charbuf2kw(cc_charbuff *b, fitsfile *f); //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

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

View File

@@ -53,7 +53,7 @@ static int oldgrabno = 0;
// IPC key for shared memory // IPC key for shared memory
static cc_IMG ima = {0}, *shmima = NULL; // ima - local storage, shmima - shm (if available) 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 size_t imbufsz = 0; // image buffer for allocated `ima`
static uint8_t *imbuf = NULL; 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
// read message from queue or file descriptor // read message from queue or file descriptor
@@ -118,6 +118,7 @@ static int getans(int sock, const char *msg){
double t0 = sl_dtime(); double t0 = sl_dtime();
char *ans = NULL; char *ans = NULL;
double tmout = answer_timeout; double tmout = answer_timeout;
// TODO: increase first timeout up to 15-30s (add key?)
if(msg) tmout *= 5.; // make first timeout larger for slow networks if(msg) tmout *= 5.; // make first timeout larger for slow networks
cc_hresult res = CC_RESULT_FAIL; cc_hresult res = CC_RESULT_FAIL;
while(sl_dtime() - t0 < tmout){ while(sl_dtime() - t0 < tmout){
@@ -161,16 +162,35 @@ static void send_headers(int sock){
DBG("infty=%d", GP->infty); DBG("infty=%d", GP->infty);
if(GP->infty > -1) SENDMSGW(CC_CMD_INFTY, "=%d", GP->infty); if(GP->infty > -1) SENDMSGW(CC_CMD_INFTY, "=%d", GP->infty);
// common information // 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 // focuser
if(GP->listdevices) SENDMSG(CC_CMD_FOCLIST); if(GP->listdevices) SENDMSG(CC_CMD_FOCLIST);
if(GP->focdevno > -1) SENDMSG(CC_CMD_FDEVNO "=%d", GP->focdevno); 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)){ if(!isnan(GP->gotopos)){
SENDMSGW(CC_CMD_FGOTO, "=%g", GP->gotopos); SENDMSGW(CC_CMD_FGOTO, "=%g", GP->gotopos);
} }
// wheel // wheel
if(GP->listdevices) SENDCMDW(CC_CMD_WLIST); if(GP->listdevices) SENDCMDW(CC_CMD_WLIST);
if(GP->whldevno > -1) SENDMSGW(CC_CMD_WDEVNO, "=%d", GP->whldevno); 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); if(GP->setwheel > -1) SENDMSGW(CC_CMD_WPOS, "=%d", GP->setwheel);
DBG("nxt"); DBG("nxt");
// CCD/CMOS // CCD/CMOS
@@ -193,8 +213,6 @@ static void send_headers(int sock){
SENDMSGW(CC_CMD_FRAMEFORMAT, "=%d,%d,%d,%d", GP->X0, GP->Y0, GP->X1, GP->Y1); 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->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->hbin) SENDMSGW(CC_CMD_HBIN, "=%d", GP->hbin);
if(GP->vbin) SENDMSGW(CC_CMD_VBIN, "=%d", GP->vbin); if(GP->vbin) SENDMSGW(CC_CMD_VBIN, "=%d", GP->vbin);
if(!isnan(GP->temperature)) SENDMSGW(CC_CMD_CAMTEMPER, "=%g", GP->temperature); if(!isnan(GP->temperature)) SENDMSGW(CC_CMD_CAMTEMPER, "=%g", GP->temperature);
@@ -255,9 +273,11 @@ static int getimage(int askheader){
static double oldtimestamp = -1.; static double oldtimestamp = -1.;
TIMESTAMP("Get image sizes"); TIMESTAMP("Get image sizes");
if(shmima){ // read image from shared memory if(shmima){ // read image from shared memory
DBG("Try to read from SHM");
double t0 = sl_dtime(); double t0 = sl_dtime();
while(sl_dtime() - t0 < MUTEX_LOCK_TMOUT){ while(sl_dtime() - t0 < MUTEX_LOCK_TMOUT){
if(client_lock_shm(shmima)){ if(cc_lock_shm(FALSE)){
DBG("Locked");
shmlocked = TRUE; shmlocked = TRUE;
break; break;
} }
@@ -269,6 +289,7 @@ static int getimage(int askheader){
} }
memcpy(&ima, shmima, sizeof(cc_IMG)); memcpy(&ima, shmima, sizeof(cc_IMG));
}else{ // get image by socket }else{ // get image by socket
DBG("Open socket @ %s", GP->imageport);
imsock = cc_open_socket(FALSE, GP->imageport, TRUE); imsock = cc_open_socket(FALSE, GP->imageport, TRUE);
if(imsock < 0) ERRX("getimage(): can't open image transport socket"); if(imsock < 0) ERRX("getimage(): can't open image transport socket");
// get image size // get image size
@@ -292,11 +313,12 @@ static int getimage(int askheader){
ima.data = imbuf; // renew this value each time after getting `ima` from server ima.data = imbuf; // renew this value each time after getting `ima` from server
TIMESTAMP("Start of data read"); TIMESTAMP("Start of data read");
if(shmima){ 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); memcpy(imbuf, datastart, ima.bytelen);
TIMESTAMP("Got by shared memory"); TIMESTAMP("Got by shared memory");
if(!askheader){ if(!askheader){
unlock_shm(shmima); cc_unlock_shm();
shmlocked = FALSE; shmlocked = FALSE;
} }
ret = TRUE; ret = TRUE;
@@ -337,11 +359,17 @@ static int getimage(int askheader){
}else WARNX("Still got old image"); }else WARNX("Still got old image");
eofg: eofg:
if(imsock != -1) close(imsock); if(imsock != -1) close(imsock);
if(shmlocked) unlock_shm(shmima); if(shmlocked) cc_unlock_shm();
return ret; return ret;
} }
void client(int sock){ 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){ if(GP->restart){
SENDCMDW(CC_CMD_RESTART); SENDCMDW(CC_CMD_RESTART);
return; return;
@@ -349,43 +377,40 @@ void client(int sock){
TIMEINIT(); TIMEINIT();
send_headers(sock); send_headers(sock);
TIMESTAMP("Got headers"); TIMESTAMP("Got headers");
double t0 = sl_dtime(), tw = t0; double t0 = sl_dtime(), tw, tstart;
int Nremain = 0, nframe = 1; int Nremain = 0, nframe = 1;
// if client gives filename/prefix or Nframes, make exposition // if client gives filename/prefix or Nframes, make exposition
if((GP->outfile && *GP->outfile) || (GP->outfileprefix && *GP->outfileprefix) || GP->nframes > 0){ if((GP->outfile && *GP->outfile) || (GP->outfileprefix && *GP->outfileprefix) || GP->nframes > 0){
Nremain = GP->nframes; Nremain = GP->nframes;
if(Nremain < 1) Nremain = 1; if(Nremain < 1) Nremain = 1;
else GP->waitexpend = TRUE; // N>1 - wait for exp ends SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); // call to start capture
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); } else return; // just send headers and exit
}else{ double timeout = CC_CLIENT_TIMEOUT;
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..."); verbose(1, "Exposing frame 1...");
if(GP->waitexpend){
atomic_store(&expstate, CAMERA_CAPTURE); // could be changed earlier atomic_store(&expstate, CAMERA_CAPTURE); // could be changed earlier
verbose(2, "Wait for exposition end"); verbose(2, "Wait for exposition end");
} t0 = sl_dtime();
tw = tstart = t0;
while(sl_dtime() - t0 < timeout){ while(sl_dtime() - t0 < timeout){
if(GP->waitexpend && sl_dtime() - tw > CC_WAIT_TIMEOUT){ if(sl_dtime() - tw > CC_WAIT_TIMEOUT){
SENDCMDW(CC_CMD_TREMAIN); // get remained time SENDCMDW(CC_CMD_TREMAIN); // get remained time
tw = sl_dtime(); tw = sl_dtime();
sprintf(sendbuf, "%s", CC_CMD_EXPSTATE);
cc_sendstrmessage(sock, sendbuf);
} }
if(getans(sock, NULL)){ // got next portion of data if(sl_dtime() - tstart < GP->exptime){
DBG("server message"); t0 = sl_dtime(); // refresh timeout until exp not ends
t0 = sl_dtime(); }else{
SENDCMDW(CC_CMD_EXPSTATE);
#ifdef EBUG
usleep(300000);
#endif
}
int curst = atomic_load(&expstate); int curst = atomic_load(&expstate);
if(curst == CAMERA_ERROR){ if(curst == CAMERA_ERROR){
WARNX(_("Can't make exposition")); WARNX(_("Can't make exposition"));
if(Nremain > 1){ if(Nremain > 1){
verbose(1, "Exposing frame %d...", nframe); verbose(1, "Exposing frame %d...", nframe);
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
tstart = sl_dtime();
} }
continue; continue;
} }
@@ -395,6 +420,7 @@ void client(int sock){
if(Nremain > 1){ if(Nremain > 1){
verbose(1, "Exposing frame %d...", nframe+1); verbose(1, "Exposing frame %d...", nframe+1);
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
tstart = sl_dtime();
} }
verbose(2, "Frame ready, try to grab"); verbose(2, "Frame ready, try to grab");
int failed = TRUE; int failed = TRUE;
@@ -410,6 +436,7 @@ void client(int sock){
if(failed && Nremain == 1){ // last image -> should re-expose if(failed && Nremain == 1){ // last image -> should re-expose
verbose(1, "Exposing frame %d...", nframe); verbose(1, "Exposing frame %d...", nframe);
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
tstart = sl_dtime();
} }
if(Nremain > 0){ if(Nremain > 0){
if(GP->pause_len > 0){ if(GP->pause_len > 0){
@@ -424,14 +451,12 @@ void client(int sock){
} }
} }
}else{ }else{
GP->waitexpend = 0;
DBG("All images saved -> exit"); DBG("All images saved -> exit");
break; break;
} }
} }
} }
} if(Nremain > 0) WARNX(_("Server timeout"));
if(GP->waitexpend) WARNX(_("Server timeout"));
} }
#ifdef IMAGEVIEW #ifdef IMAGEVIEW
@@ -442,6 +467,7 @@ void init_grab_sock(int sock){
send_headers(sock); send_headers(sock);
if(!GP->forceimsock && !shmima){ // init shm buffer if user don't ask to work through image socket 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 shmima = cc_getshm(GP->shmkey, 0); // try to init client shm
cc_init_sem(FALSE);
} }
} }

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)")}, {"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")}, {"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")}, {"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\")")}, {"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")}, {"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")}, {"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")}, {"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]")}, {"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")}, {"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)")}, {"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")}, {"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)")}, {"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")}, {"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)")}, {"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)")}, {"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")}, {"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 **addhdr; // list of files from which to add header records
char **plugincmd; // plugin commands char **plugincmd; // plugin commands
int restart; // restart server int restart; // restart server
int waitexpend; // wait while exposition ends
int cancelexpose; // cancel exp (for Grasshopper - forbid forever) int cancelexpose; // cancel exp (for Grasshopper - forbid forever)
int client; // run as client 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 viewer; // passive client (only get last images)
int listdevices; // list connected devices int listdevices; // list connected devices
int fanspeed; // fan speed: 0-2 int fanspeed; // fan speed: 0-2

Binary file not shown.

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-06-02 18:19+0300\n" "POT-Creation-Date: 2026-06-04 18:22+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -62,7 +62,8 @@ msgid "rewrite output file if exists"
msgstr "" msgstr ""
#: cmdlnopts.c:59 #: 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 "" msgstr ""
#: cmdlnopts.c:60 #: cmdlnopts.c:60
@@ -117,142 +118,144 @@ msgstr ""
msgid "output file name" msgid "output file name"
msgstr "" msgstr ""
#: cmdlnopts.c:74 #: cmdlnopts.c:75
msgid "wait while exposition ends"
msgstr ""
#: cmdlnopts.c:76
msgid "N flushes before exposing (default: 1)" msgid "N flushes before exposing (default: 1)"
msgstr "" msgstr ""
#: cmdlnopts.c:77 #: cmdlnopts.c:76
msgid "horizontal binning to N pixels" msgid "horizontal binning to N pixels"
msgstr "" msgstr ""
#: cmdlnopts.c:78 #: cmdlnopts.c:77
msgid "vertical binning to N pixels" msgid "vertical binning to N pixels"
msgstr "" msgstr ""
#: cmdlnopts.c:79 #: cmdlnopts.c:78
msgid "make series of N frames" msgid "make series of N frames"
msgstr "" msgstr ""
#: cmdlnopts.c:80 #: cmdlnopts.c:79
msgid "make pause for N seconds between expositions" msgid "make pause for N seconds between expositions"
msgstr "" msgstr ""
#: cmdlnopts.c:81 #: cmdlnopts.c:80
msgid "set exposure time to given value (seconds!)" msgid "set exposure time to given value (seconds!)"
msgstr "" msgstr ""
#: cmdlnopts.c:82 #: cmdlnopts.c:81
msgid "cancel current exposition" msgid "cancel current exposition"
msgstr "" msgstr ""
#: cmdlnopts.c:83 #: cmdlnopts.c:82
msgid "" msgid ""
"absolute (not divided by binning!) frame X0 coordinate (-1 - all with " "absolute (not divided by binning!) frame X0 coordinate (-1 - all with "
"overscan)" "overscan)"
msgstr "" msgstr ""
#: cmdlnopts.c:84 #: cmdlnopts.c:83
msgid "absolute frame Y0 coordinate (-1 - all with overscan)" msgid "absolute frame Y0 coordinate (-1 - all with overscan)"
msgstr "" msgstr ""
#: cmdlnopts.c:85 #: cmdlnopts.c:84
msgid "absolute frame X1 coordinate (-1 - all with overscan)" msgid "absolute frame X1 coordinate (-1 - all with overscan)"
msgstr "" msgstr ""
#: cmdlnopts.c:86 #: cmdlnopts.c:85
msgid "absolute frame Y1 coordinate (-1 - all with overscan)" msgid "absolute frame Y1 coordinate (-1 - all with overscan)"
msgstr "" msgstr ""
#: cmdlnopts.c:88 #: cmdlnopts.c:87
msgid "open shutter" msgid "open shutter"
msgstr "" msgstr ""
#: cmdlnopts.c:89 #: cmdlnopts.c:88
msgid "close shutter" msgid "close shutter"
msgstr "" msgstr ""
#: cmdlnopts.c:90 #: cmdlnopts.c:89
msgid "run exposition on LOW @ pin5 I/O port" msgid "run exposition on LOW @ pin5 I/O port"
msgstr "" msgstr ""
#: cmdlnopts.c:91 #: cmdlnopts.c:90
msgid "run exposition on HIGH @ pin5 I/O port" msgid "run exposition on HIGH @ pin5 I/O port"
msgstr "" msgstr ""
#: cmdlnopts.c:92 #: cmdlnopts.c:91
msgid "get value of I/O port pins" msgid "get value of I/O port pins"
msgstr "" msgstr ""
#: cmdlnopts.c:93 #: cmdlnopts.c:92
msgid "move stepper motor asynchronous" msgid "move stepper motor asynchronous"
msgstr "" msgstr ""
#: cmdlnopts.c:95 #: cmdlnopts.c:94
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)" msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
msgstr "" msgstr ""
#: cmdlnopts.c:96 #: cmdlnopts.c:95
msgid "" msgid ""
"configure I/O port pins to given value (decimal number, pin1 is LSB, 1 == " "configure I/O port pins to given value (decimal number, pin1 is LSB, 1 == "
"output, 0 == input)" "output, 0 == input)"
msgstr "" msgstr ""
#: cmdlnopts.c:98 #: cmdlnopts.c:97
msgid "move focuser to absolute position, mm" msgid "move focuser to absolute position, mm"
msgstr "" msgstr ""
#: cmdlnopts.c:99 #: cmdlnopts.c:98
msgid "move focuser to relative position, mm (only for standalone)" msgid "move focuser to relative position, mm (only for standalone)"
msgstr "" msgstr ""
#: cmdlnopts.c:101 #: cmdlnopts.c:100
msgid "set wheel position" msgid "set wheel position"
msgstr "" msgstr ""
#: cmdlnopts.c:103 #: cmdlnopts.c:102
msgid "CMOS gain level" msgid "CMOS gain level"
msgstr "" msgstr ""
#: cmdlnopts.c:104 #: cmdlnopts.c:103
msgid "CMOS brightness level" msgid "CMOS brightness level"
msgstr "" msgstr ""
#: cmdlnopts.c:106 #: cmdlnopts.c:105
msgid "logging file name (if run as server)" msgid "logging file name (if run as server)"
msgstr "" msgstr ""
#: cmdlnopts.c:107 #: cmdlnopts.c:106
msgid "UNIX socket name (command socket)" msgid "UNIX socket name (command socket)"
msgstr "" msgstr ""
#: cmdlnopts.c:108 #: cmdlnopts.c:107
msgid "local INET command socket port" msgid "local INET command socket port"
msgstr "" msgstr ""
#: cmdlnopts.c:109 #: cmdlnopts.c:108
msgid "INET image socket port" msgid "INET image socket port"
msgstr "" msgstr ""
#: cmdlnopts.c:110 #: cmdlnopts.c:109
msgid "run as client" msgid "run as client"
msgstr "" msgstr ""
#: cmdlnopts.c:111 #: cmdlnopts.c:110
msgid "passive viewer (only get last images)" msgid "passive viewer (only get last images)"
msgstr "" msgstr ""
#: cmdlnopts.c:112 #: cmdlnopts.c:111
msgid "restart image server" msgid "restart image server"
msgstr "" msgstr ""
#: cmdlnopts.c:113 #: cmdlnopts.c:112
msgid "network answer timeout (default: 0.1s)" msgid "network answer timeout (default: 0.1s)"
msgstr "" msgstr ""
#: cmdlnopts.c:113
msgid ""
"get base information about connected hardware (also increasing text messages "
"level to 2)"
msgstr ""
#: cmdlnopts.c:115 #: cmdlnopts.c:115
msgid "shared memory (with image data) key (default: 7777777)" msgid "shared memory (with image data) key (default: 7777777)"
msgstr "" msgstr ""
@@ -491,12 +494,12 @@ msgstr ""
msgid "Can't set brightness to %g" msgid "Can't set brightness to %g"
msgstr "" msgstr ""
#: ccdfunc.c:690 server.c:332 #: ccdfunc.c:690 server.c:323
#, c-format #, c-format
msgid "Can't set binning %dx%d" msgid "Can't set binning %dx%d"
msgstr "" msgstr ""
#: ccdfunc.c:702 server.c:333 #: ccdfunc.c:702 server.c:324
msgid "Can't set given geometry" msgid "Can't set given geometry"
msgstr "" msgstr ""
@@ -544,11 +547,11 @@ msgstr ""
msgid "Capture frame %d" msgid "Capture frame %d"
msgstr "" msgstr ""
#: ccdfunc.c:750 ccdfunc.c:827 server.c:202 server.c:203 #: ccdfunc.c:750 ccdfunc.c:827 server.c:184 server.c:185
msgid "Camera plugin have no function `start exposition`" msgid "Camera plugin have no function `start exposition`"
msgstr "" msgstr ""
#: ccdfunc.c:752 ccdfunc.c:829 server.c:208 server.c:209 #: ccdfunc.c:752 ccdfunc.c:829 server.c:190 server.c:191
msgid "Can't start exposition" msgid "Can't start exposition"
msgstr "" msgstr ""
@@ -560,7 +563,7 @@ msgstr ""
msgid "Read grabbed image" msgid "Read grabbed image"
msgstr "" msgstr ""
#: ccdfunc.c:762 ccdfunc.c:842 server.c:226 server.c:227 #: ccdfunc.c:762 ccdfunc.c:842 server.c:208 server.c:209
msgid "Camera plugin have no function `capture`" msgid "Camera plugin have no function `capture`"
msgstr "" msgstr ""
@@ -568,7 +571,7 @@ msgstr ""
msgid "Can't grab image" msgid "Can't grab image"
msgstr "" msgstr ""
#: ccdfunc.c:778 client.c:420 #: ccdfunc.c:778 client.c:447
#, c-format #, c-format
msgid "%d seconds till pause ends\n" msgid "%d seconds till pause ends\n"
msgstr "" msgstr ""
@@ -577,15 +580,15 @@ msgstr ""
msgid "Some error when capture" msgid "Some error when capture"
msgstr "" msgstr ""
#: server.c:253 #: server.c:235
msgid "No camera device" msgid "No camera device"
msgstr "" msgstr ""
#: client.c:385 #: client.c:409
msgid "Can't make exposition" msgid "Can't make exposition"
msgstr "" msgstr ""
#: client.c:434 #: client.c:459
msgid "Server timeout" msgid "Server timeout"
msgstr "" msgstr ""

View File

@@ -7,7 +7,7 @@
msgid "" msgid ""
msgstr "Project-Id-Version: PACKAGE VERSION\n" msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-06-02 18:19+0300\n" "POT-Creation-Date: 2026-06-04 18:16+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -21,7 +21,7 @@ msgstr "Project-Id-Version: PACKAGE VERSION\n"
msgid "%.1f seconds till exposition ends" msgid "%.1f seconds till exposition ends"
msgstr "%.1f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ" msgstr "%.1f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ"
#: ccdfunc.c:778 client.c:420 #: ccdfunc.c:778 client.c:447
#, c-format #, c-format
msgid "%d seconds till pause ends\n" msgid "%d seconds till pause ends\n"
msgstr "%d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n" msgstr "%d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n"
@@ -30,11 +30,11 @@ msgstr "%d
msgid "Already initialized!" msgid "Already initialized!"
msgstr "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!" msgstr "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!"
#: cmdlnopts.c:104 #: cmdlnopts.c:103
msgid "CMOS brightness level" msgid "CMOS brightness level"
msgstr "ÕÒÏ×ÅÎØ ÑÒËÏÓÔÉ CMOS" msgstr "ÕÒÏ×ÅÎØ ÑÒËÏÓÔÉ CMOS"
#: cmdlnopts.c:103 #: cmdlnopts.c:102
msgid "CMOS gain level" msgid "CMOS gain level"
msgstr "ÕÒÏ×ÅÎØ Gain CMOS" msgstr "ÕÒÏ×ÅÎØ Gain CMOS"
@@ -66,12 +66,12 @@ msgstr "
msgid "Camera plugin have no fun speed setter" msgid "Camera plugin have no fun speed setter"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:762 ccdfunc.c:842 server.c:226 server.c:227 #: ccdfunc.c:762 ccdfunc.c:842 server.c:208 server.c:209
#, fuzzy #, fuzzy
msgid "Camera plugin have no function `capture`" msgid "Camera plugin have no function `capture`"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:750 ccdfunc.c:827 server.c:202 server.c:203 #: ccdfunc.c:750 ccdfunc.c:827 server.c:184 server.c:185
#, fuzzy #, fuzzy
msgid "Camera plugin have no function `start exposition`" msgid "Camera plugin have no function `start exposition`"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
@@ -130,7 +130,7 @@ msgstr "
msgid "Can't init mutex!" msgid "Can't init mutex!"
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!" msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
#: client.c:385 #: client.c:409
msgid "Can't make exposition" msgid "Can't make exposition"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ÜËÓÐÏÚÉÃÉÀ" msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ÜËÓÐÏÚÉÃÉÀ"
@@ -174,7 +174,7 @@ msgstr "
msgid "Can't set active wheel number" msgid "Can't set active wheel number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ"
#: ccdfunc.c:690 server.c:332 #: ccdfunc.c:690 server.c:323
#, c-format #, c-format
msgid "Can't set binning %dx%d" msgid "Can't set binning %dx%d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d"
@@ -202,7 +202,7 @@ msgstr "
msgid "Can't set gain to %g" msgid "Can't set gain to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
#: ccdfunc.c:702 server.c:333 #: ccdfunc.c:702 server.c:324
msgid "Can't set given geometry" msgid "Can't set given geometry"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ"
@@ -225,7 +225,7 @@ msgstr "
msgid "Can't set wheel position %d" msgid "Can't set wheel position %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ %d" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ %d"
#: ccdfunc.c:752 ccdfunc.c:829 server.c:208 server.c:209 #: ccdfunc.c:752 ccdfunc.c:829 server.c:190 server.c:191
msgid "Can't start exposition" msgid "Can't start exposition"
msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ" msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ"
@@ -291,7 +291,7 @@ msgstr "
msgid "Histogram conversion: %s" msgid "Histogram conversion: %s"
msgstr "ðÒÅÏÂÒÁÚÏ×ÁÎÉÅ ÇÉÓÔÏÇÒÁÍÍÙ: %s" msgstr "ðÒÅÏÂÒÁÚÏ×ÁÎÉÅ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
#: cmdlnopts.c:109 #: cmdlnopts.c:108
msgid "INET image socket port" msgid "INET image socket port"
msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ ÐÅÒÅÄÁÞÉ ÉÚÏÂÒÁÖÅÎÉÑ" msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ ÐÅÒÅÄÁÞÉ ÉÚÏÂÒÁÖÅÎÉÑ"
@@ -300,11 +300,11 @@ msgstr "
msgid "Image stat:\n" msgid "Image stat:\n"
msgstr "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ: \n" msgstr "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ: \n"
#: cmdlnopts.c:76 #: cmdlnopts.c:75
msgid "N flushes before exposing (default: 1)" msgid "N flushes before exposing (default: 1)"
msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)" msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)"
#: server.c:253 #: server.c:235
msgid "No camera device" msgid "No camera device"
msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ" msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ"
@@ -338,7 +338,7 @@ msgstr "
msgid "Readout mode: %s" msgid "Readout mode: %s"
msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s" msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s"
#: client.c:434 #: client.c:459
msgid "Server timeout" msgid "Server timeout"
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ" msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
@@ -376,7 +376,7 @@ msgstr "
msgid "Try to write %d to I/O port" msgid "Try to write %d to I/O port"
msgstr "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O" msgstr "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O"
#: cmdlnopts.c:107 #: cmdlnopts.c:106
msgid "UNIX socket name (command socket)" msgid "UNIX socket name (command socket)"
msgstr "ÉÍÑ UNIX-ÓÏËÅÔÁ" msgstr "ÉÍÑ UNIX-ÓÏËÅÔÁ"
@@ -389,21 +389,21 @@ msgstr "
msgid "Wheel position should be from 0 to %d" msgid "Wheel position should be from 0 to %d"
msgstr "ðÏÚÉÃÉÑ ËÏÌÅÓÁ ÄÏÌÖÎÁ ÂÙÔØ ÏÔ 0 ÄÏ %d" msgstr "ðÏÚÉÃÉÑ ËÏÌÅÓÁ ÄÏÌÖÎÁ ÂÙÔØ ÏÔ 0 ÄÏ %d"
#: cmdlnopts.c:83 #: cmdlnopts.c:82
msgid "absolute (not divided by binning!) frame X0 coordinate (-1 - all " msgid "absolute (not divided by binning!) frame X0 coordinate (-1 - all "
"with overscan)" "with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ (ÎÅ ÄÅÌÅÎÎÁÑ ÎÁ ÂÉÎÎÉÎÇ!) ËÏÏÒÄÉÎÁÔÁ X0 (-1 - ×ËÌÀÞÁÑ " msgstr "ÁÂÓÏÌÀÔÎÁÑ (ÎÅ ÄÅÌÅÎÎÁÑ ÎÁ ÂÉÎÎÉÎÇ!) ËÏÏÒÄÉÎÁÔÁ X0 (-1 - ×ËÌÀÞÁÑ "
"Ï×ÅÒÓËÁÎ)" "Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:85 #: cmdlnopts.c:84
msgid "absolute frame X1 coordinate (-1 - all with overscan)" msgid "absolute frame X1 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ X1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)" msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ X1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:84 #: cmdlnopts.c:83
msgid "absolute frame Y0 coordinate (-1 - all with overscan)" msgid "absolute frame Y0 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ Y0 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)" msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ Y0 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:86 #: cmdlnopts.c:85
msgid "absolute frame Y1 coordinate (-1 - all with overscan)" msgid "absolute frame Y1 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ Y1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)" msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ Y1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
@@ -419,11 +419,11 @@ msgstr "
msgid "camera device plugin (e.g. devfli.so)" msgid "camera device plugin (e.g. devfli.so)"
msgstr "ÐÌÁÇÉÎ ËÁÍÅÒÙ (ÎÁÐÒÉÍÅÒ, devfli.so)" msgstr "ÐÌÁÇÉÎ ËÁÍÅÒÙ (ÎÁÐÒÉÍÅÒ, devfli.so)"
#: cmdlnopts.c:82 #: cmdlnopts.c:81
msgid "cancel current exposition" msgid "cancel current exposition"
msgstr "ÏÔÍÅÎÁ ÔÅËÕÝÅÊ ÜËÓÐÏÚÉÃÉÉ" msgstr "ÏÔÍÅÎÁ ÔÅËÕÝÅÊ ÜËÓÐÏÚÉÃÉÉ"
#: cmdlnopts.c:89 #: cmdlnopts.c:88
msgid "close shutter" msgid "close shutter"
msgstr "ÚÁËÒÙÔØ ÚÁÔ×ÏÒ" msgstr "ÚÁËÒÙÔØ ÚÁÔ×ÏÒ"
@@ -431,7 +431,7 @@ msgstr "
msgid "common device plugin (e.g devfli.so)" msgid "common device plugin (e.g devfli.so)"
msgstr "ÏÂÝÉÊ ÐÌÁÇÉÎ ÄÌÑ ×ÓÅÈ ÕÓÔÒÏÊÓÔ× (ÎÁÐÒÉÍÅÒ, 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, " msgid "configure I/O port pins to given value (decimal number, pin1 is LSB, "
"1 == output, 0 == input)" "1 == output, 0 == input)"
msgstr "ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O × ÚÁÄÁÎÎÏÅ ÓÏÓÔÏÑÎÉÅ (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, " msgstr "ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O × ÚÁÄÁÎÎÏÅ ÓÏÓÔÏÑÎÉÅ (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, "
@@ -462,11 +462,16 @@ msgid "force using image through socket transition even if can use SHM"
msgstr "ÐÒÉÎÕÄÉÔÅÌØÎÏ ÂÒÁÔØ ÉÚÏÂÒÁÖÅÎÉÑ ÉÚ ÓÏËÅÔÁ ÄÁÖÅ ÅÓÌÉ ×ÏÚÍÏÖÎÏ " 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" msgid "get value of I/O port pins"
msgstr "ÐÏÌÕÞÉÔØ ÚÎÁÞÅÎÉÅ ÐÏÒÔÁ I/O" msgstr "ÐÏÌÕÞÉÔØ ÚÎÁÞÅÎÉÅ ÐÏÒÔÁ I/O"
#: cmdlnopts.c:77 #: cmdlnopts.c:76
msgid "horizontal binning to N pixels" msgid "horizontal binning to N pixels"
msgstr "ÇÏÒÉÚÏÎÔÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ" msgstr "ÇÏÒÉÚÏÎÔÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ"
@@ -478,36 +483,36 @@ msgstr "
msgid "list connected devices" msgid "list connected devices"
msgstr "ÓÐÉÓÏË ÐÏÄËÌÀÞÅÎÎÙÈ ÕÓÔÒÏÊÓÔ×" msgstr "ÓÐÉÓÏË ÐÏÄËÌÀÞÅÎÎÙÈ ÕÓÔÒÏÊÓÔ×"
#: cmdlnopts.c:108 #: cmdlnopts.c:107
msgid "local INET command socket port" msgid "local INET command socket port"
msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ" msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ"
#: cmdlnopts.c:106 #: cmdlnopts.c:105
msgid "logging file name (if run as server)" msgid "logging file name (if run as server)"
msgstr "ÉÍÑ ÆÁÊÌÁ ÌÏÇÇÉÒÏ×ÁÎÉÑ (ÅÓÌÉ ÚÁÐÕÝÅÎ ÓÅÒ×ÅÒ)" msgstr "ÉÍÑ ÆÁÊÌÁ ÌÏÇÇÉÒÏ×ÁÎÉÑ (ÅÓÌÉ ÚÁÐÕÝÅÎ ÓÅÒ×ÅÒ)"
#: cmdlnopts.c:80 #: cmdlnopts.c:79
msgid "make pause for N seconds between expositions" msgid "make pause for N seconds between expositions"
msgstr "ÐÁÕÚÁ × N ÓÅËÕÎÄ ÍÅÖÄÕ ÜËÓÐÏÚÉÃÉÑÍÉ" msgstr "ÐÁÕÚÁ × N ÓÅËÕÎÄ ÍÅÖÄÕ ÜËÓÐÏÚÉÃÉÑÍÉ"
#: cmdlnopts.c:79 #: cmdlnopts.c:78
msgid "make series of N frames" msgid "make series of N frames"
msgstr "ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ ÉÚ N ËÁÄÒÏ×" msgstr "ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ ÉÚ N ËÁÄÒÏ×"
#: cmdlnopts.c:98 #: cmdlnopts.c:97
msgid "move focuser to absolute position, mm" msgid "move focuser to absolute position, mm"
msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÁÂÓÏÌÀÔÎÏÅ ÐÏÌÏÖÅÎÉÅ, ÍÍ" msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÁÂÓÏÌÀÔÎÏÅ ÐÏÌÏÖÅÎÉÅ, ÍÍ"
#: cmdlnopts.c:99 #: cmdlnopts.c:98
msgid "move focuser to relative position, mm (only for standalone)" msgid "move focuser to relative position, mm (only for standalone)"
msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÏÔÎÏÓÉÔÅÌØÎÏÅ ÐÏÌÏÖÅÎÉÅ, ÍÍ (ÎÅ ÄÌÑ ÓÅÒ×ÅÒ/" msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÏÔÎÏÓÉÔÅÌØÎÏÅ ÐÏÌÏÖÅÎÉÅ, ÍÍ (ÎÅ ÄÌÑ ÓÅÒ×ÅÒ/"
"ËÌÉÅÎÔ)" "ËÌÉÅÎÔ)"
#: cmdlnopts.c:93 #: cmdlnopts.c:92
msgid "move stepper motor asynchronous" msgid "move stepper motor asynchronous"
msgstr "ÁÓÉÎÈÒÏÎÎÏÅ Ä×ÉÖÅÎÉÅ ÛÁÇÏ×ÏÇÏ Ä×ÉÇÁÔÅÌÑ" msgstr "ÁÓÉÎÈÒÏÎÎÏÅ Ä×ÉÖÅÎÉÅ ÛÁÇÏ×ÏÇÏ Ä×ÉÇÁÔÅÌÑ"
#: cmdlnopts.c:113 #: cmdlnopts.c:112
msgid "network answer timeout (default: 0.1s)" msgid "network answer timeout (default: 0.1s)"
msgstr "" msgstr ""
@@ -539,7 +544,7 @@ msgstr "
msgid "on" msgid "on"
msgstr "×ËÌ" msgstr "×ËÌ"
#: cmdlnopts.c:88 #: cmdlnopts.c:87
msgid "open shutter" msgid "open shutter"
msgstr "ÏÔËÒÙÔØ ÚÁÔ×ÏÒ" msgstr "ÏÔËÒÙÔØ ÚÁÔ×ÏÒ"
@@ -547,7 +552,7 @@ msgstr "
msgid "output file name" msgid "output file name"
msgstr "ÉÍÑ ÆÁÊÌÁ" msgstr "ÉÍÑ ÆÁÊÌÁ"
#: cmdlnopts.c:111 #: cmdlnopts.c:110
msgid "passive viewer (only get last images)" msgid "passive viewer (only get last images)"
msgstr "ÐÁÓÓÉ×ÎÙÊ ÐÒÏÓÍÏÔÒ (ÔÏÌØËÏ ÐÏÓÌÅÄÎÉÅ ËÁÄÒÙ)" msgstr "ÐÁÓÓÉ×ÎÙÊ ÐÒÏÓÍÏÔÒ (ÔÏÌØËÏ ÐÏÓÌÅÄÎÉÅ ËÁÄÒÙ)"
@@ -555,7 +560,7 @@ msgstr "
msgid "program author" msgid "program author"
msgstr "Á×ÔÏÒ ÐÒÏÇÒÁÍÍÙ" msgstr "Á×ÔÏÒ ÐÒÏÇÒÁÍÍÙ"
#: cmdlnopts.c:112 #: cmdlnopts.c:111
msgid "restart image server" msgid "restart image server"
msgstr "ÐÅÒÅÚÁÐÕÓË ÓÅÒ×ÅÒÁ" msgstr "ÐÅÒÅÚÁÐÕÓË ÓÅÒ×ÅÒÁ"
@@ -563,15 +568,15 @@ msgstr "
msgid "rewrite output file if exists" msgid "rewrite output file if exists"
msgstr "ÐÅÒÅÚÁÐÉÓØ ×ÙÈÏÄÎÏÇÏ ÆÁÊÌÁ" msgstr "ÐÅÒÅÚÁÐÉÓØ ×ÙÈÏÄÎÏÇÏ ÆÁÊÌÁ"
#: cmdlnopts.c:110 #: cmdlnopts.c:109
msgid "run as client" msgid "run as client"
msgstr "ÚÁÐÕÓÔÉÔØ ËÌÉÅÎÔ" msgstr "ÚÁÐÕÓÔÉÔØ ËÌÉÅÎÔ"
#: cmdlnopts.c:91 #: cmdlnopts.c:90
msgid "run exposition on HIGH @ pin5 I/O port" msgid "run exposition on HIGH @ pin5 I/O port"
msgstr "ÚÁÐÕÓË ÜËÓÐÏÚÉÃÉÉ ÐÏ ÷ùóïëïíõ ÓÉÇÎÁÌÕ ÎÁ ËÏÎÔÁËÔÅ 5 ÐÏÒÔÁ I/O" msgstr "ÚÁÐÕÓË ÜËÓÐÏÚÉÃÉÉ ÐÏ ÷ùóïëïíõ ÓÉÇÎÁÌÕ ÎÁ ËÏÎÔÁËÔÅ 5 ÐÏÒÔÁ I/O"
#: cmdlnopts.c:90 #: cmdlnopts.c:89
msgid "run exposition on LOW @ pin5 I/O port" msgid "run exposition on LOW @ pin5 I/O port"
msgstr "ÚÁÐÕÓË ÜËÓÐÏÚÉÃÉÉ ÐÏ îéúëïíõ ÓÉÇÎÁÌÕ ÎÁ ËÏÎÔÁËÔÅ 5 ÐÏÒÔÁ I/O" msgstr "ÚÁÐÕÓË ÜËÓÐÏÚÉÃÉÉ ÐÏ îéúëïíõ ÓÉÇÎÁÌÕ ÎÁ ËÏÎÔÁËÔÅ 5 ÐÏÒÔÁ I/O"
@@ -583,11 +588,11 @@ msgstr "8-
msgid "set CCD temperature to given value (degr C)" msgid "set CCD temperature to given value (degr C)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ (ÇÒÁÄã)" msgstr "ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ (ÇÒÁÄã)"
#: cmdlnopts.c:95 #: cmdlnopts.c:94
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)" msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÏÒÔ I/O (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, pin1 - ÍÌÁÄÛÉÊ ÂÉÔ)" msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÏÒÔ I/O (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, pin1 - ÍÌÁÄÛÉÊ ÂÉÔ)"
#: cmdlnopts.c:81 #: cmdlnopts.c:80
msgid "set exposure time to given value (seconds!)" msgid "set exposure time to given value (seconds!)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ×ÒÅÍÑ ÜËÓÐÏÚÉÃÉÉ (ÓÅËÕÎÄÙ!)" msgstr "ÕÓÔÁÎÏ×ÉÔØ ×ÒÅÍÑ ÜËÓÐÏÚÉÃÉÉ (ÓÅËÕÎÄÙ!)"
@@ -595,7 +600,7 @@ msgstr "
msgid "set fan speed (0 - off, 1 - low, 2 - high)" msgid "set fan speed (0 - off, 1 - low, 2 - high)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÁ (0 - ×ÙËÌ, 1 - ÎÉÚËÁÑ, 2 - ×ÙÓÏËÁÑ)" msgstr "ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÁ (0 - ×ÙËÌ, 1 - ÎÉÚËÁÑ, 2 - ×ÙÓÏËÁÑ)"
#: cmdlnopts.c:101 #: cmdlnopts.c:100
msgid "set wheel position" msgid "set wheel position"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ" msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ"
@@ -612,20 +617,21 @@ msgid "start (!=0) or stop(==0) infinity capturing loop"
msgstr "ÎÁÞÁÔØ (!=0) ÉÌÉ ÚÁËÏÎÞÉÔØ (==0) ÂÅÓËÏÎÅÞÎÙÊ ÃÉËÌ ÚÁÈ×ÁÔÁ ÉÚÏÂÒÁÖÅÎÉÊ" msgstr "ÎÁÞÁÔØ (!=0) ÉÌÉ ÚÁËÏÎÞÉÔØ (==0) ÂÅÓËÏÎÅÞÎÙÊ ÃÉËÌ ÚÁÈ×ÁÔÁ ÉÚÏÂÒÁÖÅÎÉÊ"
#: cmdlnopts.c:59 #: 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 - ×ÓÅ)" msgstr "ÕÒÏ×ÅÎØ ÂÏÌÔÌÉ×ÏÓÔÉ (-V - ÓÏÏÂÝÅÎÉÑ, -VV - ÏÔÌÁÄËÁ, -VVV - ×ÓÅ)"
#: cmdlnopts.c:78 #: cmdlnopts.c:77
msgid "vertical binning to N pixels" msgid "vertical binning to N pixels"
msgstr "×ÅÒÔÉËÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ" msgstr "×ÅÒÔÉËÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ"
#: cmdlnopts.c:74
msgid "wait while exposition ends"
msgstr "ÖÄÁÔØ, ÐÏËÁ ÎÅ ËÏÎÞÉÔÓÑ ÜËÓÐÏÚÉÃÉÑ"
#: cmdlnopts.c:52 #: cmdlnopts.c:52
msgid "wheel device plugin (e.g. devdummy.so)" msgid "wheel device plugin (e.g. devdummy.so)"
msgstr "ÐÌÁÇÉÎ ÕÓÔÒÏÊÓÔ×Á ÔÕÒÅÌÉ (ÎÁÐÒÉÍÅÒ, devdummy.so)" msgstr "ÐÌÁÇÉÎ ÕÓÔÒÏÊÓÔ×Á ÔÕÒÅÌÉ (ÎÁÐÒÉÍÅÒ, devdummy.so)"
#~ msgid "Camera device unknown" #~ msgid "Camera device unknown"
#~ msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÏÐÏÚÎÁÎÏ" #~ msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÏÐÏÚÎÁÎÏ"
#~ msgid "wait while exposition ends"
#~ msgstr "ÖÄÁÔØ, ÐÏËÁ ÎÅ ËÏÎÞÉÔÓÑ ÜËÓÐÏÚÉÃÉÑ"

8
main.c
View File

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

251
server.c
View File

@@ -16,13 +16,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdatomic.h> #include <fcntl.h>
#include <netdb.h> #include <netdb.h>
#include <pthread.h> #include <pthread.h>
#include <poll.h> #include <poll.h>
#include <stdatomic.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/mman.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h>
#include <usefull_macros.h> #include <usefull_macros.h>
#include "ccdfunc.h" #include "ccdfunc.h"
@@ -46,6 +49,7 @@ static float tremain = 0.; // time when capture done
// IPC key for shared memory (for client's getter) // IPC key for shared memory (for client's getter)
static key_t shmkey = IPC_PRIVATE; static key_t shmkey = IPC_PRIVATE;
static int isrunning = 1;
typedef struct{ typedef struct{
const char *key; const char *key;
@@ -54,21 +58,24 @@ typedef struct{
// cat | awk '{print "{ " $3 ", \"\" }," }' | sort // cat | awk '{print "{ " $3 ", \"\" }," }' | sort
strpair allcommands[] = { strpair allcommands[] = {
{ CC_CMD_8BIT, "run in 8 bit mode instead of 16 bit" },
{ CC_CMD_AUTHOR, "FITS 'AUTHOR' field" }, { CC_CMD_AUTHOR, "FITS 'AUTHOR' field" },
{ CC_CMD_BRIGHTNESS, "camera brightness" }, { CC_CMD_BRIGHTNESS, "camera brightness" },
{ CC_CMD_CAMDEVNO, "camera device number" }, { 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_CAMLIST, "list all connected cameras" },
{ CC_CMD_CAMFANSPD, "fan speed of camera" }, { CC_CMD_CAMFANSPD, "fan speed of camera" },
{ CC_CMD_CONFIO, "camera IO configuration" }, { CC_CMD_CONFIO, "camera IO configuration" },
{ CC_CMD_DARK, "don't open shutter @ exposure" }, { CC_CMD_DARK, "don't open shutter @ exposure" },
{ CC_CMD_EXPSTATE, "get exposition state (0: cancel, 1: capturing, 2: frame ready, 3: error) " { 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_EXPOSITION, "exposition time" },
{ CC_CMD_FASTSPD, "fast readout speed" }, { CC_CMD_FASTSPD, "fast readout speed" },
{ CC_CMD_FDEVNO, "focuser device number" }, { CC_CMD_FDEVNO, "focuser device number" },
{ CC_CMD_FOCLIST, "list all connected focusers" }, { 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_FGOTO, "focuser position" },
{ CC_CMD_FTEMP, "get focuser body temperature"},
{ CC_CMD_FRAMEFORMAT, "camera frame format (X0,Y0,X1,Y1)" }, { CC_CMD_FRAMEFORMAT, "camera frame format (X0,Y0,X1,Y1)" },
{ CC_CMD_GAIN, "camera gain" }, { CC_CMD_GAIN, "camera gain" },
{ CC_CMD_GETHEADERS, "get last file FITS headers" }, { CC_CMD_GETHEADERS, "get last file FITS headers" },
@@ -76,10 +83,10 @@ strpair allcommands[] = {
{ CC_CMD_HELP, "show this help" }, { CC_CMD_HELP, "show this help" },
{ CC_CMD_IMHEIGHT, "last image height" }, { CC_CMD_IMHEIGHT, "last image height" },
{ CC_CMD_IMWIDTH, "last image width" }, { 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_INFTY, "an infinity loop taking images until there's connected clients" },
{ CC_CMD_INSTRUMENT, "FITS 'INSTRUME' field" }, { CC_CMD_INSTRUMENT, "FITS 'INSTRUME' field" },
{ CC_CMD_IO, "get/set camera IO" }, { CC_CMD_IO, "get/set camera IO" },
{ CC_CMD_8BIT, "run in 8 bit mode instead of 16 bit" },
{ CC_CMD_FRAMEMAX, "camera maximal available format" }, { CC_CMD_FRAMEMAX, "camera maximal available format" },
{ CC_CMD_NFLUSHES, "camera number of preflushes" }, { CC_CMD_NFLUSHES, "camera number of preflushes" },
{ CC_CMD_OBJECT, "FITS 'OBJECT' field" }, { CC_CMD_OBJECT, "FITS 'OBJECT' field" },
@@ -95,7 +102,9 @@ strpair allcommands[] = {
{ CC_CMD_VBIN, "vertical binning" }, { CC_CMD_VBIN, "vertical binning" },
{ CC_CMD_WDEVNO, "wheel device number" }, { CC_CMD_WDEVNO, "wheel device number" },
{ CC_CMD_WLIST, "list all connected wheels" }, { CC_CMD_WLIST, "list all connected wheels" },
{ CC_CMD_WMAXPOS, "get maximap wheel position"},
{ CC_CMD_WPOS, "wheel position" }, { CC_CMD_WPOS, "wheel position" },
{ CC_CMD_WTEMP, "get wheel body temperature"},
{NULL, NULL}, {NULL, NULL},
}; };
@@ -118,39 +127,17 @@ static void unlock(){
static cc_IMG *ima = NULL; static cc_IMG *ima = NULL;
// client-side SHM lock // cleanup semaphore, stop server processes
int client_lock_shm(cc_IMG *img){ void stop_server(){
if(!img) return FALSE; isrunning = 0;
if(pthread_mutex_trylock(&img->mutex))
return FALSE;
return TRUE;
}
// server-side SHM lock (first - try gracefully, next - force)
static void server_lock_shm(cc_IMG *img){
if(!img) return;
double t0 = sl_dtime(); double t0 = sl_dtime();
int locked = FALSE; // wait no more than 1s for graceful closing
// lock socket operations while(sl_dtime() - t0 < 1.){
while(sl_dtime() - t0 < MUTEX_LOCK_TMOUT){ if(isrunning == -1) break;
int l = pthread_mutex_trylock(&img->mutex); usleep(1000);
if(0 == l){
locked = TRUE;
break;
}
if(l == EOWNERDEAD){ // locked while locking thread is dead
pthread_mutex_consistent(&img->mutex);
}
}
if(!locked) while(!client_lock_shm(img)) unlock_shm(img);
}
void unlock_shm(cc_IMG *img){
if(!img) return;
if(pthread_mutex_unlock(&img->mutex)){
LOGERR("Can't unlock image mutex");
ERR("Can't unlock image mutex");
} }
// destroy semaphore
cc_remove_sem();
} }
static void fixima(){ static void fixima(){
@@ -165,16 +152,11 @@ static void fixima(){
// allocate memory for largest possible image // allocate memory for largest possible image
if(!ima){ if(!ima){
ima = cc_getshm(GP->shmkey, camera->array.h * camera->array.w * 2); ima = cc_getshm(GP->shmkey, camera->array.h * camera->array.w * 2);
// init shared robust mutex if(!ima) ERR("Can't allocate memory for image");
pthread_mutexattr_t att; // init shared semaphore
pthread_mutexattr_init(&att); cc_init_sem(TRUE);
pthread_mutexattr_setrobust(&att, PTHREAD_MUTEX_ROBUST);
pthread_mutexattr_setpshared(&att, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&ima->mutex, &att);
} }
if(!ima) ERRX("Can't allocate memory for image"); cc_lock_shm(TRUE);
locked = FALSE;
server_lock_shm(ima);
shmkey = GP->shmkey; shmkey = GP->shmkey;
//if(raw_width == ima->w && raw_height == ima->h) return; // all OK //if(raw_width == ima->w && raw_height == ima->h) return; // all OK
DBG("curformat: %dx%d", curformat.w, curformat.h); DBG("curformat: %dx%d", curformat.w, curformat.h);
@@ -187,7 +169,7 @@ static void fixima(){
DBG("GP->_8bit=%d", GP->_8bit); DBG("GP->_8bit=%d", GP->_8bit);
ima->bytelen = raw_height * raw_width * cc_getNbytes(ima); ima->bytelen = raw_height * raw_width * cc_getNbytes(ima);
DBG("new image: %dx%d", raw_width, raw_height); DBG("new image: %dx%d", raw_width, raw_height);
unlock_shm(ima); cc_unlock_shm();
unlock(); unlock();
} }
@@ -228,7 +210,7 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends
camstate = CAMERA_ERROR; camstate = CAMERA_ERROR;
return; return;
} }
server_lock_shm(ima); cc_lock_shm(TRUE);
if(!camera->capture(ima)){ if(!camera->capture(ima)){
LOGERR("Can't capture image"); LOGERR("Can't capture image");
camstate = CAMERA_ERROR; camstate = CAMERA_ERROR;
@@ -239,7 +221,7 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends
fillFITSheader(ima); fillFITSheader(ima);
++ima->imnumber; // increment counter ++ima->imnumber; // increment counter
} }
unlock_shm(ima); cc_unlock_shm();
} }
camstate = CAMERA_FRAMERDY; camstate = CAMERA_FRAMERDY;
} }
@@ -253,11 +235,20 @@ static void* processCAM(_U_ void *d){
ERRX(_("No camera device")); ERRX(_("No camera device"));
} }
double logt = 0; double logt = 0;
while(1){ #ifdef EBUG
double T = sl_dtime();
#endif
while(isrunning){
if(camflags & FLAG_RESTARTSERVER){ if(camflags & FLAG_RESTARTSERVER){
LOGERR("User asks to restart"); LOGERR("User asks to restart");
signals(1); signals(1);
} }
#ifdef EBUG
if(sl_dtime() - T > 5.){
T = sl_dtime();
printf("\t\t\tprocessCAM(), 5 seconds\n");
}
#endif
usleep(100); usleep(100);
if(tremain < 0.5 && tremain > 0.) usleep(tremain*1e6); if(tremain < 0.5 && tremain > 0.) usleep(tremain*1e6);
if(lock()){ if(lock()){
@@ -616,7 +607,7 @@ static cc_hresult nflusheshandler(_U_ int fd, _U_ const char *key, _U_ const cha
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE; 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]; char buf[64];
if(val){ if(val){
int n = atoi(val); int n = atoi(val);
@@ -625,11 +616,10 @@ static cc_hresult expstatehandler(_U_ int fd, _U_ const char *key, _U_ const cha
return CC_RESULT_OK; return CC_RESULT_OK;
} }
else if(n == CAMERA_CAPTURE){ // start exposition else if(n == CAMERA_CAPTURE){ // start exposition
if(GP->exptime < 1e-9){ if(GP->exptime < 1e-9){ // need exposition time to be set
snprintf(buf, 63, CC_CMD_EXPOSITION "=%g", GP->exptime);
cc_sendstrmessage(fd, buf);
return CC_RESULT_FAIL; return CC_RESULT_FAIL;
} }
if(camstate == CAMERA_CAPTURE) return CC_RESULT_BUSY; // in progress
TIMESTAMP("Get FLAG_STARTCAPTURE"); TIMESTAMP("Get FLAG_STARTCAPTURE");
TIMEINIT(); TIMEINIT();
camflags |= FLAG_STARTCAPTURE; camflags |= FLAG_STARTCAPTURE;
@@ -639,6 +629,10 @@ static cc_hresult expstatehandler(_U_ int fd, _U_ const char *key, _U_ const cha
} }
snprintf(buf, 63, CC_CMD_EXPSTATE "=%d", camstate); snprintf(buf, 63, CC_CMD_EXPSTATE "=%d", camstate);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; 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); snprintf(buf, 63, "camflags=%d", camflags);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
@@ -722,6 +716,22 @@ static cc_hresult handler(_U_ int fd, _U_ const char *key, _U_ const char *val){
/******************************************************************************* /*******************************************************************************
***************************** cc_Wheel handlers ********************************** ***************************** 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){ static cc_hresult wlisthandler(int fd, _U_ const char *key, _U_ const char *val){
if(wheel->Ndevices < 1) return CC_RESULT_FAIL; if(wheel->Ndevices < 1) return CC_RESULT_FAIL;
for(int i = 0; i < wheel->Ndevices; ++i){ for(int i = 0; i < wheel->Ndevices; ++i){
@@ -769,18 +779,42 @@ static cc_hresult wgotohandler(_U_ int fd, _U_ const char *key, _U_ const char *
/******************************************************************************* /*******************************************************************************
**************************** Focuser handlers ********************************* **************************** 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){ static cc_hresult foclisthandler(int fd, _U_ const char *key, _U_ const char *val){
if(focuser->Ndevices < 1) return CC_RESULT_FAIL; if(focuser->Ndevices < 1) return CC_RESULT_FAIL;
for(int i = 0; i < focuser->Ndevices; ++i){ for(int i = 0; i < focuser->Ndevices; ++i){
char modname[256], buf[BUFSIZ]; char modname[256], buf[BUFSIZ];
if(focuser->setDevNo){
if(!focuser->setDevNo(i)) continue; if(!focuser->setDevNo(i)) continue;
}
focuser->getModelName(modname, 255); focuser->getModelName(modname, 255);
snprintf(buf, BUFSIZ-1, CC_CMD_FOCLIST "='%s'", modname); snprintf(buf, BUFSIZ-1, CC_CMD_FOCLIST "='%s'", modname);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
} }
int devno = atomic_load(&focdevno); int devno = atomic_load(&focdevno);
if(devno > -1) focuser->setDevNo(devno); if(devno > -1 && focuser->setDevNo) focuser->setDevNo(devno);
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
static cc_hresult fsetNhandler(int fd, _U_ const char *key, const char *val){ static cc_hresult fsetNhandler(int fd, _U_ const char *key, const char *val){
@@ -821,63 +855,6 @@ static cc_hresult fgotohandler(int fd, _U_ const char *key, const char *val){
**************************** Common handlers ********************************** **************************** 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(binhandler, CC_CMD_HBIN);
RUN(binhandler, CC_CMD_VBIN);
RUN(temphandler, CC_CMD_CAMTEMPER);
RUN(exphandler, CC_CMD_EXPOSITION);
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 // show help
static cc_hresult helphandler(int fd, _U_ const char *key, _U_ const char *val){ static cc_hresult helphandler(int fd, _U_ const char *key, _U_ const char *val){
char buf[256]; char buf[256];
@@ -971,10 +948,10 @@ static cc_hresult chkfoc(char *val){
return CC_RESULT_FAIL; return CC_RESULT_FAIL;
} }
static cc_handleritem items[] = { static cc_handleritem items[] = {
{chktrue,infohandler, CC_CMD_INFO},
{NULL, helphandler, CC_CMD_HELP}, {NULL, helphandler, CC_CMD_HELP},
{NULL, restarthandler, CC_CMD_RESTART}, {NULL, restarthandler, CC_CMD_RESTART},
{chkcc, camlisthandler, CC_CMD_CAMLIST}, {chkcc, camlisthandler, CC_CMD_CAMLIST},
{chkcc, camflagshandler, CC_CMD_CAMFLAGS},
{chkcc, camsetNhandler, CC_CMD_CAMDEVNO}, {chkcc, camsetNhandler, CC_CMD_CAMDEVNO},
{chkcc, camfanhandler, CC_CMD_CAMFANSPD}, {chkcc, camfanhandler, CC_CMD_CAMFANSPD},
{chkcc, exphandler, CC_CMD_EXPOSITION}, {chkcc, exphandler, CC_CMD_EXPOSITION},
@@ -1009,9 +986,14 @@ static cc_handleritem items[] = {
{chkfoc, foclisthandler, CC_CMD_FOCLIST}, {chkfoc, foclisthandler, CC_CMD_FOCLIST},
{chkfoc, fsetNhandler, CC_CMD_FDEVNO}, {chkfoc, fsetNhandler, CC_CMD_FDEVNO},
{chkfoc, fgotohandler, CC_CMD_FGOTO}, {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, wlisthandler, CC_CMD_WLIST},
{chkwhl, wsetNhandler, CC_CMD_WDEVNO}, {chkwhl, wsetNhandler, CC_CMD_WDEVNO},
{chkwhl, wgotohandler, CC_CMD_WPOS}, {chkwhl, wgotohandler, CC_CMD_WPOS},
{chkwhl, wmaxposhandler, CC_CMD_WMAXPOS},
{chkwhl, wtemphandler, CC_CMD_WTEMP},
{NULL, NULL, NULL}, {NULL, NULL, NULL},
}; };
@@ -1046,12 +1028,12 @@ void server(int sock, int imsock){
if(imsock < 0) WARNX("Server run without image transport socket"); if(imsock < 0) WARNX("Server run without image transport socket");
else if(listen(imsock, CC_MAXCLIENTS) == -1){ else if(listen(imsock, CC_MAXCLIENTS) == -1){
WARN("listen()"); WARN("listen()");
LOGWARN("listen()"); LOGERR("server(): error in listen() for image socket");
return; return;
} }
if(listen(sock, CC_MAXCLIENTS) == -1){ if(listen(sock, CC_MAXCLIENTS) == -1){
WARN("listen()"); WARN("listen()");
LOGWARN("listen()"); LOGERR("server(): error in listen() for command socket");
return; return;
} }
// init everything // init everything
@@ -1062,11 +1044,17 @@ void server(int sock, int imsock){
wheeldevini(0); wheeldevini(0);
if(startCCD()) --ctr; if(startCCD()) --ctr;
camdevini(0); camdevini(0);
if(ctr == 3) ERRX("No devices found"); if(ctr == 3){
LOGERR("server(): no devices found");
WARNX("No devices found");
}
// start camera thread // start camera thread
pthread_t camthread; pthread_t camthread;
if(camera){ 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 int nfd = 2; // only two listening sockets @start: command and image
struct pollfd poll_set[CC_MAXCLIENTS+2]; struct pollfd poll_set[CC_MAXCLIENTS+2];
@@ -1080,8 +1068,19 @@ void server(int sock, int imsock){
poll_set[0].events = POLLIN; poll_set[0].events = POLLIN;
poll_set[1].fd = imsock; poll_set[1].fd = imsock;
poll_set[1].events = POLLIN; 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
DBG("poll");
poll(poll_set, nfd, 1); // max timeout - 1ms poll(poll_set, nfd, 1); // max timeout - 1ms
DBG("chk imsock");
//if(imsock > -1 && sl_canread(imsock) > 0){ //if(imsock > -1 && sl_canread(imsock) > 0){
if(imsock > -1 && (poll_set[1].revents & POLLIN)){ if(imsock > -1 && (poll_set[1].revents & POLLIN)){
//uint8_t buf[32]; //uint8_t buf[32];
@@ -1093,6 +1092,10 @@ void server(int sock, int imsock){
DBG("client=%d", client); DBG("client=%d", client);
// sending image could be a very long operation -> run it in separate thread // sending image could be a very long operation -> run it in separate thread
if(client > -1){ if(client > -1){
if(ima->imnumber == 0){
WARNX("Client wants an image, but there's no data");
close(client);
}else{
pthread_t sendthread; pthread_t sendthread;
if(pthread_create(&sendthread, NULL, sendimage, (void*)&client)){ if(pthread_create(&sendthread, NULL, sendimage, (void*)&client)){
WARN("pthread_create()"); WARN("pthread_create()");
@@ -1107,8 +1110,10 @@ void server(int sock, int imsock){
close(client); close(client);
}else DBG("Thread detached"); }else DBG("Thread detached");
} }
}
}else{WARN("accept()"); DBG("disconnected");} }else{WARN("accept()"); DBG("disconnected");}
} }
DBG("chk cmd sock");
if(poll_set[0].revents & POLLIN){ // check main for accept() if(poll_set[0].revents & POLLIN){ // check main for accept()
struct sockaddr_in addr; struct sockaddr_in addr;
socklen_t len = sizeof(addr); socklen_t len = sizeof(addr);
@@ -1128,6 +1133,7 @@ void server(int sock, int imsock){
} }
} }
} }
#if 0
// process some data & send messages to ALL // process some data & send messages to ALL
if(camstate == CAMERA_FRAMERDY || camstate == CAMERA_ERROR){ if(camstate == CAMERA_FRAMERDY || camstate == CAMERA_ERROR){
DBG("new image: timestamp=%.1f, num=%zd", ima->timestamp, ima->imnumber); DBG("new image: timestamp=%.1f, num=%zd", ima->timestamp, ima->imnumber);
@@ -1140,6 +1146,8 @@ void server(int sock, int imsock){
} }
camstate = CAMERA_IDLE; camstate = CAMERA_IDLE;
} }
#endif
DBG("scan connections");
// scan connections // scan connections
for(int fdidx = 2; fdidx < nfd; ++fdidx){ for(int fdidx = 2; fdidx < nfd; ++fdidx){
if((poll_set[fdidx].revents & POLLIN) == 0) continue; if((poll_set[fdidx].revents & POLLIN) == 0) continue;
@@ -1165,8 +1173,9 @@ void server(int sock, int imsock){
--nfd; --nfd;
} }
} }
DBG("Check infty");
// check `infty` // 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 // mark to start new capture in infinity loop when at least one client connected
if(nfd > 2){ if(nfd > 2){
camflags |= FLAG_STARTCAPTURE; camflags |= FLAG_STARTCAPTURE;
@@ -1174,11 +1183,13 @@ void server(int sock, int imsock){
TIMEINIT(); TIMEINIT();
} }
} }
DBG("OK ->");
} }
// never reached WARNX("SERVER STOPPED!");
camstop();
focclose(); focclose();
closewheel(); closewheel();
closecam(); isrunning = -1;
} }
/** /**

View File

@@ -30,5 +30,4 @@
void server(int fd, int imsock); void server(int fd, int imsock);
char *makeabspath(const char *path, int shouldbe); char *makeabspath(const char *path, int shouldbe);
int client_lock_shm(cc_IMG *img); void stop_server();
void unlock_shm(cc_IMG *img);