mirror of
https://github.com/eddyem/CCD_Capture.git
synced 2026-06-21 19:36:21 +03:00
Compare commits
4 Commits
1f7aad348e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 92c3c54c65 | |||
|
|
94f1cf9656 | ||
| 66e2bdfaac | |||
| f65daab527 |
@@ -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;
|
||||
|
||||
@@ -187,7 +187,7 @@ clients connected.
|
||||
When you send a command to server you will receive:
|
||||
|
||||
- one of answers - "OK" (all OK), "BUSY" (can't run setter because camera is busy), "FAIL" (some error
|
||||
occured), "BADKEY" (wrong key name) or "BADVAL" (wrong key's value) - for procedures and setters
|
||||
occurred), "BADKEY" (wrong key name) or "BADVAL" (wrong key's value) - for procedures and setters
|
||||
(instead of "OK" you will give "parameter=value" for setter if all OK);
|
||||
- "parameter=value" for getters.
|
||||
|
||||
|
||||
95
ccdcapture.c
95
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;
|
||||
@@ -442,8 +525,11 @@ int cc_read2buf(int fd, cc_strbuff *buf){
|
||||
do{
|
||||
rd = read(fd, buf->buf + buf->buflen, maxlen);
|
||||
if(rd <= 0){
|
||||
if(errno == EAGAIN || errno == EWOULDBLOCK) continue;
|
||||
goto ret;
|
||||
if(errno == EINTR){
|
||||
DBG("errno=%d, '%s'", errno, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
goto ret; // EAGAIN or other error -> client disconnected
|
||||
}else break;
|
||||
}while(1);
|
||||
DBG("got %zd bytes", rd);
|
||||
@@ -653,6 +739,7 @@ char *cc_nextkw(char *buf, char record[FLEN_CARD], int newlines){
|
||||
}
|
||||
}else nextline = buf + (FLEN_CARD - 1);
|
||||
strncpy(record, buf, l);
|
||||
if(l < FLEN_CARD) record[l] = 0;
|
||||
return nextline;
|
||||
}
|
||||
|
||||
|
||||
28
ccdcapture.h
28
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
|
||||
@@ -198,9 +201,11 @@ typedef struct{
|
||||
// wait for mutex locking
|
||||
#define CC_BUSY_TIMEOUT (1.0)
|
||||
// wait for exposition ends (between subsequent check calls)
|
||||
#define CC_WAIT_TIMEOUT (2.0)
|
||||
#define CC_WAIT_TIMEOUT (15.0)
|
||||
// client will disconnect after this time from last server message
|
||||
#define CC_CLIENT_TIMEOUT (3.0)
|
||||
#define CC_CLIENT_TIMEOUT (30.0)
|
||||
// minimal sleep (us) time when client waits for exp end
|
||||
#define CC_IMWAIT_SLEEP (1000)
|
||||
|
||||
// fd - socket fd to send private messages, key, val - key and its value
|
||||
typedef cc_hresult (*cc_mesghandler)(int fd, const char *key, const char *val);
|
||||
@@ -221,7 +226,6 @@ typedef enum{
|
||||
} cc_camera_state;
|
||||
|
||||
// common information about everything
|
||||
#define CC_CMD_INFO "info"
|
||||
#define CC_CMD_HELP "help"
|
||||
// restart server
|
||||
#define CC_CMD_RESTART "restartTheServer"
|
||||
@@ -232,6 +236,7 @@ typedef enum{
|
||||
#define CC_CMD_SHMEMKEY "shmemkey"
|
||||
|
||||
// CCD/CMOS
|
||||
#define CC_CMD_IMNUMBER "imnumber"
|
||||
#define CC_CMD_PLUGINCMD "plugincmd"
|
||||
#define CC_CMD_CAMLIST "camlist"
|
||||
#define CC_CMD_CAMDEVNO "camdevno"
|
||||
@@ -240,7 +245,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 +275,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 +348,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
|
||||
|
||||
281
client.c
281
client.c
@@ -39,11 +39,11 @@ extern double answer_timeout;
|
||||
static char sendbuf[BUFSIZ];
|
||||
static char *lastfilename = NULL;
|
||||
// send message and wait any answer
|
||||
#define SENDMSG(...) do{DBG("SENDMSG"); snprintf(sendbuf, BUFSIZ-1, __VA_ARGS__); verbose(2, "\t> %s", sendbuf); cc_sendstrmessage(sock, sendbuf); while(getans(sock, NULL));} while(0)
|
||||
#define SENDMSG(...) do{DBG("SENDMSG"); snprintf(sendbuf, BUFSIZ-1, __VA_ARGS__); verbose(2, "\t> %s", sendbuf); if(!cc_sendstrmessage(sock, sendbuf)) ERRX("Server disconnected"); while(getans(sock, NULL));} while(0)
|
||||
// send message and wait answer starting with 'cmd'
|
||||
#define SENDMSGW(cmd, ...) do{DBG("SENDMSGW"); snprintf(sendbuf, BUFSIZ-1, cmd __VA_ARGS__); verbose(2, "\t> %s", sendbuf); cc_sendstrmessage(sock, sendbuf);}while(!getans(sock, cmd))
|
||||
#define SENDMSGW(cmd, ...) do{DBG("SENDMSGW"); snprintf(sendbuf, BUFSIZ-1, cmd __VA_ARGS__); verbose(2, "\t> %s", sendbuf); if(!cc_sendstrmessage(sock, sendbuf)) ERRX("Server disconnected");}while(!getans(sock, cmd))
|
||||
// send command and wait for answer on it
|
||||
#define SENDCMDW(cmd) do{DBG("SENDCMDW"); strncpy(sendbuf, cmd, BUFSIZ-1); verbose(2, "\t> %s", sendbuf); cc_sendstrmessage(sock, sendbuf);}while(!getans(sock, cmd))
|
||||
#define SENDCMDW(cmd) do{DBG("SENDCMDW"); strncpy(sendbuf, cmd, BUFSIZ-1); verbose(2, "\t> %s", sendbuf); if(!cc_sendstrmessage(sock, sendbuf)) ERRX("Server disconnected");}while(!getans(sock, cmd))
|
||||
static volatile atomic_int expstate = CAMERA_CAPTURE;
|
||||
static int xm0,ym0,xm1,ym1; // max format
|
||||
static int xc0,yc0,xc1,yc1; // current format
|
||||
@@ -53,9 +53,10 @@ 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
|
||||
static int current_image_number = -1; // for net-parser - last number of exposed image
|
||||
|
||||
#if 0
|
||||
// read message from queue or file descriptor
|
||||
static char *readmsg(int fd){
|
||||
static cc_strbuff *buf = NULL;
|
||||
@@ -78,6 +79,7 @@ static char *readmsg(int fd){
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CMP_ANS(cmd, ans) strncmp(cmd, ans, sizeof(cmd)-1)
|
||||
// parser of CCD server messages; return TRUE to exit from polling cycle of `getans` (if receive 'FAIL', 'OK' or 'BUSY')
|
||||
@@ -89,7 +91,7 @@ static cc_hresult parseans(char *ans){
|
||||
for(cc_hresult res = CC_RESULT_BUSY; res < CC_RESULT_NUM; ++res){
|
||||
const char *resmsg = cc_hresult2str(res);
|
||||
if(0 == strcmp(resmsg, ans)){
|
||||
WARNX("Server answered: %s", resmsg);
|
||||
verbose(1, "Server answered: %s", resmsg);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -97,16 +99,18 @@ static cc_hresult parseans(char *ans){
|
||||
if(0 == CMP_ANS(CC_CMD_EXPSTATE, ans)){
|
||||
int st = atoi(val);
|
||||
atomic_store(&expstate, st);
|
||||
DBG("Exposition state: %d", st);
|
||||
return CC_RESULT_OK;
|
||||
DBG("Current state: %d", atomic_load(&expstate));
|
||||
return CC_RESULT_SILENCE;
|
||||
}else if(0 == CMP_ANS(CC_CMD_FRAMEMAX, ans)){
|
||||
sscanf(val, "%d,%d,%d,%d", &xm0, &ym0, &xm1, &ym1);
|
||||
DBG("Got maxformat: %d,%d,%d,%d", xm0, ym0, xm1, ym1);
|
||||
return CC_RESULT_OK;
|
||||
return CC_RESULT_SILENCE;
|
||||
}else if(0 == CMP_ANS(CC_CMD_FRAMEFORMAT, ans)){
|
||||
sscanf(val, "%d,%d,%d,%d", &xc0, &yc0, &xc1, &yc1);
|
||||
DBG("Got current format: %d,%d,%d,%d", xc0, yc0, xc1, yc1);
|
||||
return CC_RESULT_OK;
|
||||
return CC_RESULT_SILENCE;
|
||||
}else if(0 == CMP_ANS(CC_CMD_IMNUMBER, ans)){
|
||||
current_image_number = atoi(val);
|
||||
}
|
||||
//TIMESTAMP("parseans() end");
|
||||
return CC_RESULT_SILENCE; // echo of sent command or something else
|
||||
@@ -116,12 +120,28 @@ static cc_hresult parseans(char *ans){
|
||||
// if msg != NULL - wait for it in answer
|
||||
static int getans(int sock, const char *msg){
|
||||
double t0 = sl_dtime();
|
||||
char buf[BUFSIZ+1];
|
||||
int idx = 0;
|
||||
char *ans = NULL;
|
||||
double tmout = answer_timeout;
|
||||
if(msg) tmout *= 5.; // make first timeout larger for slow networks
|
||||
TIMESTAMP("GetAns(%s)", msg);
|
||||
double tmout = answer_timeout + 5.; // make first timeout larger for slow networks
|
||||
// TODO: increase first timeout up to 15-30s (add key?)
|
||||
cc_hresult res = CC_RESULT_FAIL;
|
||||
while(sl_dtime() - t0 < tmout){
|
||||
ans = readmsg(sock);
|
||||
ans = NULL;
|
||||
if(1 == sl_canread(sock)){
|
||||
ssize_t got = read(sock, buf+idx, BUFSIZ-idx);
|
||||
if(got > 0){
|
||||
idx += got;
|
||||
buf[idx] = 0;
|
||||
char *nl = strchr(buf, '\n');
|
||||
if(nl){
|
||||
*nl = 0;
|
||||
ans = buf;
|
||||
DBG("got '%s'", ans);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!ans) continue;
|
||||
// got answer -> make timeout less
|
||||
tmout = answer_timeout;
|
||||
@@ -131,14 +151,15 @@ static int getans(int sock, const char *msg){
|
||||
DBG("1 msg-> %s, ans -> %s", msg, ans);
|
||||
res = parseans(ans);
|
||||
DBG("2 msg-> %s, ans -> %s; result: %d", msg, ans, res);
|
||||
if(res == CC_RESULT_SILENCE && msg){
|
||||
if(strncmp(ans, msg, strlen(msg))) continue;
|
||||
if(msg){
|
||||
if(res != CC_RESULT_SILENCE || strncmp(ans, msg, strlen(msg))) continue;
|
||||
else res = CC_RESULT_OK;
|
||||
}
|
||||
DBG("Got answer -> break");
|
||||
break;
|
||||
}
|
||||
if(!ans) DBG("Got no answer from server");
|
||||
TIMESTAMP("GetAns(%s), ans: '%s', result: %d", msg, ans, res);
|
||||
if(!ans) DBG("Got no answer from server; result=%d", res);
|
||||
if(res == CC_RESULT_OK) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
@@ -161,16 +182,35 @@ static void send_headers(int sock){
|
||||
DBG("infty=%d", GP->infty);
|
||||
if(GP->infty > -1) SENDMSGW(CC_CMD_INFTY, "=%d", GP->infty);
|
||||
// common information
|
||||
SENDMSG(CC_CMD_INFO);
|
||||
if(GP->listdevices) SENDCMDW(CC_CMD_CAMLIST);
|
||||
if(GP->camdevno > -1) SENDMSGW(CC_CMD_CAMDEVNO, "=%d", GP->camdevno);
|
||||
if(GP->info){
|
||||
SENDCMDW(CC_CMD_HBIN);
|
||||
SENDCMDW(CC_CMD_VBIN);
|
||||
SENDCMDW(CC_CMD_CAMTEMPER);
|
||||
SENDCMDW(CC_CMD_EXPOSITION);
|
||||
SENDCMDW(CC_CMD_EXPSTATE);
|
||||
}
|
||||
// focuser
|
||||
if(GP->listdevices) SENDMSG(CC_CMD_FOCLIST);
|
||||
if(GP->focdevno > -1) SENDMSG(CC_CMD_FDEVNO "=%d", GP->focdevno);
|
||||
if(GP->info){
|
||||
SENDCMDW(CC_CMD_FGOTO);
|
||||
SENDCMDW(CC_CMD_FMINPOS);
|
||||
SENDCMDW(CC_CMD_FMAXPOS);
|
||||
SENDCMDW(CC_CMD_FTEMP);
|
||||
}
|
||||
if(!isnan(GP->gotopos)){
|
||||
SENDMSGW(CC_CMD_FGOTO, "=%g", GP->gotopos);
|
||||
}
|
||||
// wheel
|
||||
if(GP->listdevices) SENDCMDW(CC_CMD_WLIST);
|
||||
if(GP->whldevno > -1) SENDMSGW(CC_CMD_WDEVNO, "=%d", GP->whldevno);
|
||||
if(GP->info){
|
||||
SENDCMDW(CC_CMD_WPOS);
|
||||
SENDCMDW(CC_CMD_WMAXPOS);
|
||||
SENDCMDW(CC_CMD_WTEMP);
|
||||
}
|
||||
if(GP->setwheel > -1) SENDMSGW(CC_CMD_WPOS, "=%d", GP->setwheel);
|
||||
DBG("nxt");
|
||||
// CCD/CMOS
|
||||
@@ -193,8 +233,6 @@ static void send_headers(int sock){
|
||||
SENDMSGW(CC_CMD_FRAMEFORMAT, "=%d,%d,%d,%d", GP->X0, GP->Y0, GP->X1, GP->Y1);
|
||||
}
|
||||
if(GP->cancelexpose) SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_IDLE);
|
||||
if(GP->listdevices) SENDCMDW(CC_CMD_CAMLIST);
|
||||
if(GP->camdevno > -1) SENDMSGW(CC_CMD_CAMDEVNO, "=%d", GP->camdevno);
|
||||
if(GP->hbin) SENDMSGW(CC_CMD_HBIN, "=%d", GP->hbin);
|
||||
if(GP->vbin) SENDMSGW(CC_CMD_VBIN, "=%d", GP->vbin);
|
||||
if(!isnan(GP->temperature)) SENDMSGW(CC_CMD_CAMTEMPER, "=%g", GP->temperature);
|
||||
@@ -255,9 +293,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,7 +309,10 @@ static int getimage(int askheader){
|
||||
}
|
||||
memcpy(&ima, shmima, sizeof(cc_IMG));
|
||||
}else{ // get image by socket
|
||||
imsock = cc_open_socket(FALSE, GP->imageport, TRUE);
|
||||
if(imsock < 0){
|
||||
DBG("Open socket @ %s", GP->imageport);
|
||||
imsock = cc_open_socket(FALSE, GP->imageport, TRUE);
|
||||
}
|
||||
if(imsock < 0) ERRX("getimage(): can't open image transport socket");
|
||||
// get image size
|
||||
if(!readNbytes(imsock, sizeof(cc_IMG), (uint8_t*)&ima)){
|
||||
@@ -277,6 +320,10 @@ static int getimage(int askheader){
|
||||
goto eofg;
|
||||
}
|
||||
}
|
||||
if(ima.MAGICK != CC_SHM_MAGIC){
|
||||
WARNX("Wrong image: bad magick");
|
||||
goto eofg;
|
||||
}
|
||||
if(ima.bytelen < 1){
|
||||
WARNX("Wrong image size");
|
||||
goto eofg;
|
||||
@@ -292,11 +339,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;
|
||||
@@ -336,12 +384,31 @@ static int getimage(int askheader){
|
||||
}else ima.headerstrings = 0;
|
||||
}else WARNX("Still got old image");
|
||||
eofg:
|
||||
if(imsock != -1) close(imsock);
|
||||
if(shmlocked) unlock_shm(shmima);
|
||||
if(imsock != -1) close(imsock); // reopen in next time in case of error
|
||||
if(shmlocked) cc_unlock_shm();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// get number of current image; return number or -1 if got error/timeout
|
||||
static int curImNo(int sock){
|
||||
if(shmima){
|
||||
if(!cc_lock_shm(FALSE)) return -1;
|
||||
int CurNo = shmima->imnumber;
|
||||
cc_unlock_shm();
|
||||
return CurNo;
|
||||
}
|
||||
// no shared memory: try to get number over TCP
|
||||
SENDCMDW(CC_CMD_IMNUMBER);
|
||||
return current_image_number;
|
||||
}
|
||||
|
||||
void client(int sock){
|
||||
if(sock < 0) ERRX("Can't run without command socket");
|
||||
if(!GP->forceimsock && !shmima){ // init shm buffer if user don't ask to force workign through image socket
|
||||
shmima = cc_getshm(GP->shmkey, 0); // try to init client shm
|
||||
cc_init_sem(FALSE);
|
||||
DBG("Got access to shared memory: %s", shmima ? "OK" : "FAIL");
|
||||
}
|
||||
if(GP->restart){
|
||||
SENDCMDW(CC_CMD_RESTART);
|
||||
return;
|
||||
@@ -349,55 +416,57 @@ 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");
|
||||
}
|
||||
atomic_store(&expstate, CAMERA_CAPTURE); // could be changed earlier
|
||||
DBG("Current state: %d", atomic_load(&expstate));
|
||||
verbose(2, "Wait for exposition end");
|
||||
t0 = sl_dtime();
|
||||
tw = tstart = t0;
|
||||
int lastImNo = curImNo(sock);
|
||||
while(sl_dtime() - t0 < timeout){
|
||||
if(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();
|
||||
int curst = atomic_load(&expstate);
|
||||
if(curst == CAMERA_ERROR){
|
||||
WARNX(_("Can't make exposition"));
|
||||
if(Nremain > 1){
|
||||
verbose(1, "Exposing frame %d...", nframe);
|
||||
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
|
||||
}
|
||||
continue;
|
||||
if(sl_dtime() - tstart < GP->exptime){
|
||||
t0 = sl_dtime(); // refresh timeout until exp not ends
|
||||
continue;
|
||||
}else{
|
||||
SENDCMDW(CC_CMD_EXPSTATE);
|
||||
}
|
||||
int curst = atomic_load(&expstate);
|
||||
DBG("Current state: %d", curst);
|
||||
if(curst == CAMERA_ERROR){
|
||||
WARNX(_("Can't make exposition"));
|
||||
if(Nremain > 1){
|
||||
verbose(1, "Exposing frame %d...", nframe);
|
||||
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
|
||||
tstart = sl_dtime();
|
||||
}
|
||||
//if(expstate != CAMERA_CAPTURE){
|
||||
if(curst == CAMERA_FRAMERDY){
|
||||
atomic_store(&expstate, CAMERA_IDLE);
|
||||
if(Nremain > 1){
|
||||
verbose(1, "Exposing frame %d...", nframe+1);
|
||||
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(curst == CAMERA_FRAMERDY){
|
||||
atomic_store(&expstate, CAMERA_IDLE);
|
||||
int cur = curImNo(sock);
|
||||
DBG("Current state: %d, imno: %d", atomic_load(&expstate), cur);
|
||||
if(Nremain > 1){ // start next capture
|
||||
verbose(1, "Exposing frame %d...", nframe);
|
||||
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
|
||||
tstart = sl_dtime();
|
||||
}
|
||||
int failed = TRUE;
|
||||
if(lastImNo < cur){
|
||||
lastImNo = cur;
|
||||
verbose(2, "Frame ready, try to grab");
|
||||
int failed = TRUE;
|
||||
if(!getimage(TRUE)){
|
||||
WARNX("Can't get next image");
|
||||
}else{
|
||||
@@ -407,31 +476,31 @@ void client(int sock){
|
||||
failed = FALSE;
|
||||
}
|
||||
}
|
||||
if(failed && Nremain == 1){ // last image -> should re-expose
|
||||
verbose(1, "Exposing frame %d...", nframe);
|
||||
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
|
||||
}
|
||||
if(Nremain > 0){
|
||||
if(GP->pause_len > 0){
|
||||
double delta, time1 = sl_dtime() + GP->pause_len;
|
||||
while(1){
|
||||
SENDCMDW(CC_CMD_CAMTEMPER);
|
||||
if((delta = time1 - sl_dtime()) < __FLT_EPSILON__) break;
|
||||
if(delta > 1.) verbose(1, _("%d seconds till pause ends\n"), (int)delta);
|
||||
if(delta > 6.) sleep(5);
|
||||
else if(delta > 1.) sleep((int)delta);
|
||||
else usleep((int)(delta*1e6 + 1));
|
||||
}
|
||||
}else verbose(2, "Got already saved image, wait next");
|
||||
if(failed && Nremain == 1){ // last image -> should re-expose
|
||||
verbose(1, "Exposing frame %d...", nframe);
|
||||
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
|
||||
tstart = sl_dtime();
|
||||
}
|
||||
if(Nremain > 0){
|
||||
if(GP->pause_len > 0){
|
||||
double delta, time1 = sl_dtime() + GP->pause_len;
|
||||
while(1){
|
||||
SENDCMDW(CC_CMD_CAMTEMPER);
|
||||
if((delta = time1 - sl_dtime()) < __FLT_EPSILON__) break;
|
||||
if(delta > 1.) verbose(1, _("%d seconds till pause ends\n"), (int)delta);
|
||||
if(delta > 6.) sleep(5);
|
||||
else if(delta > 1.) sleep((int)delta);
|
||||
else usleep((int)(delta*1e6 + 1));
|
||||
}
|
||||
}else{
|
||||
GP->waitexpend = 0;
|
||||
DBG("All images saved -> exit");
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
DBG("All images saved -> exit");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(GP->waitexpend) WARNX(_("Server timeout"));
|
||||
if(Nremain > 0) WARNX(_("Server timeout"));
|
||||
}
|
||||
|
||||
#ifdef IMAGEVIEW
|
||||
@@ -442,6 +511,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,32 +520,40 @@ static void *grabnext(void _U_ *arg){
|
||||
FNAME();
|
||||
if(controlfd < 0) return NULL;
|
||||
int sock = controlfd;
|
||||
int lastImNo = curImNo(sock);
|
||||
while(1){
|
||||
if(!getWin()) exit(1);
|
||||
TIMESTAMP("End of cycle, start new");
|
||||
atomic_store(&expstate, CAMERA_CAPTURE);
|
||||
DBG("Current state: %d", atomic_load(&expstate));
|
||||
TIMEINIT();
|
||||
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); // start capture
|
||||
double timeout = GP->exptime + CC_CLIENT_TIMEOUT, t0 = sl_dtime();
|
||||
useconds_t sleept = 500000; // 0.5s
|
||||
if(GP->exptime < 0.5){
|
||||
sleept = (useconds_t)(GP->exptime * 500000.);
|
||||
if(sleept < 1000) sleept = 1000;
|
||||
sleept = (useconds_t)(GP->exptime * 250000.); // a quater of exposition time
|
||||
if(sleept < CC_IMWAIT_SLEEP) sleept = CC_IMWAIT_SLEEP;
|
||||
}
|
||||
// double exptime = GP->exptime;
|
||||
TIMESTAMP("Wait for exposition ends (%g s)", timeout);
|
||||
TIMESTAMP("Wait for exposition ends (%g s), sleep for %dus", timeout, sleept);
|
||||
int curst = CAMERA_CAPTURE;
|
||||
while(sl_dtime() - t0 < timeout){
|
||||
DBG("start sleep for %dus", sleept);
|
||||
usleep(sleept);
|
||||
// getans(sock, NULL);
|
||||
//TIMESTAMP("EXPSTATE ===> %d", expstate);
|
||||
if(atomic_load(&expstate) != CAMERA_CAPTURE) break;
|
||||
if(sl_dtime() - t0 < GP->exptime + 0.5) sleept = 1000;
|
||||
SENDCMDW(CC_CMD_EXPSTATE);
|
||||
curst = atomic_load(&expstate);
|
||||
if(curst != CAMERA_CAPTURE) break;
|
||||
if(sl_dtime() - t0 > GP->exptime && sleept != CC_IMWAIT_SLEEP){
|
||||
DBG("Set sleeping time to %dus", sleept);
|
||||
sleept = CC_IMWAIT_SLEEP;
|
||||
}
|
||||
}
|
||||
if(sl_dtime() - t0 >= timeout || atomic_load(&expstate) != CAMERA_FRAMERDY){
|
||||
WARNX("Image wasn't received");
|
||||
int cur = curImNo(sock);
|
||||
if(sl_dtime() - t0 >= timeout || curst != CAMERA_FRAMERDY || cur <= lastImNo){
|
||||
WARNX("Image wasn't received, state: %d, waiting: %g, lastNo: %d, curNo: %d (timeout: %g)", curst, sl_dtime() - t0, lastImNo, cur, timeout);
|
||||
continue;
|
||||
}
|
||||
TIMESTAMP("Frame ready");
|
||||
lastImNo = cur;
|
||||
TIMESTAMP("Frame ready (%d from server's start)", cur);
|
||||
getimage(FALSE);
|
||||
}
|
||||
return NULL;
|
||||
@@ -486,17 +564,26 @@ static void *waitimage(void _U_ *arg){
|
||||
FNAME();
|
||||
if(controlfd < 0) return NULL;
|
||||
int sock = controlfd;
|
||||
int lastImNo = curImNo(sock);
|
||||
double t0 = sl_dtime();
|
||||
while(1){
|
||||
if(!getWin()) exit(1);
|
||||
getans(sock, NULL);
|
||||
if(atomic_load(&expstate) != CAMERA_FRAMERDY){
|
||||
usleep(1000);
|
||||
double tcur = sl_dtime();
|
||||
if(tcur - t0 >= CC_WAIT_TIMEOUT){
|
||||
SENDCMDW(CC_CMD_EXPSTATE); // `ping` server to know if it disconnected
|
||||
t0 = tcur;
|
||||
}
|
||||
int cur = curImNo(sock);
|
||||
if(cur <= lastImNo){
|
||||
usleep(CC_IMWAIT_SLEEP);
|
||||
continue;
|
||||
}
|
||||
TIMESTAMP("End of cycle, start new");
|
||||
lastImNo = cur;
|
||||
TIMESTAMP("End of cycle #%d, start new", cur);
|
||||
TIMEINIT();
|
||||
getimage(FALSE);
|
||||
atomic_store(&expstate, CAMERA_IDLE);
|
||||
DBG("Current state: %d", atomic_load(&expstate));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -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-08 17:06+0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -62,7 +62,8 @@ msgid "rewrite output file if exists"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:59
|
||||
msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)"
|
||||
msgid ""
|
||||
"verbose level (-V - main messages, -VV - secondary messages, -VVV - debug)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:60
|
||||
@@ -117,142 +118,144 @@ msgstr ""
|
||||
msgid "output file name"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:74
|
||||
msgid "wait while exposition ends"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:76
|
||||
#: cmdlnopts.c:75
|
||||
msgid "N flushes before exposing (default: 1)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:77
|
||||
#: cmdlnopts.c:76
|
||||
msgid "horizontal binning to N pixels"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:78
|
||||
#: cmdlnopts.c:77
|
||||
msgid "vertical binning to N pixels"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:79
|
||||
#: cmdlnopts.c:78
|
||||
msgid "make series of N frames"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:80
|
||||
#: cmdlnopts.c:79
|
||||
msgid "make pause for N seconds between expositions"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:81
|
||||
#: cmdlnopts.c:80
|
||||
msgid "set exposure time to given value (seconds!)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:82
|
||||
#: cmdlnopts.c:81
|
||||
msgid "cancel current exposition"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:83
|
||||
#: cmdlnopts.c:82
|
||||
msgid ""
|
||||
"absolute (not divided by binning!) frame X0 coordinate (-1 - all with "
|
||||
"overscan)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:84
|
||||
#: cmdlnopts.c:83
|
||||
msgid "absolute frame Y0 coordinate (-1 - all with overscan)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:85
|
||||
#: cmdlnopts.c:84
|
||||
msgid "absolute frame X1 coordinate (-1 - all with overscan)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:86
|
||||
#: cmdlnopts.c:85
|
||||
msgid "absolute frame Y1 coordinate (-1 - all with overscan)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:88
|
||||
#: cmdlnopts.c:87
|
||||
msgid "open shutter"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:89
|
||||
#: cmdlnopts.c:88
|
||||
msgid "close shutter"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:90
|
||||
#: cmdlnopts.c:89
|
||||
msgid "run exposition on LOW @ pin5 I/O port"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:91
|
||||
#: cmdlnopts.c:90
|
||||
msgid "run exposition on HIGH @ pin5 I/O port"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:92
|
||||
#: cmdlnopts.c:91
|
||||
msgid "get value of I/O port pins"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:93
|
||||
#: cmdlnopts.c:92
|
||||
msgid "move stepper motor asynchronous"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:95
|
||||
#: cmdlnopts.c:94
|
||||
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:96
|
||||
#: cmdlnopts.c:95
|
||||
msgid ""
|
||||
"configure I/O port pins to given value (decimal number, pin1 is LSB, 1 == "
|
||||
"output, 0 == input)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:98
|
||||
#: cmdlnopts.c:97
|
||||
msgid "move focuser to absolute position, mm"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:99
|
||||
#: cmdlnopts.c:98
|
||||
msgid "move focuser to relative position, mm (only for standalone)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:101
|
||||
#: cmdlnopts.c:100
|
||||
msgid "set wheel position"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:103
|
||||
#: cmdlnopts.c:102
|
||||
msgid "CMOS gain level"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:104
|
||||
#: cmdlnopts.c:103
|
||||
msgid "CMOS brightness level"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:106
|
||||
#: cmdlnopts.c:105
|
||||
msgid "logging file name (if run as server)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:107
|
||||
#: cmdlnopts.c:106
|
||||
msgid "UNIX socket name (command socket)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:108
|
||||
#: cmdlnopts.c:107
|
||||
msgid "local INET command socket port"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:109
|
||||
#: cmdlnopts.c:108
|
||||
msgid "INET image socket port"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:110
|
||||
#: cmdlnopts.c:109
|
||||
msgid "run as client"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:111
|
||||
#: cmdlnopts.c:110
|
||||
msgid "passive viewer (only get last images)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:112
|
||||
#: cmdlnopts.c:111
|
||||
msgid "restart image server"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:113
|
||||
#: cmdlnopts.c:112
|
||||
msgid "network answer timeout (default: 0.1s)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:113
|
||||
msgid ""
|
||||
"get base information about connected hardware (also increasing text messages "
|
||||
"level to 2)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:115
|
||||
msgid "shared memory (with image data) key (default: 7777777)"
|
||||
msgstr ""
|
||||
@@ -491,12 +494,12 @@ msgstr ""
|
||||
msgid "Can't set brightness to %g"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:690 server.c:332
|
||||
#: ccdfunc.c:690 server.c:330
|
||||
#, c-format
|
||||
msgid "Can't set binning %dx%d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:702 server.c:333
|
||||
#: ccdfunc.c:702 server.c:331
|
||||
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:194 server.c:195
|
||||
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:200 server.c:201
|
||||
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:218 server.c:219
|
||||
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:491
|
||||
#, 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:247
|
||||
msgid "No camera device"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:385
|
||||
#: client.c:449
|
||||
msgid "Can't make exposition"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:434
|
||||
#: client.c:503
|
||||
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-08 16:46+0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -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:491
|
||||
#, 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:218 server.c:219
|
||||
#, 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:194 server.c:195
|
||||
#, 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:449
|
||||
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:330
|
||||
#, 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:331
|
||||
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:200 server.c:201
|
||||
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:247
|
||||
msgid "No camera device"
|
||||
msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ"
|
||||
|
||||
@@ -338,7 +338,7 @@ msgstr "
|
||||
msgid "Readout mode: %s"
|
||||
msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s"
|
||||
|
||||
#: client.c:434
|
||||
#: client.c:503
|
||||
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);
|
||||
|
||||
343
server.c
343
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,32 +58,36 @@ typedef struct{
|
||||
|
||||
// cat | awk '{print "{ " $3 ", \"\" }," }' | sort
|
||||
strpair allcommands[] = {
|
||||
{ CC_CMD_8BIT, "run in 8 bit mode instead of 16 bit" },
|
||||
{ CC_CMD_AUTHOR, "FITS 'AUTHOR' field" },
|
||||
{ CC_CMD_BRIGHTNESS, "camera brightness" },
|
||||
{ CC_CMD_CAMDEVNO, "camera device number" },
|
||||
{ CC_CMD_CAMFLAGS, "get camflags (bits: 0-start capture, 1-cancel, 2-restart server"},
|
||||
{ CC_CMD_CAMLIST, "list all connected cameras" },
|
||||
{ CC_CMD_CAMFANSPD, "fan speed of camera" },
|
||||
{ CC_CMD_CONFIO, "camera IO configuration" },
|
||||
{ CC_CMD_DARK, "don't open shutter @ exposure" },
|
||||
{ CC_CMD_EXPSTATE, "get exposition state (0: cancel, 1: capturing, 2: frame ready, 3: error) "
|
||||
"or set (0: cancel, 1: start exp)\n also get camflags (bits: 0-start capture, 1-cancel, 2-restart server" },
|
||||
"or set (0: cancel, 1: start exp)\n" },
|
||||
{ CC_CMD_EXPOSITION, "exposition time" },
|
||||
{ CC_CMD_FASTSPD, "fast readout speed" },
|
||||
{ CC_CMD_FDEVNO, "focuser device number" },
|
||||
{ CC_CMD_FOCLIST, "list all connected focusers" },
|
||||
{ CC_CMD_FMAXPOS, "get maximal focuser position"},
|
||||
{ CC_CMD_FMINPOS, "get minimal focuser position"},
|
||||
{ CC_CMD_FGOTO, "focuser position" },
|
||||
{ CC_CMD_FTEMP, "get focuser body temperature"},
|
||||
{ CC_CMD_FRAMEFORMAT, "camera frame format (X0,Y0,X1,Y1)" },
|
||||
{ CC_CMD_GAIN, "camera gain" },
|
||||
{ CC_CMD_GETHEADERS, "get last file FITS headers" },
|
||||
{ CC_CMD_HBIN, "horizontal binning" },
|
||||
{ CC_CMD_HELP, "show this help" },
|
||||
{ CC_CMD_IMHEIGHT, "last image height" },
|
||||
{ CC_CMD_IMNUMBER, "grabbed image number from server start"},
|
||||
{ CC_CMD_IMWIDTH, "last image width" },
|
||||
{ CC_CMD_INFO, "connected devices state" },
|
||||
{ CC_CMD_INFTY, "an infinity loop taking images until there's connected clients" },
|
||||
{ CC_CMD_INSTRUMENT, "FITS 'INSTRUME' field" },
|
||||
{ CC_CMD_IO, "get/set camera IO" },
|
||||
{ CC_CMD_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 +103,9 @@ strpair allcommands[] = {
|
||||
{ CC_CMD_VBIN, "vertical binning" },
|
||||
{ CC_CMD_WDEVNO, "wheel device number" },
|
||||
{ CC_CMD_WLIST, "list all connected wheels" },
|
||||
{ CC_CMD_WMAXPOS, "get maximap wheel position"},
|
||||
{ CC_CMD_WPOS, "wheel position" },
|
||||
{ CC_CMD_WTEMP, "get wheel body temperature"},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -107,6 +117,7 @@ static int lock(){
|
||||
//DBG("\n\nAlready locked");
|
||||
return FALSE;
|
||||
}
|
||||
//DBG("LOCK()");
|
||||
return TRUE;
|
||||
}
|
||||
static void unlock(){
|
||||
@@ -114,43 +125,22 @@ static void unlock(){
|
||||
LOGERR("Can't unlock socket mutex");
|
||||
ERR("Can't unlock socket mutex");
|
||||
}
|
||||
//DBG("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(){
|
||||
@@ -158,23 +148,24 @@ static void fixima(){
|
||||
if(!camera) return;
|
||||
double t0 = sl_dtime();
|
||||
int locked = FALSE;
|
||||
TIMESTAMP("Lock socket");
|
||||
// lock socket operations
|
||||
while(!(locked = lock()) && sl_dtime() - t0 < 0.5);
|
||||
if(!locked) while(!lock()) unlock(); // force unlocking if can't do this gracefully
|
||||
while(!(locked = lock()) && sl_dtime() - t0 < 0.5) usleep(1000);
|
||||
if(!locked){
|
||||
DBG("Still locked from outside -> unlock/lock");
|
||||
while(!lock()) unlock(); // force unlocking if can't do this gracefully
|
||||
}else DBG("LOCK takes %gs", sl_dtime()-t0);
|
||||
int raw_width = curformat.w / GP->hbin, raw_height = curformat.h / GP->vbin;
|
||||
TIMESTAMP("Check SHM image");
|
||||
// allocate memory for largest possible image
|
||||
if(!ima){
|
||||
ima = cc_getshm(GP->shmkey, camera->array.h * camera->array.w * 2);
|
||||
// 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);
|
||||
TIMESTAMP("Lock SHM image");
|
||||
cc_lock_shm(TRUE);
|
||||
shmkey = GP->shmkey;
|
||||
//if(raw_width == ima->w && raw_height == ima->h) return; // all OK
|
||||
DBG("curformat: %dx%d", curformat.w, curformat.h);
|
||||
@@ -187,8 +178,9 @@ static void fixima(){
|
||||
DBG("GP->_8bit=%d", GP->_8bit);
|
||||
ima->bytelen = raw_height * raw_width * cc_getNbytes(ima);
|
||||
DBG("new image: %dx%d", raw_width, raw_height);
|
||||
unlock_shm(ima);
|
||||
cc_unlock_shm();
|
||||
unlock();
|
||||
TIMESTAMP("All OK");
|
||||
}
|
||||
|
||||
// functions for processCAM finite state machine
|
||||
@@ -228,18 +220,20 @@ 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;
|
||||
return;
|
||||
}else{
|
||||
TIMESTAMP("Fill FITS header");
|
||||
ima->gotstat = 0; // fresh image without statistics - recalculate when save
|
||||
ima->timestamp = sl_dtime(); // set timestamp
|
||||
fillFITSheader(ima);
|
||||
++ima->imnumber; // increment counter
|
||||
}
|
||||
unlock_shm(ima);
|
||||
cc_unlock_shm();
|
||||
TIMESTAMP("Captured and unlocked");
|
||||
}
|
||||
camstate = CAMERA_FRAMERDY;
|
||||
}
|
||||
@@ -253,12 +247,21 @@ static void* processCAM(_U_ void *d){
|
||||
ERRX(_("No camera device"));
|
||||
}
|
||||
double logt = 0;
|
||||
while(1){
|
||||
#ifdef EBUG
|
||||
double T = sl_dtime();
|
||||
#endif
|
||||
while(isrunning){
|
||||
if(camflags & FLAG_RESTARTSERVER){
|
||||
LOGERR("User asks to restart");
|
||||
signals(1);
|
||||
}
|
||||
usleep(100);
|
||||
#ifdef EBUG
|
||||
if(sl_dtime() - T > 5.){
|
||||
T = sl_dtime();
|
||||
printf("\t\t\tprocessCAM(), 5 seconds\n");
|
||||
}
|
||||
#endif
|
||||
usleep(1000);
|
||||
if(tremain < 0.5 && tremain > 0.) usleep(tremain*1e6);
|
||||
if(lock()){
|
||||
// log
|
||||
@@ -285,22 +288,17 @@ static void* processCAM(_U_ void *d){
|
||||
unlock();
|
||||
continue;
|
||||
}
|
||||
unlock();
|
||||
cc_camera_state curstate = camstate;
|
||||
switch(curstate){
|
||||
case CAMERA_IDLE:
|
||||
cameraidlestate();
|
||||
break;
|
||||
case CAMERA_CAPTURE:
|
||||
cameracapturestate();
|
||||
break;
|
||||
case CAMERA_FRAMERDY:
|
||||
// do nothing: when `server` got this state it sends "expstate=2" to all clients and changes state to IDLE
|
||||
break;
|
||||
case CAMERA_ERROR:
|
||||
// do nothing: when `server` got this state it sends "expstate=3" to all clients and changes state to IDLE
|
||||
default:
|
||||
cameraidlestate();
|
||||
break;
|
||||
}
|
||||
unlock();
|
||||
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@@ -372,9 +370,7 @@ static cc_hresult restarthandler(_U_ int fd, _U_ const char *key, _U_ const char
|
||||
static cc_hresult imsizehandler(int fd, const char *key, _U_ const char *val){
|
||||
char buf[64];
|
||||
if(!ima) return CC_RESULT_FAIL;
|
||||
// send image width/height in pixels
|
||||
if(0 == strcmp(key, CC_CMD_IMHEIGHT)) snprintf(buf, 63, CC_CMD_IMHEIGHT "=%d", ima->h);
|
||||
else snprintf(buf, 63, CC_CMD_IMWIDTH "=%d", ima->w);
|
||||
snprintf(buf, 63, "%s=%d", key, (0 == strcmp(key, CC_CMD_IMHEIGHT)) ? ima->h : ima->w);
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
return CC_RESULT_SILENCE;
|
||||
}
|
||||
@@ -497,19 +493,21 @@ static cc_hresult camfanhandler(int fd, _U_ const char *key, _U_ const char *val
|
||||
}
|
||||
const char *shutterstr[] = {"open", "close", "expose @high", "expose @low"};
|
||||
static cc_hresult shutterhandler(_U_ int fd, _U_ const char *key, const char *val){
|
||||
char buf[64];
|
||||
if(!camera->shuttercmd) return CC_RESULT_FAIL;
|
||||
if(val){
|
||||
int x = atoi(val);
|
||||
if(x < 0 || x >= SHUTTER_AMOUNT) return CC_RESULT_BADVAL;
|
||||
int r = camera->shuttercmd((cc_shutter_op)x);
|
||||
if(r){
|
||||
LOGMSG("Shutter command '%s'", shutterstr[x]);
|
||||
}else{
|
||||
LOGWARN("Can't run shutter command '%s'", shutterstr[x]);
|
||||
return CC_RESULT_FAIL;
|
||||
}
|
||||
if(!val) return CC_RESULT_BADVAL;
|
||||
int x = atoi(val);
|
||||
if(x < 0 || x >= SHUTTER_AMOUNT) return CC_RESULT_BADVAL;
|
||||
int r = camera->shuttercmd((cc_shutter_op)x);
|
||||
if(r){
|
||||
LOGMSG("Shutter command '%s'", shutterstr[x]);
|
||||
}else{
|
||||
LOGWARN("Can't run shutter command '%s'", shutterstr[x]);
|
||||
return CC_RESULT_FAIL;
|
||||
}
|
||||
return CC_RESULT_OK;
|
||||
snprintf(buf, 63, "%s=%d", key, x);
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
return CC_RESULT_SILENCE;
|
||||
}
|
||||
static cc_hresult confiohandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||
char buf[64];
|
||||
@@ -616,29 +614,33 @@ static cc_hresult nflusheshandler(_U_ int fd, _U_ const char *key, _U_ const cha
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
return CC_RESULT_SILENCE;
|
||||
}
|
||||
static cc_hresult expstatehandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||
static cc_hresult expstatehandler(int fd, _U_ const char *key, const char *val){
|
||||
char buf[64];
|
||||
if(val){
|
||||
int n = atoi(val);
|
||||
if(n == CAMERA_IDLE){ // cancel expositions
|
||||
camflags |= FLAG_CANCEL;
|
||||
return CC_RESULT_OK;
|
||||
}
|
||||
else if(n == CAMERA_CAPTURE){ // start exposition
|
||||
if(GP->exptime < 1e-9){
|
||||
snprintf(buf, 63, CC_CMD_EXPOSITION "=%g", GP->exptime);
|
||||
cc_sendstrmessage(fd, buf);
|
||||
if(GP->exptime < 1e-9){ // need exposition time to be set
|
||||
return CC_RESULT_FAIL;
|
||||
}
|
||||
if(camstate == CAMERA_CAPTURE){
|
||||
DBG("Capture in process when user ask '%s=%s'", key, val);
|
||||
return CC_RESULT_BUSY; // in progress
|
||||
}
|
||||
TIMESTAMP("Get FLAG_STARTCAPTURE");
|
||||
TIMEINIT();
|
||||
camflags |= FLAG_STARTCAPTURE;
|
||||
return CC_RESULT_OK;
|
||||
}
|
||||
else return CC_RESULT_BADVAL;
|
||||
}
|
||||
snprintf(buf, 63, CC_CMD_EXPSTATE "=%d", camstate);
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
return CC_RESULT_SILENCE;
|
||||
}
|
||||
static cc_hresult camflagshandler(int fd, _U_ const char *key, _U_ const char *val){
|
||||
char buf[64];
|
||||
snprintf(buf, 63, "camflags=%d", camflags);
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
return CC_RESULT_SILENCE;
|
||||
@@ -663,6 +665,16 @@ static cc_hresult _8bithandler(int fd, _U_ const char *key, const char *val){
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
return CC_RESULT_SILENCE;
|
||||
}
|
||||
static cc_hresult imnohandler(int fd, const char *key, const char _U_ *val){
|
||||
if(!ima) return CC_RESULT_FAIL;
|
||||
char buf[64];
|
||||
cc_lock_shm(TRUE);
|
||||
int No = ima->imnumber;
|
||||
cc_unlock_shm();
|
||||
snprintf(buf, 63, "%s=%d", key, No);
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
return CC_RESULT_SILENCE;
|
||||
}
|
||||
static cc_hresult fastspdhandler(int fd, _U_ const char *key, const char *val){
|
||||
char buf[64];
|
||||
if(!camera->setfastspeed) return CC_RESULT_FAIL;
|
||||
@@ -722,6 +734,22 @@ static cc_hresult handler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||
/*******************************************************************************
|
||||
***************************** cc_Wheel handlers **********************************
|
||||
******************************************************************************/
|
||||
static cc_hresult wmaxposhandler(int fd, const char *key, _U_ const char *val){
|
||||
if(wheel->Ndevices < 1) return CC_RESULT_FAIL;
|
||||
char buf[64];
|
||||
snprintf(buf, 63, "%s=%d", key, wmaxpos);
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
return CC_RESULT_SILENCE;
|
||||
}
|
||||
static cc_hresult wtemphandler(int fd, const char *key, _U_ const char *val){
|
||||
if(wheel->Ndevices < 1 || !wheel->getTbody) return CC_RESULT_FAIL;
|
||||
char buf[64];
|
||||
float t;
|
||||
if(!wheel->getTbody(&t)) return CC_RESULT_FAIL;
|
||||
snprintf(buf, 63, "%s=%.1f", key, t);
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
return CC_RESULT_SILENCE;
|
||||
}
|
||||
static cc_hresult wlisthandler(int fd, _U_ const char *key, _U_ const char *val){
|
||||
if(wheel->Ndevices < 1) return CC_RESULT_FAIL;
|
||||
for(int i = 0; i < wheel->Ndevices; ++i){
|
||||
@@ -769,18 +797,42 @@ static cc_hresult wgotohandler(_U_ int fd, _U_ const char *key, _U_ const char *
|
||||
/*******************************************************************************
|
||||
**************************** Focuser handlers *********************************
|
||||
******************************************************************************/
|
||||
|
||||
static cc_hresult fminposhandler(int fd, const char *key, _U_ const char *val){
|
||||
if(focuser->Ndevices < 1) return CC_RESULT_FAIL;
|
||||
char buf[64];
|
||||
snprintf(buf, 63, "%s=%g", key, focminpos);
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
return CC_RESULT_SILENCE;
|
||||
}
|
||||
static cc_hresult fmaxposhandler(int fd, const char *key, _U_ const char *val){
|
||||
if(focuser->Ndevices < 1) return CC_RESULT_FAIL;
|
||||
char buf[64];
|
||||
snprintf(buf, 63, "%s=%g", key, focmaxpos);
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
return CC_RESULT_SILENCE;
|
||||
}
|
||||
static cc_hresult ftemphandler(int fd, const char *key, _U_ const char *val){
|
||||
if(focuser->Ndevices < 1 || !focuser->getTbody) return CC_RESULT_FAIL;
|
||||
char buf[64];
|
||||
float t;
|
||||
if(!focuser->getTbody(&t)) return CC_RESULT_FAIL;
|
||||
snprintf(buf, 63, "%s=%.1f", key, t);
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
return CC_RESULT_SILENCE;
|
||||
}
|
||||
static cc_hresult foclisthandler(int fd, _U_ const char *key, _U_ const char *val){
|
||||
if(focuser->Ndevices < 1) return CC_RESULT_FAIL;
|
||||
for(int i = 0; i < focuser->Ndevices; ++i){
|
||||
char modname[256], buf[BUFSIZ];
|
||||
if(!focuser->setDevNo(i)) continue;
|
||||
if(focuser->setDevNo){
|
||||
if(!focuser->setDevNo(i)) continue;
|
||||
}
|
||||
focuser->getModelName(modname, 255);
|
||||
snprintf(buf, BUFSIZ-1, CC_CMD_FOCLIST "='%s'", modname);
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
}
|
||||
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 +873,6 @@ static cc_hresult fgotohandler(int fd, _U_ const char *key, const char *val){
|
||||
**************************** Common handlers **********************************
|
||||
******************************************************************************/
|
||||
|
||||
// information about everything
|
||||
static cc_hresult infohandler(int fd, _U_ const char *key, _U_ const char *val){
|
||||
char buf[BUFSIZ], buf1[256];
|
||||
float f;
|
||||
int i;
|
||||
if(camera){
|
||||
if(camera->getModelName && camera->getModelName(buf1, 255)){
|
||||
snprintf(buf, BUFSIZ-1, CC_CMD_CAMLIST "='%s'", buf1);
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
}
|
||||
#define RUN(f, arg) do{if(CC_RESULT_DISCONNECTED == f(fd, arg, NULL)) return CC_RESULT_DISCONNECTED;}while(0)
|
||||
RUN(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,13 +966,14 @@ static cc_hresult chkfoc(char *val){
|
||||
return CC_RESULT_FAIL;
|
||||
}
|
||||
static cc_handleritem items[] = {
|
||||
{chktrue,infohandler, CC_CMD_INFO},
|
||||
{NULL, helphandler, CC_CMD_HELP},
|
||||
{NULL, restarthandler, CC_CMD_RESTART},
|
||||
{chkcc, camlisthandler, CC_CMD_CAMLIST},
|
||||
{chkcc, camflagshandler, CC_CMD_CAMFLAGS},
|
||||
{chkcc, camsetNhandler, CC_CMD_CAMDEVNO},
|
||||
{chkcc, camfanhandler, CC_CMD_CAMFANSPD},
|
||||
{chkcc, exphandler, CC_CMD_EXPOSITION},
|
||||
{chkcc, imnohandler, CC_CMD_IMNUMBER},
|
||||
{chkcc, binhandler, CC_CMD_HBIN},
|
||||
{chkcc, binhandler, CC_CMD_VBIN},
|
||||
{chkcc, temphandler, CC_CMD_CAMTEMPER},
|
||||
@@ -1009,9 +1005,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 +1047,12 @@ void server(int sock, int imsock){
|
||||
if(imsock < 0) WARNX("Server run without image transport socket");
|
||||
else if(listen(imsock, CC_MAXCLIENTS) == -1){
|
||||
WARN("listen()");
|
||||
LOGWARN("listen()");
|
||||
LOGERR("server(): error in listen() for image socket");
|
||||
return;
|
||||
}
|
||||
if(listen(sock, CC_MAXCLIENTS) == -1){
|
||||
WARN("listen()");
|
||||
LOGWARN("listen()");
|
||||
LOGERR("server(): error in listen() for command socket");
|
||||
return;
|
||||
}
|
||||
// init everything
|
||||
@@ -1062,11 +1063,17 @@ void server(int sock, int imsock){
|
||||
wheeldevini(0);
|
||||
if(startCCD()) --ctr;
|
||||
camdevini(0);
|
||||
if(ctr == 3) ERRX("No devices found");
|
||||
if(ctr == 3){
|
||||
LOGERR("server(): no devices found");
|
||||
WARNX("No devices found");
|
||||
}
|
||||
// start camera thread
|
||||
pthread_t camthread;
|
||||
if(camera){
|
||||
if(pthread_create(&camthread, NULL, processCAM, NULL)) ERR("pthread_create()");
|
||||
if(pthread_create(&camthread, NULL, processCAM, NULL)){
|
||||
WARN("pthread_create()");
|
||||
LOGERR("server(): pthread_create()");
|
||||
}
|
||||
}
|
||||
int nfd = 2; // only two listening sockets @start: command and image
|
||||
struct pollfd poll_set[CC_MAXCLIENTS+2];
|
||||
@@ -1080,7 +1087,16 @@ void server(int sock, int imsock){
|
||||
poll_set[0].events = POLLIN;
|
||||
poll_set[1].fd = imsock;
|
||||
poll_set[1].events = POLLIN;
|
||||
while(1){
|
||||
#ifdef EBUG
|
||||
double T = sl_dtime();
|
||||
#endif
|
||||
while(isrunning == 1){
|
||||
#ifdef EBUG
|
||||
if(sl_dtime() - T > 5.){
|
||||
T = sl_dtime();
|
||||
printf("\t\t\tserver(), 5 seconds\n");
|
||||
}
|
||||
#endif
|
||||
poll(poll_set, nfd, 1); // max timeout - 1ms
|
||||
//if(imsock > -1 && sl_canread(imsock) > 0){
|
||||
if(imsock > -1 && (poll_set[1].revents & POLLIN)){
|
||||
@@ -1093,19 +1109,24 @@ 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){
|
||||
pthread_t sendthread;
|
||||
if(pthread_create(&sendthread, NULL, sendimage, (void*)&client)){
|
||||
WARN("pthread_create()");
|
||||
LOGWARN("pthread_create() error");
|
||||
if(ima->imnumber == 0){
|
||||
WARNX("Client wants an image, but there's no data");
|
||||
close(client);
|
||||
}else{
|
||||
DBG("Thread created -> detach");
|
||||
if(pthread_detach(sendthread)){
|
||||
WARN("pthread_detach()");
|
||||
LOGWARN("pthread_detach() error");
|
||||
pthread_cancel(sendthread);
|
||||
pthread_t sendthread;
|
||||
if(pthread_create(&sendthread, NULL, sendimage, (void*)&client)){
|
||||
WARN("pthread_create()");
|
||||
LOGWARN("pthread_create() error");
|
||||
close(client);
|
||||
}else DBG("Thread detached");
|
||||
}else{
|
||||
DBG("Thread created -> detach");
|
||||
if(pthread_detach(sendthread)){
|
||||
WARN("pthread_detach()");
|
||||
LOGWARN("pthread_detach() error");
|
||||
pthread_cancel(sendthread);
|
||||
close(client);
|
||||
}else DBG("Thread detached");
|
||||
}
|
||||
}
|
||||
}else{WARN("accept()"); DBG("disconnected");}
|
||||
}
|
||||
@@ -1128,6 +1149,7 @@ void server(int sock, int imsock){
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
// process some data & send messages to ALL
|
||||
if(camstate == CAMERA_FRAMERDY || camstate == CAMERA_ERROR){
|
||||
DBG("new image: timestamp=%.1f, num=%zd", ima->timestamp, ima->imnumber);
|
||||
@@ -1140,10 +1162,12 @@ void server(int sock, int imsock){
|
||||
}
|
||||
camstate = CAMERA_IDLE;
|
||||
}
|
||||
#endif
|
||||
// scan connections
|
||||
for(int fdidx = 2; fdidx < nfd; ++fdidx){
|
||||
if((poll_set[fdidx].revents & POLLIN) == 0) continue;
|
||||
int fd = poll_set[fdidx].fd;
|
||||
DBG("Got active fd=%d", fd);
|
||||
cc_strbuff *curbuff = buffers[fdidx-1];
|
||||
int disconnected = 0;
|
||||
if(cc_read2buf(fd, curbuff)){
|
||||
@@ -1166,7 +1190,7 @@ void server(int sock, int imsock){
|
||||
}
|
||||
}
|
||||
// check `infty`
|
||||
if(camstate == CAMERA_IDLE && infty){ // start new exposition
|
||||
if(camstate != CAMERA_CAPTURE && infty){ // start new exposition
|
||||
// mark to start new capture in infinity loop when at least one client connected
|
||||
if(nfd > 2){
|
||||
camflags |= FLAG_STARTCAPTURE;
|
||||
@@ -1175,10 +1199,11 @@ void server(int sock, int imsock){
|
||||
}
|
||||
}
|
||||
}
|
||||
// never reached
|
||||
WARNX("SERVER STOPPED!");
|
||||
camstop();
|
||||
focclose();
|
||||
closewheel();
|
||||
closecam();
|
||||
isrunning = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user