mirror of
https://github.com/eddyem/CCD_Capture.git
synced 2026-06-21 11:26:30 +03:00
next fixes
This commit is contained in:
@@ -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;
|
||||
|
||||
87
ccdcapture.c
87
ccdcapture.c
@@ -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
|
||||
@@ -253,7 +330,7 @@ char *cc_get_keyval(char **keyval){
|
||||
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);
|
||||
@@ -272,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;
|
||||
|
||||
21
ccdcapture.h
21
ccdcapture.h
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <fitsio.h> // FLEN_CARD
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h> // for size_t
|
||||
|
||||
@@ -29,10 +30,12 @@
|
||||
// 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 {
|
||||
typedef struct __attribute__((packed)){
|
||||
uint32_t MAGICK; // magick (DEADBEEF) - to mark our shm
|
||||
pthread_mutex_t mutex; // shared mutex
|
||||
double timestamp; // timestamp of image taken
|
||||
uint8_t bitpix; // bits per pixel (8 or 16)
|
||||
int w, h; // image size
|
||||
@@ -221,7 +224,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"
|
||||
@@ -240,7 +242,8 @@ typedef enum{
|
||||
#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"
|
||||
@@ -269,11 +272,16 @@ typedef enum{
|
||||
#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
|
||||
@@ -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);
|
||||
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();
|
||||
|
||||
27
ccdfunc.c
27
ccdfunc.c
@@ -384,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)){
|
||||
@@ -402,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;
|
||||
@@ -423,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(){
|
||||
@@ -472,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)){
|
||||
@@ -492,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(){
|
||||
@@ -923,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
|
||||
|
||||
86
client.c
86
client.c
@@ -53,7 +53,7 @@ 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;
|
||||
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
|
||||
@@ -118,6 +118,7 @@ static int getans(int sock, const char *msg){
|
||||
double t0 = sl_dtime();
|
||||
char *ans = NULL;
|
||||
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
|
||||
cc_hresult res = CC_RESULT_FAIL;
|
||||
while(sl_dtime() - t0 < tmout){
|
||||
@@ -161,16 +162,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
|
||||
@@ -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);
|
||||
}
|
||||
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);
|
||||
@@ -255,9 +273,11 @@ static int getimage(int askheader){
|
||||
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(client_lock_shm(shmima)){
|
||||
if(cc_lock_shm(FALSE)){
|
||||
DBG("Locked");
|
||||
shmlocked = TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -269,6 +289,7 @@ static int getimage(int askheader){
|
||||
}
|
||||
memcpy(&ima, shmima, sizeof(cc_IMG));
|
||||
}else{ // get image by socket
|
||||
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
|
||||
@@ -292,11 +313,12 @@ static int getimage(int askheader){
|
||||
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){
|
||||
unlock_shm(shmima);
|
||||
cc_unlock_shm();
|
||||
shmlocked = FALSE;
|
||||
}
|
||||
ret = TRUE;
|
||||
@@ -337,11 +359,17 @@ static int getimage(int askheader){
|
||||
}else WARNX("Still got old image");
|
||||
eofg:
|
||||
if(imsock != -1) close(imsock);
|
||||
if(shmlocked) unlock_shm(shmima);
|
||||
if(shmlocked) cc_unlock_shm();
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -349,43 +377,40 @@ void client(int sock){
|
||||
TIMEINIT();
|
||||
send_headers(sock);
|
||||
TIMESTAMP("Got headers");
|
||||
double t0 = sl_dtime(), tw = t0;
|
||||
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;
|
||||
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;
|
||||
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...");
|
||||
if(GP->waitexpend){
|
||||
atomic_store(&expstate, CAMERA_CAPTURE); // could be changed earlier
|
||||
verbose(2, "Wait for exposition end");
|
||||
}
|
||||
t0 = sl_dtime();
|
||||
tw = tstart = t0;
|
||||
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
|
||||
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(sl_dtime() - tstart < GP->exptime){
|
||||
t0 = sl_dtime(); // refresh timeout until exp not ends
|
||||
}else{
|
||||
SENDCMDW(CC_CMD_EXPSTATE);
|
||||
#ifdef EBUG
|
||||
usleep(300000);
|
||||
#endif
|
||||
}
|
||||
int curst = atomic_load(&expstate);
|
||||
if(curst == CAMERA_ERROR){
|
||||
WARNX(_("Can't make exposition"));
|
||||
if(Nremain > 1){
|
||||
verbose(1, "Exposing frame %d...", nframe);
|
||||
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
|
||||
tstart = sl_dtime();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -395,6 +420,7 @@ void client(int sock){
|
||||
if(Nremain > 1){
|
||||
verbose(1, "Exposing frame %d...", nframe+1);
|
||||
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
|
||||
tstart = sl_dtime();
|
||||
}
|
||||
verbose(2, "Frame ready, try to grab");
|
||||
int failed = TRUE;
|
||||
@@ -410,6 +436,7 @@ void client(int sock){
|
||||
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){
|
||||
@@ -424,14 +451,12 @@ void client(int sock){
|
||||
}
|
||||
}
|
||||
}else{
|
||||
GP->waitexpend = 0;
|
||||
DBG("All images saved -> exit");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(GP->waitexpend) WARNX(_("Server timeout"));
|
||||
if(Nremain > 0) WARNX(_("Server timeout"));
|
||||
}
|
||||
|
||||
#ifdef IMAGEVIEW
|
||||
@@ -442,6 +467,7 @@ void init_grab_sock(int 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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")},
|
||||
|
||||
@@ -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.
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\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"
|
||||
"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 ""
|
||||
@@ -491,12 +494,12 @@ msgstr ""
|
||||
msgid "Can't set brightness to %g"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:690 server.c:332
|
||||
#: ccdfunc.c:690 server.c:323
|
||||
#, c-format
|
||||
msgid "Can't set binning %dx%d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:702 server.c:333
|
||||
#: ccdfunc.c:702 server.c:324
|
||||
msgid "Can't set given geometry"
|
||||
msgstr ""
|
||||
|
||||
@@ -544,11 +547,11 @@ msgstr ""
|
||||
msgid "Capture frame %d"
|
||||
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`"
|
||||
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"
|
||||
msgstr ""
|
||||
|
||||
@@ -560,7 +563,7 @@ msgstr ""
|
||||
msgid "Read grabbed image"
|
||||
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`"
|
||||
msgstr ""
|
||||
|
||||
@@ -568,7 +571,7 @@ msgstr ""
|
||||
msgid "Can't grab image"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:778 client.c:420
|
||||
#: ccdfunc.c:778 client.c:447
|
||||
#, c-format
|
||||
msgid "%d seconds till pause ends\n"
|
||||
msgstr ""
|
||||
@@ -577,15 +580,15 @@ msgstr ""
|
||||
msgid "Some error when capture"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:253
|
||||
#: server.c:235
|
||||
msgid "No camera device"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:385
|
||||
#: client.c:409
|
||||
msgid "Can't make exposition"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:434
|
||||
#: client.c:459
|
||||
msgid "Server timeout"
|
||||
msgstr ""
|
||||
|
||||
|
||||
100
locale/ru/ru.po
100
locale/ru/ru.po
@@ -7,7 +7,7 @@
|
||||
msgid ""
|
||||
msgstr "Project-Id-Version: PACKAGE VERSION\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"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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"
|
||||
msgstr "%.1f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ"
|
||||
|
||||
#: ccdfunc.c:778 client.c:420
|
||||
#: ccdfunc.c:778 client.c:447
|
||||
#, c-format
|
||||
msgid "%d seconds till pause ends\n"
|
||||
msgstr "%d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n"
|
||||
@@ -30,11 +30,11 @@ msgstr "%d
|
||||
msgid "Already initialized!"
|
||||
msgstr "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!"
|
||||
|
||||
#: cmdlnopts.c:104
|
||||
#: cmdlnopts.c:103
|
||||
msgid "CMOS brightness level"
|
||||
msgstr "ÕÒÏ×ÅÎØ ÑÒËÏÓÔÉ CMOS"
|
||||
|
||||
#: cmdlnopts.c:103
|
||||
#: cmdlnopts.c:102
|
||||
msgid "CMOS gain level"
|
||||
msgstr "ÕÒÏ×ÅÎØ Gain CMOS"
|
||||
|
||||
@@ -66,12 +66,12 @@ msgstr "
|
||||
msgid "Camera plugin have no fun speed setter"
|
||||
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
|
||||
msgid "Camera plugin have no function `capture`"
|
||||
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
|
||||
msgid "Camera plugin have no function `start exposition`"
|
||||
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
|
||||
@@ -130,7 +130,7 @@ msgstr "
|
||||
msgid "Can't init mutex!"
|
||||
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
|
||||
|
||||
#: client.c:385
|
||||
#: client.c:409
|
||||
msgid "Can't make exposition"
|
||||
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ÜËÓÐÏÚÉÃÉÀ"
|
||||
|
||||
@@ -174,7 +174,7 @@ msgstr "
|
||||
msgid "Can't set active wheel number"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ"
|
||||
|
||||
#: ccdfunc.c:690 server.c:332
|
||||
#: ccdfunc.c:690 server.c:323
|
||||
#, c-format
|
||||
msgid "Can't set binning %dx%d"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d"
|
||||
@@ -202,7 +202,7 @@ msgstr "
|
||||
msgid "Can't set gain to %g"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
|
||||
|
||||
#: ccdfunc.c:702 server.c:333
|
||||
#: ccdfunc.c:702 server.c:324
|
||||
msgid "Can't set given geometry"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ"
|
||||
|
||||
@@ -225,7 +225,7 @@ msgstr "
|
||||
msgid "Can't set wheel position %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"
|
||||
msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ"
|
||||
|
||||
@@ -291,7 +291,7 @@ msgstr "
|
||||
msgid "Histogram conversion: %s"
|
||||
msgstr "ðÒÅÏÂÒÁÚÏ×ÁÎÉÅ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
|
||||
|
||||
#: cmdlnopts.c:109
|
||||
#: cmdlnopts.c:108
|
||||
msgid "INET image socket port"
|
||||
msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ ÐÅÒÅÄÁÞÉ ÉÚÏÂÒÁÖÅÎÉÑ"
|
||||
|
||||
@@ -300,11 +300,11 @@ msgstr "
|
||||
msgid "Image stat:\n"
|
||||
msgstr "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ: \n"
|
||||
|
||||
#: cmdlnopts.c:76
|
||||
#: cmdlnopts.c:75
|
||||
msgid "N flushes before exposing (default: 1)"
|
||||
msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)"
|
||||
|
||||
#: server.c:253
|
||||
#: server.c:235
|
||||
msgid "No camera device"
|
||||
msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ"
|
||||
|
||||
@@ -338,7 +338,7 @@ msgstr "
|
||||
msgid "Readout mode: %s"
|
||||
msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s"
|
||||
|
||||
#: client.c:434
|
||||
#: client.c:459
|
||||
msgid "Server timeout"
|
||||
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
|
||||
|
||||
@@ -376,7 +376,7 @@ msgstr "
|
||||
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-ÓÏËÅÔÁ"
|
||||
|
||||
@@ -389,21 +389,21 @@ msgstr "
|
||||
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 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
|
||||
|
||||
@@ -419,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 "ÚÁËÒÙÔØ ÚÁÔ×ÏÒ"
|
||||
|
||||
@@ -431,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 × ÚÁÄÁÎÎÏÅ ÓÏÓÔÏÑÎÉÅ (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, "
|
||||
@@ -462,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 ÐÉËÓÅÌÅÊ"
|
||||
|
||||
@@ -478,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 ""
|
||||
|
||||
@@ -539,7 +544,7 @@ msgstr "
|
||||
msgid "on"
|
||||
msgstr "×ËÌ"
|
||||
|
||||
#: cmdlnopts.c:88
|
||||
#: cmdlnopts.c:87
|
||||
msgid "open shutter"
|
||||
msgstr "ÏÔËÒÙÔØ ÚÁÔ×ÏÒ"
|
||||
|
||||
@@ -547,7 +552,7 @@ msgstr "
|
||||
msgid "output file name"
|
||||
msgstr "ÉÍÑ ÆÁÊÌÁ"
|
||||
|
||||
#: cmdlnopts.c:111
|
||||
#: cmdlnopts.c:110
|
||||
msgid "passive viewer (only get last images)"
|
||||
msgstr "ÐÁÓÓÉ×ÎÙÊ ÐÒÏÓÍÏÔÒ (ÔÏÌØËÏ ÐÏÓÌÅÄÎÉÅ ËÁÄÒÙ)"
|
||||
|
||||
@@ -555,7 +560,7 @@ msgstr "
|
||||
msgid "program author"
|
||||
msgstr "Á×ÔÏÒ ÐÒÏÇÒÁÍÍÙ"
|
||||
|
||||
#: cmdlnopts.c:112
|
||||
#: cmdlnopts.c:111
|
||||
msgid "restart image server"
|
||||
msgstr "ÐÅÒÅÚÁÐÕÓË ÓÅÒ×ÅÒÁ"
|
||||
|
||||
@@ -563,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"
|
||||
|
||||
@@ -583,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 "ÕÓÔÁÎÏ×ÉÔØ ×ÒÅÍÑ ÜËÓÐÏÚÉÃÉÉ (ÓÅËÕÎÄÙ!)"
|
||||
|
||||
@@ -595,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 "ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ"
|
||||
|
||||
@@ -612,20 +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 "Camera device unknown"
|
||||
#~ msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÏÐÏÚÎÁÎÏ"
|
||||
|
||||
#~ msgid "wait while exposition ends"
|
||||
#~ msgstr "ÖÄÁÔØ, ÐÏËÁ ÎÅ ËÏÎÞÉÔÓÑ ÜËÓÐÏÚÉÃÉÑ"
|
||||
|
||||
8
main.c
8
main.c
@@ -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,6 +128,7 @@ 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);
|
||||
|
||||
251
server.c
251
server.c
@@ -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"
|
||||
@@ -46,6 +49,7 @@ static float tremain = 0.; // time when capture done
|
||||
|
||||
// IPC key for shared memory (for client's getter)
|
||||
static key_t shmkey = IPC_PRIVATE;
|
||||
static int isrunning = 1;
|
||||
|
||||
typedef struct{
|
||||
const char *key;
|
||||
@@ -54,21 +58,24 @@ 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_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" },
|
||||
@@ -76,10 +83,10 @@ strpair allcommands[] = {
|
||||
{ CC_CMD_HELP, "show this help" },
|
||||
{ CC_CMD_IMHEIGHT, "last image height" },
|
||||
{ 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_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" },
|
||||
@@ -95,7 +102,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},
|
||||
};
|
||||
|
||||
@@ -118,39 +127,17 @@ static void unlock(){
|
||||
|
||||
static cc_IMG *ima = NULL;
|
||||
|
||||
// client-side SHM lock
|
||||
int client_lock_shm(cc_IMG *img){
|
||||
if(!img) return FALSE;
|
||||
if(pthread_mutex_trylock(&img->mutex))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// server-side SHM lock (first - try gracefully, next - force)
|
||||
static void server_lock_shm(cc_IMG *img){
|
||||
if(!img) return;
|
||||
// cleanup semaphore, stop server processes
|
||||
void stop_server(){
|
||||
isrunning = 0;
|
||||
double t0 = sl_dtime();
|
||||
int locked = FALSE;
|
||||
// lock socket operations
|
||||
while(sl_dtime() - t0 < MUTEX_LOCK_TMOUT){
|
||||
int l = pthread_mutex_trylock(&img->mutex);
|
||||
if(0 == l){
|
||||
locked = TRUE;
|
||||
break;
|
||||
}
|
||||
if(l == EOWNERDEAD){ // locked while locking thread is dead
|
||||
pthread_mutex_consistent(&img->mutex);
|
||||
}
|
||||
}
|
||||
if(!locked) while(!client_lock_shm(img)) unlock_shm(img);
|
||||
}
|
||||
|
||||
void unlock_shm(cc_IMG *img){
|
||||
if(!img) return;
|
||||
if(pthread_mutex_unlock(&img->mutex)){
|
||||
LOGERR("Can't unlock image mutex");
|
||||
ERR("Can't unlock image mutex");
|
||||
// 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(){
|
||||
@@ -165,16 +152,11 @@ static void fixima(){
|
||||
// allocate memory for largest possible image
|
||||
if(!ima){
|
||||
ima = cc_getshm(GP->shmkey, camera->array.h * camera->array.w * 2);
|
||||
// init shared robust mutex
|
||||
pthread_mutexattr_t att;
|
||||
pthread_mutexattr_init(&att);
|
||||
pthread_mutexattr_setrobust(&att, PTHREAD_MUTEX_ROBUST);
|
||||
pthread_mutexattr_setpshared(&att, PTHREAD_PROCESS_SHARED);
|
||||
pthread_mutex_init(&ima->mutex, &att);
|
||||
if(!ima) ERR("Can't allocate memory for image");
|
||||
// init shared semaphore
|
||||
cc_init_sem(TRUE);
|
||||
}
|
||||
if(!ima) ERRX("Can't allocate memory for image");
|
||||
locked = FALSE;
|
||||
server_lock_shm(ima);
|
||||
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);
|
||||
@@ -187,7 +169,7 @@ static void fixima(){
|
||||
DBG("GP->_8bit=%d", GP->_8bit);
|
||||
ima->bytelen = raw_height * raw_width * cc_getNbytes(ima);
|
||||
DBG("new image: %dx%d", raw_width, raw_height);
|
||||
unlock_shm(ima);
|
||||
cc_unlock_shm();
|
||||
unlock();
|
||||
}
|
||||
|
||||
@@ -228,7 +210,7 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends
|
||||
camstate = CAMERA_ERROR;
|
||||
return;
|
||||
}
|
||||
server_lock_shm(ima);
|
||||
cc_lock_shm(TRUE);
|
||||
if(!camera->capture(ima)){
|
||||
LOGERR("Can't capture image");
|
||||
camstate = CAMERA_ERROR;
|
||||
@@ -239,7 +221,7 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends
|
||||
fillFITSheader(ima);
|
||||
++ima->imnumber; // increment counter
|
||||
}
|
||||
unlock_shm(ima);
|
||||
cc_unlock_shm();
|
||||
}
|
||||
camstate = CAMERA_FRAMERDY;
|
||||
}
|
||||
@@ -253,11 +235,20 @@ 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);
|
||||
}
|
||||
#ifdef EBUG
|
||||
if(sl_dtime() - T > 5.){
|
||||
T = sl_dtime();
|
||||
printf("\t\t\tprocessCAM(), 5 seconds\n");
|
||||
}
|
||||
#endif
|
||||
usleep(100);
|
||||
if(tremain < 0.5 && tremain > 0.) usleep(tremain*1e6);
|
||||
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;
|
||||
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);
|
||||
@@ -625,11 +616,10 @@ static cc_hresult expstatehandler(_U_ int fd, _U_ const char *key, _U_ const cha
|
||||
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) return CC_RESULT_BUSY; // in progress
|
||||
TIMESTAMP("Get FLAG_STARTCAPTURE");
|
||||
TIMEINIT();
|
||||
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);
|
||||
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;
|
||||
@@ -722,6 +716,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){
|
||||
@@ -769,18 +779,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){
|
||||
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;
|
||||
}
|
||||
int devno = atomic_load(&focdevno);
|
||||
if(devno > -1) focuser->setDevNo(devno);
|
||||
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){
|
||||
@@ -821,63 +855,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(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
|
||||
static cc_hresult helphandler(int fd, _U_ const char *key, _U_ const char *val){
|
||||
char buf[256];
|
||||
@@ -971,10 +948,10 @@ 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},
|
||||
@@ -1009,9 +986,14 @@ static cc_handleritem items[] = {
|
||||
{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},
|
||||
};
|
||||
|
||||
@@ -1046,12 +1028,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
|
||||
@@ -1062,11 +1044,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];
|
||||
@@ -1080,8 +1068,19 @@ 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
|
||||
DBG("poll");
|
||||
poll(poll_set, nfd, 1); // max timeout - 1ms
|
||||
DBG("chk imsock");
|
||||
//if(imsock > -1 && sl_canread(imsock) > 0){
|
||||
if(imsock > -1 && (poll_set[1].revents & POLLIN)){
|
||||
//uint8_t buf[32];
|
||||
@@ -1093,6 +1092,10 @@ void server(int sock, int imsock){
|
||||
DBG("client=%d", client);
|
||||
// sending image could be a very long operation -> run it in separate thread
|
||||
if(client > -1){
|
||||
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()");
|
||||
@@ -1107,8 +1110,10 @@ void server(int sock, int imsock){
|
||||
close(client);
|
||||
}else DBG("Thread detached");
|
||||
}
|
||||
}
|
||||
}else{WARN("accept()"); DBG("disconnected");}
|
||||
}
|
||||
DBG("chk cmd sock");
|
||||
if(poll_set[0].revents & POLLIN){ // check main for accept()
|
||||
struct sockaddr_in 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
|
||||
if(camstate == CAMERA_FRAMERDY || camstate == CAMERA_ERROR){
|
||||
DBG("new image: timestamp=%.1f, num=%zd", ima->timestamp, ima->imnumber);
|
||||
@@ -1140,6 +1146,8 @@ void server(int sock, int imsock){
|
||||
}
|
||||
camstate = CAMERA_IDLE;
|
||||
}
|
||||
#endif
|
||||
DBG("scan connections");
|
||||
// scan connections
|
||||
for(int fdidx = 2; fdidx < nfd; ++fdidx){
|
||||
if((poll_set[fdidx].revents & POLLIN) == 0) continue;
|
||||
@@ -1165,8 +1173,9 @@ void server(int sock, int imsock){
|
||||
--nfd;
|
||||
}
|
||||
}
|
||||
DBG("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
|
||||
if(nfd > 2){
|
||||
camflags |= FLAG_STARTCAPTURE;
|
||||
@@ -1174,11 +1183,13 @@ void server(int sock, int imsock){
|
||||
TIMEINIT();
|
||||
}
|
||||
}
|
||||
DBG("OK ->");
|
||||
}
|
||||
// never reached
|
||||
WARNX("SERVER STOPPED!");
|
||||
camstop();
|
||||
focclose();
|
||||
closewheel();
|
||||
closecam();
|
||||
isrunning = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user