fixed bug with SIGPIPE @write, fixed some other big bugs

This commit is contained in:
Edward Emelianov 2022-03-24 17:06:29 +03:00
parent 290934f798
commit 684a0616a4
14 changed files with 296 additions and 276 deletions

View File

@ -107,7 +107,7 @@ set(RU_FILE ${LCPATH}/ru.po)
# exe file # exe file
add_executable(${PROJ} ${SOURCES} ${PO_FILE} ${MO_FILE}) add_executable(${PROJ} ${SOURCES} ${PO_FILE} ${MO_FILE})
target_link_libraries(${PROJ} ${CFITSIO_LIBRARIES} ${X11_LIBRARIES} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${${PROJ}_LIBRARIES} -lm) target_link_libraries(${PROJ} ${CFITSIO_LIBRARIES} ${X11_LIBRARIES} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${${PROJ}_LIBRARIES} -lm ${CMAKE_DL_LIBS})
include_directories(${${PROJ}_INCLUDE_DIRS} .) include_directories(${${PROJ}_INCLUDE_DIRS} .)
link_directories(${${PROJ}_LIBRARY_DIRS} ) link_directories(${${PROJ}_LIBRARY_DIRS} )

View File

@ -9,4 +9,4 @@ include_directories(${${CCDLIB}_INCLUDE_DIRS} ..)
link_directories(${${CCDLIB}_LIBRARY_DIRS}) link_directories(${${CCDLIB}_LIBRARY_DIRS})
add_library(${CCDLIB} SHARED ${SRC}) add_library(${CCDLIB} SHARED ${SRC})
target_link_libraries(${CCDLIB} ${${CCDLIB}_LIBRARIES}) target_link_libraries(${CCDLIB} ${${CCDLIB}_LIBRARIES} -fPIC)

View File

@ -9,4 +9,4 @@ include_directories(${${CCDLIB}_INCLUDE_DIRS} ..)
link_directories(${${CCDLIB}_LIBRARY_DIRS}) link_directories(${${CCDLIB}_LIBRARY_DIRS})
add_library(${CCDLIB} SHARED ${SRC}) add_library(${CCDLIB} SHARED ${SRC})
target_link_libraries(${CCDLIB} ${${CCDLIB}_LIBRARIES}) target_link_libraries(${CCDLIB} ${${CCDLIB}_LIBRARIES} -fPIC)

View File

@ -49,7 +49,7 @@ extern Wheel wheel;
#define FOCSCALE (10000.) #define FOCSCALE (10000.)
#define TRYFUNC(f, ...) \ #define TRYFUNC(f, ...) \
do{ if((fli_err = f(__VA_ARGS__))) \ do{fli_err = 0; if((fli_err = f(__VA_ARGS__))) \
WARNX(#f "() failed"); \ WARNX(#f "() failed"); \
}while(0) }while(0)
@ -62,7 +62,7 @@ typedef struct{
static char camname[BUFSIZ] = {0}, whlname[BUFSIZ], focname[BUFSIZ]; static char camname[BUFSIZ] = {0}, whlname[BUFSIZ], focname[BUFSIZ];
static long fli_err, tmpl; static long fli_err, tmpl;
static cam_t *camz = NULL, *whlz = NULL, *focz = NULL; static cam_t *camz = NULL, *whlz = NULL, *focz = NULL;
static flidev_t camdev, whldev, focdev; static flidev_t camdev = -1, whldev = -1, focdev = -1;
static capture_status capStatus = CAPTURE_NO; static capture_status capStatus = CAPTURE_NO;
static int curhbin = 1, curvbin = 1; static int curhbin = 1, curvbin = 1;
static long filterpos = -1, filtermax = -1; // filter position static long filterpos = -1, filtermax = -1; // filter position
@ -140,15 +140,20 @@ static int fli_findCCD(){
return TRUE; return TRUE;
} }
static int fli_setActiceCam(int n){ static int fli_setActiceCam(int n){
DBG("SET ACTUIVE #%d", n);
if(!camz && !fli_findCCD()) return FALSE; if(!camz && !fli_findCCD()) return FALSE;
if(n >= camera.Ndevices){ if(n >= camera.Ndevices){
return FALSE; return FALSE;
} }
if(camdev > -1){
FLIClose(camdev); FLIClose(camdev);
camdev = -1;
}
TRYFUNC(FLIOpen, &camdev, camz[n].name, camz[n].domain); TRYFUNC(FLIOpen, &camdev, camz[n].name, camz[n].domain);
if(fli_err){ if(fli_err){
return FALSE; return FALSE;
} }
DBG("camera fdno: %ld", camdev);
TRYFUNC(FLIGetModel, camdev, camname, BUFSIZ); TRYFUNC(FLIGetModel, camdev, camname, BUFSIZ);
#ifdef EBUG #ifdef EBUG
if(!fli_err) DBG("Model: %s", camname); if(!fli_err) DBG("Model: %s", camname);
@ -205,12 +210,16 @@ static int fli_findFocuser(){
static int fli_setActiceFocuser(int n){ static int fli_setActiceFocuser(int n){
if(!focz && !fli_findFocuser()) return FALSE; if(!focz && !fli_findFocuser()) return FALSE;
if(n >= focuser.Ndevices) return FALSE; if(n >= focuser.Ndevices) return FALSE;
if(focdev > -1){
FLIClose(focdev); FLIClose(focdev);
focdev = -1;
}
int OK = FALSE; int OK = FALSE;
for(int i = 0; i < focuser.Ndevices; ++i){ for(int i = 0; i < focuser.Ndevices; ++i){
DBG("Try %s", focz[i].name); DBG("Try %s", focz[i].name);
TRYFUNC(FLIOpen, &focdev, focz[i].name, focz[i].domain); TRYFUNC(FLIOpen, &focdev, focz[i].name, focz[i].domain);
if(fli_err) continue; if(fli_err) continue;
DBG("focuser fdno: %ld", focdev);
TRYFUNC(FLIGetModel, focdev, focname, BUFSIZ); TRYFUNC(FLIGetModel, focdev, focname, BUFSIZ);
DBG("MODEL '%s'", focname); DBG("MODEL '%s'", focname);
if(fli_err) continue; if(fli_err) continue;
@ -315,12 +324,16 @@ static int fli_wgetpos(int *p);
static int fli_setActiceWheel(int n){ static int fli_setActiceWheel(int n){
if(!whlz && !fli_findWheel()) return FALSE; if(!whlz && !fli_findWheel()) return FALSE;
if(n >= wheel.Ndevices) return FALSE; if(n >= wheel.Ndevices) return FALSE;
if(whldev > -1){
FLIClose(whldev); FLIClose(whldev);
whldev = -1;
}
int OK = FALSE; int OK = FALSE;
for(int i = 0; i < focuser.Ndevices; ++i){ for(int i = 0; i < wheel.Ndevices; ++i){
DBG("Try %s", whlz[i].name); DBG("Try %s", whlz[i].name);
TRYFUNC(FLIOpen, &whldev, whlz[i].name, whlz[i].domain); TRYFUNC(FLIOpen, &whldev, whlz[i].name, whlz[i].domain);
if(fli_err) continue; if(fli_err) continue;
DBG("wheel fdno: %ld", whldev);
TRYFUNC(FLIGetFilterCount, whldev, &filtermax); TRYFUNC(FLIGetFilterCount, whldev, &filtermax);
if(fli_err || filtermax < 2){ // not a wheel if(fli_err || filtermax < 2){ // not a wheel
DBG("Not a wheel"); DBG("Not a wheel");
@ -351,6 +364,7 @@ static int fli_setActiceWheel(int n){
} }
static int fli_wgetname(char *x, int n){ static int fli_wgetname(char *x, int n){
if(!x) return FALSE;
strncpy(x, whlname, n); strncpy(x, whlname, n);
return TRUE; return TRUE;
} }
@ -381,7 +395,9 @@ static int fli_wgetpos(int *p){
static int fli_wsetpos(int p){ static int fli_wsetpos(int p){
if(p == filterpos) return TRUE; if(p == filterpos) return TRUE;
if(p > filtermax || p < 0) return FALSE; if(p > filtermax || p < 0) return FALSE;
DBG("RUN FLISetFilterPos");
TRYFUNC(FLISetFilterPos, whldev, (long)p); TRYFUNC(FLISetFilterPos, whldev, (long)p);
DBG("end");
if(fli_err) return FALSE; if(fli_err) return FALSE;
return TRUE; return TRUE;
} }
@ -427,7 +443,7 @@ static int fli_pollcapt(capture_status *st, float *remain){
goto retn; goto retn;
} }
if(remain) *remain = tmpl/1000.; if(remain) *remain = tmpl/1000.;
DBG("remained: %g", tmpl/1000.); //DBG("remained: %g", tmpl/1000.);
if(tmpl == 0){ if(tmpl == 0){
if(st) *st = CAPTURE_READY; if(st) *st = CAPTURE_READY;
capStatus = CAPTURE_NO; capStatus = CAPTURE_NO;
@ -506,15 +522,19 @@ typedef enum{
} temptype; } temptype;
static int fli_gettemp(temptype type, float *t){ static int fli_gettemp(temptype type, float *t){
if(!t) return FALSE;
double d; double d;
switch(type){ switch(type){
case T_COLD: case T_COLD:
DBG("read T_COLD");
TRYFUNC(FLIGetTemperature, camdev, &d); TRYFUNC(FLIGetTemperature, camdev, &d);
break; break;
case T_BODY: case T_BODY:
DBG("read T_BODY");
TRYFUNC(FLIReadTemperature, camdev, FLI_TEMPERATURE_EXTERNAL, &d); TRYFUNC(FLIReadTemperature, camdev, FLI_TEMPERATURE_EXTERNAL, &d);
break; break;
default: default:
DBG("read T_HOT");
TRYFUNC(FLIReadTemperature, camdev, FLI_TEMPERATURE_INTERNAL, &d); TRYFUNC(FLIReadTemperature, camdev, FLI_TEMPERATURE_INTERNAL, &d);
} }
if(fli_err) return FALSE; if(fli_err) return FALSE;
@ -581,8 +601,10 @@ static int fli_setio(int io){
static int fli_setexp(float t){ static int fli_setexp(float t){
long e = (long)(t*1000.); // milliseconds! long e = (long)(t*1000.); // milliseconds!
DBG("Try to set exp to %ldms", e);
TRYFUNC(FLISetExposureTime, camdev, e); TRYFUNC(FLISetExposureTime, camdev, e);
if(fli_err) return FALSE; if(fli_err) return FALSE;
DBG("OK");
return TRUE; return TRUE;
} }

View File

@ -9,4 +9,4 @@ include_directories(${${CCDLIB}_INCLUDE_DIRS} ..)
link_directories(${${CCDLIB}_LIBRARY_DIRS}) link_directories(${${CCDLIB}_LIBRARY_DIRS})
add_library(${CCDLIB} SHARED ${SRC}) add_library(${CCDLIB} SHARED ${SRC})
target_link_libraries(${CCDLIB} ${${CCDLIB}_LIBRARIES} -lASICamera2) target_link_libraries(${CCDLIB} ${${CCDLIB}_LIBRARIES} -lASICamera2 -fPIC)

View File

@ -85,18 +85,25 @@ static int asi_checkcam(){
static int campoll(capture_status *st, float *remain){ static int campoll(capture_status *st, float *remain){
if(!st) return FALSE; if(!st) return FALSE;
ASI_EXPOSURE_STATUS s; ASI_EXPOSURE_STATUS s;
if(ASI_SUCCESS != ASIGetExpStatus(caminfo.CameraID, &s)) return FALSE; if(ASI_SUCCESS != ASIGetExpStatus(caminfo.CameraID, &s)){
DBG("Can't get exp status");
return FALSE;
}
switch(s){ switch(s){
case ASI_EXP_IDLE: case ASI_EXP_IDLE:
DBG("No capture");
*st = CAPTURE_NO; *st = CAPTURE_NO;
break; break;
case ASI_EXP_WORKING: case ASI_EXP_WORKING:
DBG("Capture in progress");
*st = CAPTURE_PROCESS; *st = CAPTURE_PROCESS;
break; break;
case ASI_EXP_SUCCESS: case ASI_EXP_SUCCESS:
DBG("Capture ready");
*st = CAPTURE_READY; *st = CAPTURE_READY;
break; break;
default: // failed default: // failed
DBG("Failed: %d", s);
*st = CAPTURE_ABORTED; *st = CAPTURE_ABORTED;
} }
if(remain){ if(remain){
@ -309,8 +316,8 @@ static int gett(_U_ float *t){
static int camsetbin(int h, int v){ static int camsetbin(int h, int v){
DBG("set bin %dx%d", h, v); DBG("set bin %dx%d", h, v);
if(h != v){ if(h != v){
WARNX(_("BinX and BinY should be equal")); WARNX(_("BinX and BinY should be equal, take h"));
return FALSE; //return FALSE;
} }
if(h > extrvalues.maxbin){ if(h > extrvalues.maxbin){
WARNX(_("Maximal binning value is %d"), extrvalues.maxbin); WARNX(_("Maximal binning value is %d"), extrvalues.maxbin);

View File

@ -30,7 +30,7 @@
static char sendbuf[BUFSIZ]; static char sendbuf[BUFSIZ];
#define SENDMSG(...) do{snprintf(sendbuf, BUFSIZ-1, __VA_ARGS__); verbose(2, "\t> %s", sendbuf); sendstrmessage(sock, sendbuf); getans(sock);}while(0) #define SENDMSG(...) do{snprintf(sendbuf, BUFSIZ-1, __VA_ARGS__); verbose(2, "\t> %s", sendbuf); sendstrmessage(sock, sendbuf); getans(sock);}while(0)
static int expstate = 0; static int expstate = CAMERA_CAPTURE;
/** /**
* check data from fd (polling function for client) * check data from fd (polling function for client)
@ -77,7 +77,7 @@ static char *readmsg(int fd){
curlen += rd; curlen += rd;
buf[curlen] = 0; buf[curlen] = 0;
if(curlen == 0) return NULL; if(curlen == 0) return NULL;
DBG("cur buffer: ----%s----", buf); //DBG("cur buffer: ----%s----", buf);
char *nl = strchr(buf, '\n'); char *nl = strchr(buf, '\n');
if(!nl) return NULL; if(!nl) return NULL;
*nl++ = 0; *nl++ = 0;
@ -91,11 +91,15 @@ static char *readmsg(int fd){
// parser of CCD server messages; return TRUE to exit from polling cycle of `getans` (if receive 'FAIL', 'OK' or 'BUSY') // parser of CCD server messages; return TRUE to exit from polling cycle of `getans` (if receive 'FAIL', 'OK' or 'BUSY')
static int parseans(char *ans){ static int parseans(char *ans){
if(!ans) return FALSE; if(!ans) return FALSE;
//DBG("Parsing of '%s'", ans);
if(0 == strcmp(hresult2str(RESULT_BUSY), ans)) ERRX("Server busy"); if(0 == strcmp(hresult2str(RESULT_BUSY), ans)) ERRX("Server busy");
if(0 == strcmp(hresult2str(RESULT_FAIL), ans)) return TRUE; if(0 == strcmp(hresult2str(RESULT_FAIL), ans)) return TRUE;
if(0 == strcmp(hresult2str(RESULT_OK), ans)) return TRUE; if(0 == strcmp(hresult2str(RESULT_OK), ans)) return TRUE;
char *val = get_keyval(ans); // now `ans` is a key and `val` its value char *val = get_keyval(ans); // now `ans` is a key and `val` its value
if(0 == strcmp(CMD_EXPSTATE, ans)) expstate = atoi(val); if(0 == strcmp(CMD_EXPSTATE, ans)){
expstate = atoi(val);
DBG("Exposition state: %d", expstate);
}
return FALSE; return FALSE;
} }
@ -109,11 +113,13 @@ static int getans(int sock){
if(ans) return TRUE; if(ans) return TRUE;
else continue; else continue;
} }
t0 = dtime();
ans = s; ans = s;
DBG("Got from server: %s", ans); DBG("Got from server: %s", ans);
verbose(1, "\t%s", ans); verbose(1, "\t%s", ans);
if(parseans(ans)) break; if(parseans(ans)) break;
} }
DBG("GETANS: timeout, ans: %s", ans);
return ((ans) ? TRUE : FALSE); return ((ans) ? TRUE : FALSE);
} }
@ -121,6 +127,8 @@ static int getans(int sock){
* @brief processData - process here some actions and make messages for server * @brief processData - process here some actions and make messages for server
*/ */
static void process_data(int sock){ static void process_data(int sock){
// common information
SENDMSG(CMD_INFO);
// focuser // focuser
if(GP->listdevices) SENDMSG(CMD_FOCLIST); if(GP->listdevices) SENDMSG(CMD_FOCLIST);
if(GP->focdevno > -1) SENDMSG(CMD_FDEVNO "=%d", GP->focdevno); if(GP->focdevno > -1) SENDMSG(CMD_FDEVNO "=%d", GP->focdevno);
@ -181,8 +189,6 @@ static void process_data(int sock){
} }
SENDMSG(CMD_HEADERFILES "=%s", buf); SENDMSG(CMD_HEADERFILES "=%s", buf);
} }
// common information
SENDMSG(CMD_INFO);
} }
void client(int sock){ void client(int sock){
@ -200,12 +206,16 @@ void client(int sock){
else GP->waitexpend = TRUE; // N>1 - wait for exp ends else GP->waitexpend = TRUE; // N>1 - wait for exp ends
SENDMSG(CMD_EXPSTATE "=%d", CAMERA_CAPTURE); SENDMSG(CMD_EXPSTATE "=%d", CAMERA_CAPTURE);
} else { } else {
getans(sock); while(getans(sock));
DBG("RETURN: no more data");
return; return;
} }
double timeout = GP->waitexpend ? CLIENT_TIMEOUT : 0.1; double timeout = GP->waitexpend ? CLIENT_TIMEOUT : WAIT_TIMEOUT;
verbose(1, "Exposing frame 1..."); verbose(1, "Exposing frame 1...");
if(GP->waitexpend) verbose(2, "Wait for exposition end"); if(GP->waitexpend){
expstate = CAMERA_CAPTURE; // could be changed earlier
verbose(2, "Wait for exposition end");
}
while(dtime() - t0 < timeout){ while(dtime() - t0 < timeout){
if(GP->waitexpend && dtime() - tw > WAIT_TIMEOUT){ if(GP->waitexpend && dtime() - tw > WAIT_TIMEOUT){
SENDMSG(CMD_TREMAIN); // get remained time SENDMSG(CMD_TREMAIN); // get remained time
@ -214,6 +224,7 @@ void client(int sock){
sendstrmessage(sock, sendbuf); sendstrmessage(sock, sendbuf);
} }
if(getans(sock)){ // got next portion of data if(getans(sock)){ // got next portion of data
DBG("server message");
t0 = dtime(); t0 = dtime();
if(expstate == CAMERA_ERROR){ if(expstate == CAMERA_ERROR){
WARNX(_("Can't make exposition")); WARNX(_("Can't make exposition"));
@ -240,7 +251,7 @@ void client(int sock){
SENDMSG(CMD_EXPSTATE "=%d", CAMERA_CAPTURE); SENDMSG(CMD_EXPSTATE "=%d", CAMERA_CAPTURE);
}else{ }else{
GP->waitexpend = 0; GP->waitexpend = 0;
timeout = 0.2; // wait for last file name timeout = WAIT_TIMEOUT; // wait for last file name
} }
} }
} }

View File

@ -20,13 +20,6 @@
#ifndef CLIENT_H__ #ifndef CLIENT_H__
#define CLIENT_H__ #define CLIENT_H__
// waiting for answer timeout
#define ANSWER_TIMEOUT 1.0
// wait for exposition ends (between subsequent check calls)
#define WAIT_TIMEOUT 2.0
// client will disconnect after this time from last server message
#define CLIENT_TIMEOUT 10.0
// client-side functions // client-side functions
void client(int fd); void client(int fd);

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-03-22 17:17+0300\n" "POT-Creation-Date: 2022-03-24 11:43+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -473,12 +473,12 @@ msgstr ""
msgid "Can't set brightness to %g" msgid "Can't set brightness to %g"
msgstr "" msgstr ""
#: ccdfunc.c:703 server.c:219 #: ccdfunc.c:703 server.c:225
#, c-format #, c-format
msgid "Can't set binning %dx%d" msgid "Can't set binning %dx%d"
msgstr "" msgstr ""
#: ccdfunc.c:713 server.c:220 #: ccdfunc.c:713 server.c:226
msgid "Can't set given geometry" msgid "Can't set given geometry"
msgstr "" msgstr ""
@ -528,7 +528,7 @@ msgstr ""
msgid "Capture frame %d" msgid "Capture frame %d"
msgstr "" msgstr ""
#: ccdfunc.c:756 server.c:120 #: ccdfunc.c:756 server.c:121
msgid "Can't start exposition" msgid "Can't start exposition"
msgstr "" msgstr ""
@ -545,20 +545,20 @@ msgid "Can't grab image"
msgstr "" msgstr ""
#. %d секунд до окончания паузы\n #. %d секунд до окончания паузы\n
#: ccdfunc.c:803 client.c:232 #: ccdfunc.c:803 client.c:236
#, c-format #, c-format
msgid "%d seconds till pause ends\n" msgid "%d seconds till pause ends\n"
msgstr "" msgstr ""
#: server.c:161 #: server.c:163
msgid "No camera device" msgid "No camera device"
msgstr "" msgstr ""
#: client.c:219 #: client.c:223
msgid "Can't make exposition" msgid "Can't make exposition"
msgstr "" msgstr ""
#: client.c:248 #: client.c:252
msgid "Server timeout" msgid "Server timeout"
msgstr "" msgstr ""

View File

@ -7,7 +7,7 @@
msgid "" msgid ""
msgstr "Project-Id-Version: PACKAGE VERSION\n" msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-03-22 17:17+0300\n" "POT-Creation-Date: 2022-03-24 11:10+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -22,7 +22,7 @@ msgid "%.1f seconds till exposition ends"
msgstr "" msgstr ""
#. %d секунд до окончания паузы\n #. %d секунд до окончания паузы\n
#: ccdfunc.c:803 client.c:232 #: ccdfunc.c:803 client.c:236
#, c-format #, c-format
msgid "%d seconds till pause ends\n" msgid "%d seconds till pause ends\n"
msgstr "" msgstr ""
@ -117,7 +117,7 @@ msgstr ""
msgid "Can't init mutex!" msgid "Can't init mutex!"
msgstr "" msgstr ""
#: client.c:219 #: client.c:223
msgid "Can't make exposition" msgid "Can't make exposition"
msgstr "" msgstr ""
@ -162,7 +162,7 @@ msgstr ""
msgid "Can't set active wheel number" msgid "Can't set active wheel number"
msgstr "" msgstr ""
#: ccdfunc.c:703 server.c:219 #: ccdfunc.c:703 server.c:225
#, c-format #, c-format
msgid "Can't set binning %dx%d" msgid "Can't set binning %dx%d"
msgstr "" msgstr ""
@ -190,7 +190,7 @@ msgstr ""
msgid "Can't set gain to %g" msgid "Can't set gain to %g"
msgstr "" msgstr ""
#: ccdfunc.c:713 server.c:220 #: ccdfunc.c:713 server.c:226
msgid "Can't set given geometry" msgid "Can't set given geometry"
msgstr "" msgstr ""
@ -213,7 +213,7 @@ msgstr ""
msgid "Can't set wheel position %d" msgid "Can't set wheel position %d"
msgstr "" msgstr ""
#: ccdfunc.c:756 server.c:120 #: ccdfunc.c:756 server.c:121
msgid "Can't start exposition" msgid "Can't start exposition"
msgstr "" msgstr ""
@ -288,7 +288,7 @@ msgstr ""
msgid "Neither filename nor filename prefix pointed!" msgid "Neither filename nor filename prefix pointed!"
msgstr "" msgstr ""
#: server.c:161 #: server.c:163
msgid "No camera device" msgid "No camera device"
msgstr "" msgstr ""
@ -326,7 +326,7 @@ msgstr ""
msgid "Readout mode: %s" msgid "Readout mode: %s"
msgstr "" msgstr ""
#: client.c:248 #: client.c:252
msgid "Server timeout" msgid "Server timeout"
msgstr "" msgstr ""

2
main.c
View File

@ -47,7 +47,7 @@ void signals(int signo){
signal(signo, signals); signal(signo, signals);
return; return;
} }
DBG("Master killed with sig=%d", signo); WARNX("Master killed with sig=%d", signo);
LOGERR("Master killed with sig=%d", signo); LOGERR("Master killed with sig=%d", signo);
if(!GP->client){ if(!GP->client){
DBG("Unlink pid file"); DBG("Unlink pid file");

293
server.c
View File

@ -52,58 +52,59 @@ typedef struct{
// cat | awk '{print "{ " $3 ", \"\" }," }' | sort // cat | awk '{print "{ " $3 ", \"\" }," }' | sort
strpair allcommands[] = { strpair allcommands[] = {
{ "8bit", "run in 8 bit mode instead of 16 bit" }, { CMD_8BIT, "run in 8 bit mode instead of 16 bit" },
{ "author", "FITS 'AUTHOR' field" }, { CMD_AUTHOR, "FITS 'AUTHOR' field" },
{ "brightness", "camera brightness" }, { CMD_BRIGHTNESS, "camera brightness" },
{ "camdevno", "camera device number" }, { CMD_CAMDEVNO, "camera device number" },
{ "camlist", "list all connected cameras" }, { CMD_CAMLIST, "list all connected cameras" },
{ "ccdfanspeed", "fan speed of camera" }, { CMD_CAMFANSPD, "fan speed of camera" },
{ "confio", "camera IO configuration" }, { CMD_CONFIO, "camera IO configuration" },
{ "dark", "don't open shutter @ exposure" }, { CMD_DARK, "don't open shutter @ exposure" },
{ "expstate", "get exposition state" }, { CMD_EXPSTATE, "get exposition state" },
{ "exptime", "exposition time" }, { CMD_EXPOSITION, "exposition time" },
{ "fastspeed", "fast readout speed" }, { CMD_FASTSPD, "fast readout speed" },
{ "filename", "save file with this name, like file.fits" }, { CMD_FILENAME, "save file with this name, like file.fits" },
{ "filenameprefix", "prefix of files, like ex (will be saved as exXXXX.fits)" }, { CMD_FILENAMEPREFIX,"prefix of files, like ex (will be saved as exXXXX.fits)" },
{ "focdevno", "focuser device number" }, { CMD_FDEVNO, "focuser device number" },
{ "foclist", "list all connected focusers" }, { CMD_FOCLIST, "list all connected focusers" },
{ "focpos", "focuser position" }, { CMD_FGOTO, "focuser position" },
{ "format", "camera frame format (X0,Y0,X1,Y1)" }, { CMD_FRAMEFORMAT, "camera frame format (X0,Y0,X1,Y1)" },
{ "gain", "camera gain" }, { CMD_GAIN, "camera gain" },
{ "hbin", "horizontal binning" }, { CMD_HBIN, "horizontal binning" },
{ "headerfiles", "add FITS records from these files (comma-separated list)" }, { CMD_HEADERFILES, "add FITS records from these files (comma-separated list)" },
{ "help", "show this help" }, { CMD_HELP, "show this help" },
{ "info", "connected devices state" }, { CMD_INFO, "connected devices state" },
{ "instrument", "FITS 'INSTRUME' field" }, { CMD_INSTRUMENT, "FITS 'INSTRUME' field" },
{ "io", "get/set camera IO" }, { CMD_IO, "get/set camera IO" },
{ "lastfilename", "path to last saved file"}, { CMD_LASTFNAME, "path to last saved file"},
{ "maxformat", "camera maximal available format" }, { CMD_FRAMEMAX, "camera maximal available format" },
{ "nflushes", "camera number of preflushes" }, { CMD_NFLUSHES, "camera number of preflushes" },
{ "object", "FITS 'OBJECT' field" }, { CMD_OBJECT, "FITS 'OBJECT' field" },
{ "objtype", "FITS 'IMAGETYP' field" }, { CMD_OBJTYPE, "FITS 'IMAGETYP' field" },
{ "observer", "FITS 'OBSERVER' field" }, { CMD_OBSERVER, "FITS 'OBSERVER' field" },
{ "program", "FITS 'PROG-ID' field" }, { CMD_PROGRAM, "FITS 'PROG-ID' field" },
{ "rewrite", "rewrite file (if give `filename`, not `filenameprefix`" }, { CMD_RESTART, "restart server" },
{ "shutter", "camera shutter's operations" }, { CMD_REWRITE, "rewrite file (if give `filename`, not `filenameprefix`" },
{ "tcold", "camera chip temperature" }, { CMD_SHUTTER, "camera shutter's operations" },
{ "tremain", "time (in seconds) of exposition remained" }, { CMD_CAMTEMPER, "camera chip temperature" },
{ "vbin", "vertical binning" }, { CMD_TREMAIN, "time (in seconds) of exposition remained" },
{ "wdevno", "wheel device number" }, { CMD_VBIN, "vertical binning" },
{ "wlist", "list all connected wheels" }, { CMD_WDEVNO, "wheel device number" },
{ "wpos", "wheel position" }, { CMD_WLIST, "list all connected wheels" },
{ CMD_WPOS, "wheel position" },
{NULL, NULL}, {NULL, NULL},
}; };
static IMG ima = {0}; static IMG ima = {0};
static void fixima(){ static void fixima(){
FNAME(); FNAME();
if(!camera) return;
int raw_width = curformat.w / GP->hbin, raw_height = curformat.h / GP->vbin; int raw_width = curformat.w / GP->hbin, raw_height = curformat.h / GP->vbin;
if(!ima.data) ima.data = MALLOC(uint16_t, camera->array.h * camera->array.w);
if(ima.data && raw_width == ima.w && raw_height == ima.h) return; // all OK if(ima.data && raw_width == ima.w && raw_height == ima.h) return; // all OK
FREE(ima.data);
DBG("curformat: %dx%d", curformat.w, curformat.h); DBG("curformat: %dx%d", curformat.w, curformat.h);
ima.h = raw_height; ima.h = raw_height;
ima.w = raw_width; ima.w = raw_width;
ima.data = MALLOC(uint16_t, raw_width * raw_height);
DBG("new image: %dx%d", raw_width, raw_height); DBG("new image: %dx%d", raw_width, raw_height);
} }
@ -126,6 +127,7 @@ static inline void cameraidlestate(){ // idle - wait for capture commands
static inline void cameracapturestate(){ // capturing - wait for exposition ends static inline void cameracapturestate(){ // capturing - wait for exposition ends
if(camflags & FLAG_CANCEL){ // cancel all expositions if(camflags & FLAG_CANCEL){ // cancel all expositions
DBG("Cancel exposition"); DBG("Cancel exposition");
LOGMSG("User canceled exposition");
camflags &= ~(FLAG_STARTCAPTURE | FLAG_CANCEL); camflags &= ~(FLAG_STARTCAPTURE | FLAG_CANCEL);
camera->cancel(); camera->cancel();
camstate = CAMERA_IDLE; camstate = CAMERA_IDLE;
@ -166,18 +168,20 @@ static void* processCAM(_U_ void *d){
LOGERR("User asks to restart"); LOGERR("User asks to restart");
signals(1); signals(1);
} }
usleep(100);
if(0 == pthread_mutex_trylock(&locmutex)){
// log // log
if(dtime() - logt > TLOG_PAUSE){ if(dtime() - logt > TLOG_PAUSE){
logt = dtime(); logt = dtime();
float t; float t;
if(camera->getTcold(&t)){ if(camera->getTcold(&t)){
LOGMSG("CCDTEMP=%f", t); LOGMSG("CCDTEMP=%.1f", t);
} }
if(camera->getThot(&t)){ if(camera->getThot(&t)){
LOGMSG("HOTTEMP=%f", t); LOGMSG("HOTTEMP=%.1f", t);
} }
if(camera->getTbody(&t)){ if(camera->getTbody(&t)){
LOGMSG("BODYTEMP=%f", t); LOGMSG("BODYTEMP=%.1f", t);
} }
} }
camera_state curstate = camstate; camera_state curstate = camstate;
@ -189,12 +193,14 @@ static void* processCAM(_U_ void *d){
cameracapturestate(); cameracapturestate();
break; break;
case CAMERA_FRAMERDY: case CAMERA_FRAMERDY:
// do nothing: when `server` got this state it sends "expstate=2" to all clients and changes state to IDLE // do nothing: when `server` got this state it sends "expstate=2" to all clients and changes state to IDLE
break; break;
case CAMERA_ERROR: case CAMERA_ERROR:
// do nothing: when `server` got this state it sends "expstate=3" to all clients and changes state to IDLE // do nothing: when `server` got this state it sends "expstate=3" to all clients and changes state to IDLE
break; break;
} }
pthread_mutex_unlock(&locmutex);
}
} }
return NULL; return NULL;
} }
@ -202,10 +208,8 @@ static void* processCAM(_U_ void *d){
// functions running @ each devno change // functions running @ each devno change
static int camdevini(int n){ static int camdevini(int n){
if(!camera) return FALSE; if(!camera) return FALSE;
//pthread_mutex_lock(&locmutex);
if(!camera->setDevNo(n)){ if(!camera->setDevNo(n)){
LOGERR("Can't set active camera number"); LOGERR("Can't set active camera number");
//pthread_mutex_unlock(&locmutex);
return FALSE; return FALSE;
} }
camdevno = n; camdevno = n;
@ -218,36 +222,29 @@ static int camdevini(int n){
fixima(); fixima();
if(!camera->setbin(GP->hbin, GP->vbin)) WARNX(_("Can't set binning %dx%d"), GP->hbin, GP->vbin); if(!camera->setbin(GP->hbin, GP->vbin)) WARNX(_("Can't set binning %dx%d"), GP->hbin, GP->vbin);
if(!camera->setgeometry(&curformat)) WARNX(_("Can't set given geometry")); if(!camera->setgeometry(&curformat)) WARNX(_("Can't set given geometry"));
//pthread_mutex_unlock(&locmutex);
return TRUE; return TRUE;
} }
static int focdevini(int n){ static int focdevini(int n){
if(!focuser) return FALSE; if(!focuser) return FALSE;
//pthread_mutex_lock(&locmutex);
if(!focuser->setDevNo(n)){ if(!focuser->setDevNo(n)){
LOGERR("Can't set active focuser number"); LOGERR("Can't set active focuser number");
//pthread_mutex_unlock(&locmutex);
return FALSE; return FALSE;
} }
focdevno = n; focdevno = n;
LOGMSG("Set focuser device number to %d", focdevno); LOGMSG("Set focuser device number to %d", focdevno);
focuser->getMaxPos(&focmaxpos); focuser->getMaxPos(&focmaxpos);
focuser->getMinPos(&focminpos); focuser->getMinPos(&focminpos);
//pthread_mutex_unlock(&locmutex);
return TRUE; return TRUE;
} }
static int wheeldevini(int n){ static int wheeldevini(int n){
if(!wheel) return FALSE; if(!wheel) return FALSE;
//pthread_mutex_unlock(&locmutex);
if(!wheel->setDevNo(n)){ if(!wheel->setDevNo(n)){
LOGERR("Can't set active wheel number"); LOGERR("Can't set active wheel number");
//pthread_mutex_unlock(&locmutex);
return FALSE; return FALSE;
} }
wheeldevno = n; wheeldevno = n;
LOGMSG("Set wheel device number to %d", wheeldevno); LOGMSG("Set wheel device number to %d", wheeldevno);
wheel->getMaxPos(&wmaxpos); wheel->getMaxPos(&wmaxpos);
//pthread_mutex_unlock(&locmutex);
return TRUE; return TRUE;
} }
@ -264,15 +261,13 @@ static hresult restarthandler(_U_ int fd, _U_ const char *key, _U_ const char *v
******************************************************************************/ ******************************************************************************/
static hresult camlisthandler(int fd, _U_ const char *key, _U_ const char *val){ static hresult camlisthandler(int fd, _U_ const char *key, _U_ const char *val){
char buf[BUFSIZ], modname[256]; char buf[BUFSIZ], modname[256];
//pthread_mutex_lock(&locmutex);
for(int i = 0; i < camera->Ndevices; ++i){ for(int i = 0; i < camera->Ndevices; ++i){
if(!camera->setDevNo(i)) continue; if(!camera->setDevNo(i)) continue;
camera->getModelName(modname, 255); camera->getModelName(modname, 255);
snprintf(buf, BUFSIZ-1, CMD_CAMLIST "='%s'", modname); snprintf(buf, BUFSIZ-1, CMD_CAMLIST "='%s'", modname);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
} }
if(camdevno > -1) camera->setDevNo(camdevno); if(camdevno > -1) camera->setDevNo(camdevno);
//pthread_mutex_unlock(&locmutex);
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult camsetNhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){ static hresult camsetNhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
@ -285,61 +280,55 @@ static hresult camsetNhandler(_U_ int fd, _U_ const char *key, _U_ const char *v
if(!camdevini(num)) return RESULT_FAIL; if(!camdevini(num)) return RESULT_FAIL;
} }
snprintf(buf, 63, CMD_CAMDEVNO "=%d", camdevno); snprintf(buf, 63, CMD_CAMDEVNO "=%d", camdevno);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
// exposition time setter/getter // exposition time setter/getter
static hresult exphandler(int fd, _U_ const char *key, const char *val){ static hresult exphandler(int fd, _U_ const char *key, const char *val){
char buf[64]; char buf[64];
if(val){ if(val){
DBG("setexp to %s", val);
double v = atof(val); double v = atof(val);
if(v < DBL_EPSILON) return RESULT_BADVAL; if(v < DBL_EPSILON) return RESULT_BADVAL;
//pthread_mutex_lock(&locmutex);
if(camera->setexp(v)){ if(camera->setexp(v)){
GP->exptime = v; GP->exptime = v;
}else LOGWARN("Can't set exptime to %g", v); }else LOGWARN("Can't set exptime to %g", v);
//pthread_mutex_unlock(&locmutex);
} }
DBG("expt: %g", GP->exptime);
snprintf(buf, 63, CMD_EXPOSITION "=%g", GP->exptime); snprintf(buf, 63, CMD_EXPOSITION "=%g", GP->exptime);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
// show last filename of saved FITS // show last filename of saved FITS
static hresult lastfnamehandler(int fd, _U_ const char *key, _U_ const char *val){ static hresult lastfnamehandler(int fd, _U_ const char *key, _U_ const char *val){
char buf[PATH_MAX+32]; char buf[PATH_MAX+32];
//pthread_mutex_lock(&locmutex);
snprintf(buf, PATH_MAX+31, CMD_LASTFNAME "=%s", lastfile); snprintf(buf, PATH_MAX+31, CMD_LASTFNAME "=%s", lastfile);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
//pthread_mutex_unlock(&locmutex);
return RESULT_SILENCE; return RESULT_SILENCE;
} }
// filename setter/getter // filename setter/getter
static hresult namehandler(int fd, _U_ const char *key, const char *val){ static hresult namehandler(int fd, _U_ const char *key, const char *val){
char buf[PATH_MAX+32]; char buf[PATH_MAX+32];
if(val){ if(val){
//pthread_mutex_lock(&locmutex);
char *path = makeabspath(val, FALSE); char *path = makeabspath(val, FALSE);
if(!path){ if(!path){
LOGERR("Can't create file '%s'", val); LOGERR("Can't create file '%s'", val);
//pthread_mutex_unlock(&locmutex);
return RESULT_BADVAL; return RESULT_BADVAL;
} }
FREE(outfile); FREE(outfile);
outfile = strdup(path); outfile = strdup(path);
GP->outfile = outfile; GP->outfile = outfile;
GP->outfileprefix = NULL; GP->outfileprefix = NULL;
//pthread_mutex_unlock(&locmutex);
} }
if(!GP->outfile) return RESULT_FAIL; if(!GP->outfile) return RESULT_FAIL;
snprintf(buf, PATH_MAX+31, CMD_FILENAME "=%s", GP->outfile); snprintf(buf, PATH_MAX+31, CMD_FILENAME "=%s", GP->outfile);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
// filename prefix // filename prefix
static hresult nameprefixhandler(_U_ int fd, _U_ const char *key, const char *val){ static hresult nameprefixhandler(_U_ int fd, _U_ const char *key, const char *val){
char buf[PATH_MAX+32]; char buf[PATH_MAX+32];
if(val){ if(val){
//pthread_mutex_lock(&locmutex);
char *path = makeabspath(val, FALSE); char *path = makeabspath(val, FALSE);
if(!path){ if(!path){
LOGERR("Can't create file '%s'", val); LOGERR("Can't create file '%s'", val);
@ -350,11 +339,10 @@ static hresult nameprefixhandler(_U_ int fd, _U_ const char *key, const char *va
outfile = strdup(path); outfile = strdup(path);
GP->outfileprefix = outfile; GP->outfileprefix = outfile;
GP->outfile = NULL; GP->outfile = NULL;
//pthread_mutex_unlock(&locmutex);
} }
if(!GP->outfileprefix) return RESULT_FAIL; if(!GP->outfileprefix) return RESULT_FAIL;
snprintf(buf, PATH_MAX+31, CMD_FILENAMEPREFIX "=%s", GP->outfileprefix); snprintf(buf, PATH_MAX+31, CMD_FILENAMEPREFIX "=%s", GP->outfileprefix);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
// rewrite // rewrite
@ -363,12 +351,10 @@ static hresult rewritefilehandler(_U_ int fd, _U_ const char *key, const char *v
if(val){ if(val){
int n = atoi(val); int n = atoi(val);
if(n < 0 || n > 1) return RESULT_BADVAL; if(n < 0 || n > 1) return RESULT_BADVAL;
//pthread_mutex_lock(&locmutex);
GP->rewrite = n; GP->rewrite = n;
//pthread_mutex_unlock(&locmutex);
} }
snprintf(buf, 63, CMD_REWRITE "=%d", GP->rewrite); snprintf(buf, 63, CMD_REWRITE "=%d", GP->rewrite);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult binhandler(_U_ int fd, const char *key, const char *val){ static hresult binhandler(_U_ int fd, const char *key, const char *val){
@ -378,21 +364,16 @@ static hresult binhandler(_U_ int fd, const char *key, const char *val){
if(b < 1) return RESULT_BADVAL; if(b < 1) return RESULT_BADVAL;
if(0 == strcmp(key, CMD_HBIN)) GP->hbin = b; if(0 == strcmp(key, CMD_HBIN)) GP->hbin = b;
else GP->vbin = b; else GP->vbin = b;
//pthread_mutex_lock(&locmutex);
if(!camera->setbin(GP->hbin, GP->vbin)){ if(!camera->setbin(GP->hbin, GP->vbin)){
//pthread_mutex_unlock(&locmutex);
return RESULT_BADVAL; return RESULT_BADVAL;
} }
fixima();
//pthread_mutex_unlock(&locmutex);
} }
//pthread_mutex_lock(&locmutex);
int r = camera->getbin(&GP->hbin, &GP->vbin); int r = camera->getbin(&GP->hbin, &GP->vbin);
//pthread_mutex_unlock(&locmutex);
if(r){ if(r){
if(0 == strcmp(key, CMD_HBIN)) snprintf(buf, 63, "%s=%d", key, GP->hbin); if(0 == strcmp(key, CMD_HBIN)) snprintf(buf, 63, "%s=%d", key, GP->hbin);
else snprintf(buf, 63, "%s=%d", key, GP->vbin); else snprintf(buf, 63, "%s=%d", key, GP->vbin);
sendstrmessage(fd, buf); if(val) fixima();
if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
return RESULT_FAIL; return RESULT_FAIL;
@ -403,34 +384,26 @@ static hresult temphandler(_U_ int fd, _U_ const char *key, const char *val){
int r; int r;
if(val){ if(val){
f = atof(val); f = atof(val);
//pthread_mutex_lock(&locmutex);
r = camera->setT((float)f); r = camera->setT((float)f);
//pthread_mutex_unlock(&locmutex);
if(!r){ if(!r){
LOGWARN("Can't set camera T to %.1f", f); LOGWARN("Can't set camera T to %.1f", f);
return RESULT_FAIL; return RESULT_FAIL;
} }
LOGMSG("Set camera T to %.1f", f); LOGMSG("Set camera T to %.1f", f);
} }
//pthread_mutex_lock(&locmutex);
r = camera->getTcold(&f); r = camera->getTcold(&f);
//pthread_mutex_unlock(&locmutex);
if(r){ if(r){
snprintf(buf, 63, CMD_CAMTEMPER "=%.1f", f); snprintf(buf, 63, CMD_CAMTEMPER "=%.1f", f);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
//pthread_mutex_lock(&locmutex);
r = camera->getTbody(&f); r = camera->getTbody(&f);
//pthread_mutex_unlock(&locmutex);
if(r){ if(r){
snprintf(buf, 63, "tbody=%.1f", f); snprintf(buf, 63, "tbody=%.1f", f);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
} }
//pthread_mutex_lock(&locmutex);
r = camera->getThot(&f); r = camera->getThot(&f);
//pthread_mutex_unlock(&locmutex);
if(r){ if(r){
snprintf(buf, 63, "thot=%.1f", f); snprintf(buf, 63, "thot=%.1f", f);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
} }
return RESULT_SILENCE; return RESULT_SILENCE;
}else return RESULT_FAIL; }else return RESULT_FAIL;
@ -441,14 +414,12 @@ static hresult camfanhandler(_U_ int fd, _U_ const char *key, _U_ const char *va
int spd = atoi(val); int spd = atoi(val);
if(spd < 0) return RESULT_BADVAL; if(spd < 0) return RESULT_BADVAL;
if(spd > FAN_HIGH) spd = FAN_HIGH; if(spd > FAN_HIGH) spd = FAN_HIGH;
//pthread_mutex_lock(&locmutex);
int r = camera->setfanspeed((fan_speed)spd); int r = camera->setfanspeed((fan_speed)spd);
//pthread_mutex_unlock(&locmutex);
if(!r) return RESULT_FAIL; if(!r) return RESULT_FAIL;
camfanspd = spd; camfanspd = spd;
} }
snprintf(buf, 63, CMD_CAMFANSPD "=%d", camfanspd); snprintf(buf, 63, CMD_CAMFANSPD "=%d", camfanspd);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
const char *shutterstr[] = {"open", "close", "expose @high", "expose @low"}; const char *shutterstr[] = {"open", "close", "expose @high", "expose @low"};
@ -456,9 +427,7 @@ static hresult shutterhandler(_U_ int fd, _U_ const char *key, const char *val){
if(val){ if(val){
int x = atoi(val); int x = atoi(val);
if(x < 0 || x >= SHUTTER_AMOUNT) return RESULT_BADVAL; if(x < 0 || x >= SHUTTER_AMOUNT) return RESULT_BADVAL;
//pthread_mutex_lock(&locmutex);
int r = camera->shuttercmd((shutter_op)x); int r = camera->shuttercmd((shutter_op)x);
//pthread_mutex_unlock(&locmutex);
if(r){ if(r){
LOGMSG("Shutter command '%s'", shutterstr[x]); LOGMSG("Shutter command '%s'", shutterstr[x]);
}else{ }else{
@ -472,14 +441,12 @@ static hresult confiohandler(_U_ int fd, _U_ const char *key, _U_ const char *va
char buf[64]; char buf[64];
if(val){ if(val){
int io = atoi(val); int io = atoi(val);
//pthread_mutex_lock(&locmutex);
int r = camera->confio(io); int r = camera->confio(io);
//pthread_mutex_unlock(&locmutex);
if(!r) return RESULT_FAIL; if(!r) return RESULT_FAIL;
confio = io; confio = io;
} }
snprintf(buf, 63, CMD_CONFIO "=%d", confio); snprintf(buf, 63, CMD_CONFIO "=%d", confio);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult iohandler(_U_ int fd, _U_ const char *key, _U_ const char *val){ static hresult iohandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
@ -487,17 +454,13 @@ static hresult iohandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
int io; int io;
if(val){ if(val){
io = atoi(val); io = atoi(val);
//pthread_mutex_lock(&locmutex);
int r = camera->setio(io); int r = camera->setio(io);
//pthread_mutex_unlock(&locmutex);
if(!r) return RESULT_FAIL; if(!r) return RESULT_FAIL;
} }
//pthread_mutex_lock(&locmutex);
int r = camera->getio(&io); int r = camera->getio(&io);
//pthread_mutex_unlock(&locmutex);
if(!r) return RESULT_FAIL; if(!r) return RESULT_FAIL;
snprintf(buf, 63, CMD_IO "=%d", io); snprintf(buf, 63, CMD_IO "=%d", io);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult gainhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){ static hresult gainhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
@ -505,17 +468,13 @@ static hresult gainhandler(_U_ int fd, _U_ const char *key, _U_ const char *val)
float f; float f;
if(val){ if(val){
f = atof(val); f = atof(val);
//pthread_mutex_lock(&locmutex);
int r = camera->setgain(f); int r = camera->setgain(f);
//pthread_mutex_unlock(&locmutex);
if(!r) return RESULT_FAIL; if(!r) return RESULT_FAIL;
} }
//pthread_mutex_lock(&locmutex);
int r = camera->getgain(&f); int r = camera->getgain(&f);
//pthread_mutex_unlock(&locmutex);
if(!r) return RESULT_FAIL; if(!r) return RESULT_FAIL;
snprintf(buf, 63, CMD_GAIN "=%.1f", f); snprintf(buf, 63, CMD_GAIN "=%.1f", f);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult brightnesshandler(_U_ int fd, _U_ const char *key, _U_ const char *val){ static hresult brightnesshandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
@ -523,17 +482,13 @@ static hresult brightnesshandler(_U_ int fd, _U_ const char *key, _U_ const char
float b; float b;
if(val){ if(val){
b = atof(val); b = atof(val);
//pthread_mutex_lock(&locmutex);
int r = camera->setbrightness(b); int r = camera->setbrightness(b);
//pthread_mutex_unlock(&locmutex);
if(!r) return RESULT_FAIL; if(!r) return RESULT_FAIL;
} }
//pthread_mutex_lock(&locmutex);
int r = camera->getbrightness(&b); int r = camera->getbrightness(&b);
//pthread_mutex_unlock(&locmutex);
if(!r) return RESULT_FAIL; if(!r) return RESULT_FAIL;
snprintf(buf, 63, CMD_BRIGHTNESS "=%.1f", b); snprintf(buf, 63, CMD_BRIGHTNESS "=%.1f", b);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
// set format: `format=X0,X1,Y0,Y1` // set format: `format=X0,X1,Y0,Y1`
@ -545,9 +500,7 @@ static hresult formathandler(int fd, const char *key, const char *val){
if(strcmp(key, CMD_FRAMEFORMAT)) return RESULT_BADKEY; // can't set maxformat if(strcmp(key, CMD_FRAMEFORMAT)) return RESULT_BADKEY; // can't set maxformat
if(4 != sscanf(val, "%d,%d,%d,%d", &fmt.xoff, &fmt.yoff, &fmt.w, &fmt.h)) return RESULT_BADVAL; if(4 != sscanf(val, "%d,%d,%d,%d", &fmt.xoff, &fmt.yoff, &fmt.w, &fmt.h)) return RESULT_BADVAL;
fmt.w -= fmt.xoff; fmt.h -= fmt.yoff; fmt.w -= fmt.xoff; fmt.h -= fmt.yoff;
//pthread_mutex_lock(&locmutex);
int r = camera->setgeometry(&fmt); int r = camera->setgeometry(&fmt);
//pthread_mutex_unlock(&locmutex);
if(!r) return RESULT_FAIL; if(!r) return RESULT_FAIL;
curformat = fmt; curformat = fmt;
fixima(); fixima();
@ -556,7 +509,7 @@ static hresult formathandler(int fd, const char *key, const char *val){
frmformatmax.xoff, frmformatmax.yoff, frmformatmax.xoff+frmformatmax.w, frmformatmax.yoff+frmformatmax.h); frmformatmax.xoff, frmformatmax.yoff, frmformatmax.xoff+frmformatmax.w, frmformatmax.yoff+frmformatmax.h);
else snprintf(buf, 63, CMD_FRAMEFORMAT "=%d,%d,%d,%d", else snprintf(buf, 63, CMD_FRAMEFORMAT "=%d,%d,%d,%d",
camera->geometry.xoff, camera->geometry.yoff, camera->geometry.xoff+camera->geometry.w, camera->geometry.yoff+camera->geometry.h); camera->geometry.xoff, camera->geometry.yoff, camera->geometry.xoff+camera->geometry.w, camera->geometry.yoff+camera->geometry.h);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult nflusheshandler(_U_ int fd, _U_ const char *key, _U_ const char *val){ static hresult nflusheshandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
@ -564,16 +517,13 @@ static hresult nflusheshandler(_U_ int fd, _U_ const char *key, _U_ const char *
if(val){ if(val){
int n = atoi(val); int n = atoi(val);
if(n < 1) return RESULT_BADVAL; if(n < 1) return RESULT_BADVAL;
//pthread_mutex_lock(&locmutex);
if(!camera->setnflushes(n)){ if(!camera->setnflushes(n)){
//pthread_mutex_unlock(&locmutex);
return RESULT_FAIL; return RESULT_FAIL;
} }
nflushes = n; nflushes = n;
//pthread_mutex_unlock(&locmutex);
} }
snprintf(buf, 63, CMD_NFLUSHES "=%d", nflushes); snprintf(buf, 63, CMD_NFLUSHES "=%d", nflushes);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult expstatehandler(_U_ int fd, _U_ const char *key, _U_ const char *val){ static hresult expstatehandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
@ -591,15 +541,15 @@ static hresult expstatehandler(_U_ int fd, _U_ const char *key, _U_ const char *
else return RESULT_BADVAL; else return RESULT_BADVAL;
} }
snprintf(buf, 63, CMD_EXPSTATE "=%d", camstate); snprintf(buf, 63, CMD_EXPSTATE "=%d", camstate);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
snprintf(buf, 63, "camflags=%d", camflags); snprintf(buf, 63, "camflags=%d", camflags);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult tremainhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){ static hresult tremainhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
char buf[64]; char buf[64];
snprintf(buf, 63, CMD_TREMAIN "=%g", tremain); snprintf(buf, 63, CMD_TREMAIN "=%g", tremain);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult _8bithandler(int fd, _U_ const char *key, const char *val){ static hresult _8bithandler(int fd, _U_ const char *key, const char *val){
@ -612,7 +562,7 @@ static hresult _8bithandler(int fd, _U_ const char *key, const char *val){
if(!camera->setbitdepth(s)) return RESULT_FAIL; if(!camera->setbitdepth(s)) return RESULT_FAIL;
} }
snprintf(buf, 63, CMD_8BIT "=%d", GP->_8bit); snprintf(buf, 63, CMD_8BIT "=%d", GP->_8bit);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult fastspdhandler(int fd, _U_ const char *key, const char *val){ static hresult fastspdhandler(int fd, _U_ const char *key, const char *val){
@ -624,7 +574,7 @@ static hresult fastspdhandler(int fd, _U_ const char *key, const char *val){
if(!camera->setfastspeed(b)) return RESULT_FAIL; if(!camera->setfastspeed(b)) return RESULT_FAIL;
} }
snprintf(buf, 63, CMD_FASTSPD "=%d", GP->fast); snprintf(buf, 63, CMD_FASTSPD "=%d", GP->fast);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult darkhandler(int fd, _U_ const char *key, const char *val){ static hresult darkhandler(int fd, _U_ const char *key, const char *val){
@ -637,7 +587,7 @@ static hresult darkhandler(int fd, _U_ const char *key, const char *val){
if(!camera->setframetype(d)) return RESULT_FAIL; if(!camera->setframetype(d)) return RESULT_FAIL;
} }
snprintf(buf, 63, CMD_DARK "=%d", GP->dark); snprintf(buf, 63, CMD_DARK "=%d", GP->dark);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult FITSparhandler(int fd, const char *key, const char *val){ static hresult FITSparhandler(int fd, const char *key, const char *val){
@ -660,7 +610,7 @@ static hresult FITSparhandler(int fd, const char *key, const char *val){
*fitskey = strdup(val); *fitskey = strdup(val);
} }
snprintf(buf, 255, "%s=%s", key, *fitskey); snprintf(buf, 255, "%s=%s", key, *fitskey);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult FITSheaderhandler(int fd, _U_ const char *key, const char *val){ static hresult FITSheaderhandler(int fd, _U_ const char *key, const char *val){
@ -669,7 +619,6 @@ static hresult FITSheaderhandler(int fd, _U_ const char *key, const char *val){
static int firstrun = 1; static int firstrun = 1;
if(val){ if(val){
int sz = 10, amount = 0; int sz = 10, amount = 0;
//pthread_mutex_lock(&locmutex);
// first we should check `val` // first we should check `val`
char b2[BUFSIZ], *bptr = buf; char b2[BUFSIZ], *bptr = buf;
snprintf(b2, BUFSIZ-1, "%s", val); snprintf(b2, BUFSIZ-1, "%s", val);
@ -715,9 +664,8 @@ static hresult FITSheaderhandler(int fd, _U_ const char *key, const char *val){
} }
GP->addhdr = list; GP->addhdr = list;
FREE(curhdr); FREE(curhdr);
if(*val && *val != ',') curhdr = strdup(buf); if(*val && *val != ',') curhdr = strdup(buf); // command with empty arg will clear curhdr
DBG("curhdr now: %s", curhdr); DBG("curhdr now: %s", curhdr);
//pthread_mutex_unlock(&locmutex);
} }
if(!curhdr && firstrun){ if(!curhdr && firstrun){
firstrun = 0; firstrun = 0;
@ -734,7 +682,7 @@ static hresult FITSheaderhandler(int fd, _U_ const char *key, const char *val){
} }
} }
snprintf(buf, BUFSIZ-1, CMD_HEADERFILES "=%s", curhdr); snprintf(buf, BUFSIZ-1, CMD_HEADERFILES "=%s", curhdr);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
/* /*
@ -748,16 +696,14 @@ static hresult handler(_U_ int fd, _U_ const char *key, _U_ const char *val){
******************************************************************************/ ******************************************************************************/
static hresult wlisthandler(int fd, _U_ const char *key, _U_ const char *val){ static hresult wlisthandler(int fd, _U_ const char *key, _U_ const char *val){
if(wheel->Ndevices < 1) return RESULT_FAIL; if(wheel->Ndevices < 1) return RESULT_FAIL;
//pthread_mutex_lock(&locmutex);
for(int i = 0; i < wheel->Ndevices; ++i){ for(int i = 0; i < wheel->Ndevices; ++i){
if(!wheel->setDevNo(i)) continue; if(!wheel->setDevNo(i)) continue;
char modname[256], buf[BUFSIZ]; char modname[256], buf[BUFSIZ];
wheel->getModelName(modname, 255); wheel->getModelName(modname, 255);
snprintf(buf, BUFSIZ-1, CMD_WLIST "='%s'", modname); snprintf(buf, BUFSIZ-1, CMD_WLIST "='%s'", modname);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
} }
if(wheeldevno > -1) wheel->setDevNo(wheeldevno); if(wheeldevno > -1) wheel->setDevNo(wheeldevno);
//pthread_mutex_unlock(&locmutex);
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult wsetNhandler(int fd, _U_ const char *key, const char *val){ static hresult wsetNhandler(int fd, _U_ const char *key, const char *val){
@ -770,7 +716,7 @@ static hresult wsetNhandler(int fd, _U_ const char *key, const char *val){
if(!wheeldevini(num)) return RESULT_FAIL; if(!wheeldevini(num)) return RESULT_FAIL;
} }
snprintf(buf, 63, CMD_WDEVNO "=%d", wheeldevno); snprintf(buf, 63, CMD_WDEVNO "=%d", wheeldevno);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
@ -779,17 +725,15 @@ static hresult wgotohandler(_U_ int fd, _U_ const char *key, _U_ const char *val
int pos; int pos;
if(val){ if(val){
pos = atoi(val); pos = atoi(val);
//pthread_mutex_lock(&locmutex); DBG("USER wants to %d", pos);
int r = wheel->setPos(pos); int r = wheel->setPos(pos);
//pthread_mutex_unlock(&locmutex); DBG("wheel->setPos(%d)", pos);
if(!r) return RESULT_BADVAL; if(!r) return RESULT_BADVAL;
} }
//pthread_mutex_lock(&locmutex);
int r = wheel->getPos(&pos); int r = wheel->getPos(&pos);
//pthread_mutex_unlock(&locmutex);
if(!r) return RESULT_FAIL; if(!r) return RESULT_FAIL;
snprintf(buf, 63, CMD_WPOS "=%d", pos); snprintf(buf, 63, CMD_WPOS "=%d", pos);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
@ -799,16 +743,14 @@ static hresult wgotohandler(_U_ int fd, _U_ const char *key, _U_ const char *val
static hresult foclisthandler(int fd, _U_ const char *key, _U_ const char *val){ static hresult foclisthandler(int fd, _U_ const char *key, _U_ const char *val){
if(focuser->Ndevices < 1) return RESULT_FAIL; if(focuser->Ndevices < 1) return RESULT_FAIL;
//pthread_mutex_lock(&locmutex);
for(int i = 0; i < focuser->Ndevices; ++i){ for(int i = 0; i < focuser->Ndevices; ++i){
char modname[256], buf[BUFSIZ]; char modname[256], buf[BUFSIZ];
if(!focuser->setDevNo(i)) continue; if(!focuser->setDevNo(i)) continue;
focuser->getModelName(modname, 255); focuser->getModelName(modname, 255);
snprintf(buf, BUFSIZ-1, CMD_FOCLIST "='%s'", modname); snprintf(buf, BUFSIZ-1, CMD_FOCLIST "='%s'", modname);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
} }
if(focdevno > -1) focuser->setDevNo(focdevno); if(focdevno > -1) focuser->setDevNo(focdevno);
//pthread_mutex_unlock(&locmutex);
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult fsetNhandler(int fd, _U_ const char *key, const char *val){ static hresult fsetNhandler(int fd, _U_ const char *key, const char *val){
@ -821,7 +763,7 @@ static hresult fsetNhandler(int fd, _U_ const char *key, const char *val){
if(!focdevini(num)) return RESULT_FAIL; if(!focdevini(num)) return RESULT_FAIL;
} }
snprintf(buf, 63, CMD_FDEVNO "=%d", focdevno); snprintf(buf, 63, CMD_FDEVNO "=%d", focdevno);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
static hresult fgotohandler(int fd, _U_ const char *key, const char *val){ static hresult fgotohandler(int fd, _U_ const char *key, const char *val){
@ -831,21 +773,17 @@ static hresult fgotohandler(int fd, _U_ const char *key, const char *val){
if(val){ if(val){
f = atof(val); f = atof(val);
if(f < focminpos || f > focmaxpos) return RESULT_BADVAL; if(f < focminpos || f > focmaxpos) return RESULT_BADVAL;
//pthread_mutex_lock(&locmutex);
if(f - focminpos < __FLT_EPSILON__){ if(f - focminpos < __FLT_EPSILON__){
r = focuser->home(1); r = focuser->home(1);
}else{ }else{
r = focuser->setAbsPos(1, f); r = focuser->setAbsPos(1, f);
} }
//pthread_mutex_unlock(&locmutex);
if(!r) return RESULT_FAIL; if(!r) return RESULT_FAIL;
} }
//pthread_mutex_lock(&locmutex);
r = focuser->getPos(&f); r = focuser->getPos(&f);
//pthread_mutex_unlock(&locmutex);
if(!r) return RESULT_FAIL; if(!r) return RESULT_FAIL;
snprintf(buf, 63, CMD_FGOTO "=%g", f); snprintf(buf, 63, CMD_FGOTO "=%g", f);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE; return RESULT_SILENCE;
} }
@ -861,48 +799,52 @@ static hresult infohandler(int fd, _U_ const char *key, _U_ const char *val){
if(camera){ if(camera){
if(camera->getModelName(buf1, 255)){ if(camera->getModelName(buf1, 255)){
snprintf(buf, BUFSIZ-1, CMD_CAMLIST "='%s'", buf1); snprintf(buf, BUFSIZ-1, CMD_CAMLIST "='%s'", buf1);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
} }
namehandler(fd, CMD_FILENAME, NULL); #define RUN(f, arg) do{if(RESULT_DISCONNECTED == f(fd, arg, NULL)) return RESULT_DISCONNECTED;}while(0)
binhandler(fd, CMD_HBIN, NULL); RUN(namehandler, CMD_FILENAME);
binhandler(fd, CMD_VBIN, NULL); RUN(binhandler, CMD_HBIN);
temphandler(fd, CMD_CAMTEMPER, NULL); RUN(binhandler, CMD_VBIN);
exphandler(fd, CMD_EXPOSITION, NULL); RUN(temphandler, CMD_CAMTEMPER);
lastfnamehandler(fd, CMD_LASTFNAME, NULL); RUN(exphandler, CMD_EXPOSITION);
expstatehandler(fd, CMD_EXPSTATE, NULL); RUN(lastfnamehandler, CMD_LASTFNAME);
RUN(expstatehandler, CMD_EXPSTATE);
#undef RUN
} }
DBG("chk wheel");
if(wheel){ if(wheel){
DBG("Wname");
if(wheel->getModelName(buf1, 255)){ if(wheel->getModelName(buf1, 255)){
snprintf(buf, BUFSIZ-1, CMD_WLIST "='%s'", buf1); snprintf(buf, BUFSIZ-1, CMD_WLIST "='%s'", buf1);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
} }
if(wheel->getTbody(&f)){ if(wheel->getTbody(&f)){
snprintf(buf, BUFSIZ-1, "wtemp=%.1f", f); snprintf(buf, BUFSIZ-1, "wtemp=%.1f", f);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
} }
if(wheel->getPos(&i)){ if(wheel->getPos(&i)){
snprintf(buf, BUFSIZ-1, CMD_WPOS "=%d", i); snprintf(buf, BUFSIZ-1, CMD_WPOS "=%d", i);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
} }
snprintf(buf, BUFSIZ-1, "wmaxpos=%d", wmaxpos); snprintf(buf, BUFSIZ-1, "wmaxpos=%d", wmaxpos);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
} }
if(focuser){ if(focuser){
if(focuser->getModelName(buf1, 255)){ if(focuser->getModelName(buf1, 255)){
snprintf(buf, BUFSIZ-1, CMD_FOCLIST "='%s'", buf1); snprintf(buf, BUFSIZ-1, CMD_FOCLIST "='%s'", buf1);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
} }
if(focuser->getTbody(&f)){ if(focuser->getTbody(&f)){
snprintf(buf, BUFSIZ-1, "foctemp=%.1f", f); snprintf(buf, BUFSIZ-1, "foctemp=%.1f", f);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
} }
snprintf(buf, BUFSIZ-1, "focminpos=%g", focminpos); snprintf(buf, BUFSIZ-1, "focminpos=%g", focminpos);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
snprintf(buf, BUFSIZ-1, "focmaxpos=%g", focmaxpos); snprintf(buf, BUFSIZ-1, "focmaxpos=%g", focmaxpos);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
if(focuser->getPos(&f)){ if(focuser->getPos(&f)){
snprintf(buf, BUFSIZ-1, CMD_FGOTO "=%g", f); snprintf(buf, BUFSIZ-1, CMD_FGOTO "=%g", f);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
} }
} }
return RESULT_SILENCE; return RESULT_SILENCE;
@ -913,7 +855,7 @@ static hresult helphandler(int fd, _U_ const char *key, _U_ const char *val){
strpair *ptr = allcommands; strpair *ptr = allcommands;
while(ptr->key){ while(ptr->key){
snprintf(buf, 255, "%s - %s", ptr->key, ptr->help); snprintf(buf, 255, "%s - %s", ptr->key, ptr->help);
sendstrmessage(fd, buf); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
++ptr; ++ptr;
} }
return RESULT_SILENCE; return RESULT_SILENCE;
@ -927,7 +869,10 @@ static int CAMbusy(){
} }
return FALSE; return FALSE;
} }
// check funtions
static hresult chktrue(_U_ char *val){ // dummy check for `infohandler` (need to lock mutex anymore)
return RESULT_OK;
}
static hresult chkcam(char *val){ static hresult chkcam(char *val){
if(val && CAMbusy()) return RESULT_BUSY; if(val && CAMbusy()) return RESULT_BUSY;
if(camera) return RESULT_OK; if(camera) return RESULT_OK;
@ -944,7 +889,7 @@ static hresult chkfoc(char *val){
return RESULT_FAIL; return RESULT_FAIL;
} }
static handleritem items[] = { static handleritem items[] = {
{NULL, infohandler, CMD_INFO}, {chktrue,infohandler, CMD_INFO},
{NULL, helphandler, CMD_HELP}, {NULL, helphandler, CMD_HELP},
{NULL, restarthandler, CMD_RESTART}, {NULL, restarthandler, CMD_RESTART},
{chkcam, camlisthandler, CMD_CAMLIST}, {chkcam, camlisthandler, CMD_CAMLIST},
@ -991,12 +936,12 @@ static handleritem items[] = {
void server(int sock){ void server(int sock){
// init everything // init everything
startCCD(&camdev);
camdevini(0);
startFocuser(&focdev); startFocuser(&focdev);
focdevini(0); focdevini(0);
startWheel(&wheeldev); startWheel(&wheeldev);
wheeldevini(0); wheeldevini(0);
startCCD(&camdev);
camdevini(0);
if(listen(sock, MAXCLIENTS) == -1){ if(listen(sock, MAXCLIENTS) == -1){
WARN("listen"); WARN("listen");
LOGWARN("listen"); LOGWARN("listen");

View File

@ -18,7 +18,6 @@
#include <ctype.h> // isspace #include <ctype.h> // isspace
#include <netdb.h> #include <netdb.h>
#include <pthread.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -30,7 +29,7 @@
#include "server.h" #include "server.h"
#include "socket.h" #include "socket.h"
static pthread_mutex_t locmutex = PTHREAD_MUTEX_INITIALIZER; // mutex for wheel/camera/focuser functions pthread_mutex_t locmutex = PTHREAD_MUTEX_INITIALIZER; // mutex for wheel/camera/focuser functions
/** /**
* @brief start_socket - create socket and run client or server * @brief start_socket - create socket and run client or server
@ -82,26 +81,28 @@ int start_socket(int isserver, char *path, int isnet){
if(isserver){ if(isserver){
int reuseaddr = 1; int reuseaddr = 1;
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)) == -1){ if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)) == -1){
LOGWARN("setsockopt()");
WARN("setsockopt()"); WARN("setsockopt()");
LOGWARN("setsockopt()");
close(sock); sock = -1; close(sock); sock = -1;
continue; continue;
} }
if(bind(sock, p->ai_addr, p->ai_addrlen) == -1){ if(bind(sock, p->ai_addr, p->ai_addrlen) == -1){
LOGWARN("bind()");
WARN("bind()"); WARN("bind()");
LOGWARN("bind()");
close(sock); sock = -1; close(sock); sock = -1;
continue; continue;
} }
/*
int enable = 1; int enable = 1;
if(ioctl(sock, FIONBIO, (void *)&enable) < 0){ // make socket nonblocking if(ioctl(sock, FIONBIO, (void *)&enable) < 0){ // make socket nonblocking
LOGERR("Can't make socket nonblocking"); WARN("ioctl()");
ERRX("ioctl()"); LOGWARN("Can't make socket nonblocking");
} }
*/
}else{ }else{
if(connect(sock, p->ai_addr, p->ai_addrlen) == -1){ if(connect(sock, p->ai_addr, p->ai_addrlen) == -1){
LOGWARN("connect()");
WARN("connect()"); WARN("connect()");
LOGWARN("connect()");
close(sock); sock = -1; close(sock); sock = -1;
} }
} }
@ -121,27 +122,34 @@ int start_socket(int isserver, char *path, int isnet){
} }
// simple wrapper over write: add missed newline and log data // simple wrapper over write: add missed newline and log data
void sendmessage(int fd, const char *msg, int l){ int sendmessage(int fd, const char *msg, int l){
if(fd < 1 || !msg || l < 1) return; if(fd < 1 || !msg || l < 1) return TRUE; // empty message
static char *tmpbuf = NULL;
static int buflen = 0;
if(l + 1 > buflen){
buflen += 1024;
tmpbuf = realloc(tmpbuf, buflen);
}
DBG("send to fd %d: %s [%d]", fd, msg, l); DBG("send to fd %d: %s [%d]", fd, msg, l);
char *tmpbuf = MALLOC(char, l+1);
memcpy(tmpbuf, msg, l); memcpy(tmpbuf, msg, l);
if(msg[l-1] != '\n') tmpbuf[l++] = '\n'; if(msg[l-1] != '\n') tmpbuf[l++] = '\n';
if(l != write(fd, tmpbuf, l)){ if(l != send(fd, tmpbuf, l, MSG_NOSIGNAL)){
LOGWARN("write()");
WARN("write()"); WARN("write()");
LOGWARN("write()");
return FALSE;
}else{ }else{
DBG("success");
if(globlog){ // logging turned ON if(globlog){ // logging turned ON
tmpbuf[l-1] = 0; // remove trailing '\n' for logging tmpbuf[l-1] = 0; // remove trailing '\n' for logging
LOGDBG("SEND '%s'", tmpbuf); LOGDBG("SEND '%s'", tmpbuf);
} }
} }
FREE(tmpbuf); return TRUE;
} }
void sendstrmessage(int fd, const char *msg){ int sendstrmessage(int fd, const char *msg){
if(fd < 1 || !msg) return; if(fd < 1 || !msg) return FALSE;
int l = strlen(msg); int l = strlen(msg);
sendmessage(fd, msg, l); return sendmessage(fd, msg, l);
} }
// text messages for `hresult` // text messages for `hresult`
@ -165,7 +173,7 @@ const char *hresult2str(hresult r){
* @return `val` * @return `val`
*/ */
char *get_keyval(char *keyval){ char *get_keyval(char *keyval){
DBG("Got string %s", keyval); //DBG("Got string %s", keyval);
// remove starting spaces in key // remove starting spaces in key
while(isspace(*keyval)) ++keyval; while(isspace(*keyval)) ++keyval;
char *val = strchr(keyval, '='); char *val = strchr(keyval, '=');
@ -178,32 +186,49 @@ char *get_keyval(char *keyval){
while(isspace(*e) && e > keyval) --e; while(isspace(*e) && e > keyval) --e;
e[1] = 0; e[1] = 0;
// now we have key (`str`) and val (or NULL) // now we have key (`str`) and val (or NULL)
DBG("key=%s, val=%s", keyval, val); //DBG("key=%s, val=%s", keyval, val);
return val; return val;
} }
// parse string of data (command or key=val) // parse string of data (command or key=val)
// the CONTENT of buffer `str` WILL BE BROKEN! // the CONTENT of buffer `str` WILL BE BROKEN!
static void parsestring(int fd, handleritem *handlers, char *str){ // @return FALSE if client closed (nothing to read)
if(fd < 1 || !handlers || !handlers->key || !str || !*str) return; static int parsestring(int fd, handleritem *handlers, char *str){
if(fd < 1 || !handlers || !handlers->key || !str || !*str) return FALSE;
char *val = get_keyval(str); char *val = get_keyval(str);
if(val) LOGDBG("RECEIVE '%s=%s'", str, val); if(val){
else LOGDBG("RECEIVE '%s'", str); DBG("RECEIVE '%s=%s'", str, val);
LOGDBG("RECEIVE '%s=%s'", str, val);
}else{
DBG("RECEIVE '%s'", str);
LOGDBG("RECEIVE '%s'", str);
}
for(handleritem *h = handlers; h->key; ++h){ for(handleritem *h = handlers; h->key; ++h){
if(strcmp(str, h->key) == 0){ // found command if(strcmp(str, h->key) == 0){ // found command
pthread_mutex_lock(&locmutex);
hresult r = RESULT_OK; hresult r = RESULT_OK;
if(h->chkfunction) r = h->chkfunction(val); int l = 1;
if(h->chkfunction){
double t0 = dtime();
do{ l = pthread_mutex_trylock(&locmutex); }while(l && dtime() - t0 > BUSY_TIMEOUT);
if(l){
DBG("Can't lock mutex");
return RESULT_BUSY; // long blocking work
}
r = h->chkfunction(val);
} // else NULL instead of chkfuntion -> don't check and don't lock mutex
if(r == RESULT_OK){ // no test function or it returns TRUE if(r == RESULT_OK){ // no test function or it returns TRUE
if(h->handler) r = h->handler(fd, str, val); if(h->handler) r = h->handler(fd, str, val);
else r = RESULT_FAIL; else r = RESULT_FAIL;
} }
pthread_mutex_unlock(&locmutex); if(!l) pthread_mutex_unlock(&locmutex);
sendstrmessage(fd, hresult2str(r)); if(r == RESULT_DISCONNECTED){
return; DBG("handler return RESULT_DISCONNECTED");
return FALSE;
}
return sendstrmessage(fd, hresult2str(r));
} }
} }
sendstrmessage(fd, resmessages[RESULT_BADKEY]); return sendstrmessage(fd, resmessages[RESULT_BADKEY]);
} }
/** /**
@ -218,17 +243,20 @@ int processData(int fd, handleritem *handlers, char *buf, int buflen){
int curlen = strlen(buf); int curlen = strlen(buf);
if(curlen == buflen-1) curlen = 0; // buffer overflow - clear old content if(curlen == buflen-1) curlen = 0; // buffer overflow - clear old content
ssize_t rd = read(fd, buf + curlen, buflen-1 - curlen); ssize_t rd = read(fd, buf + curlen, buflen-1 - curlen);
if(rd <= 0) return FALSE; if(rd <= 0){
DBG("got %s[%zd] from %d", buf, rd, fd); //DBG("read %zd bytes from client", rd);
return FALSE;
}
//DBG("got %s[%zd] from %d", buf, rd, fd);
char *restofdata = buf, *eptr = buf + curlen + rd; char *restofdata = buf, *eptr = buf + curlen + rd;
*eptr = 0; *eptr = 0;
do{ do{
char *nl = strchr(restofdata, '\n'); char *nl = strchr(restofdata, '\n');
if(!nl) break; if(!nl) break;
*nl++ = 0; *nl++ = 0;
parsestring(fd, handlers, restofdata); if(!parsestring(fd, handlers, restofdata)) return FALSE; // client disconnected
restofdata = nl; restofdata = nl;
DBG("rest of data: %s", restofdata); //DBG("rest of data: %s", restofdata);
}while(1); }while(1);
if(restofdata != buf) memmove(buf, restofdata, eptr - restofdata + 1); if(restofdata != buf) memmove(buf, restofdata, eptr - restofdata + 1);
return TRUE; return TRUE;

View File

@ -20,6 +20,8 @@
#ifndef SERSOCK_H__ #ifndef SERSOCK_H__
#define SERSOCK_H__ #define SERSOCK_H__
#include <pthread.h>
// max & min TCP socket port number // max & min TCP socket port number
#define PORTN_MAX (65535) #define PORTN_MAX (65535)
#define PORTN_MIN (1024) #define PORTN_MIN (1024)
@ -28,6 +30,17 @@
// Max amount of connections // Max amount of connections
#define MAXCLIENTS (30) #define MAXCLIENTS (30)
// wait for mutex locking
#define BUSY_TIMEOUT (0.3)
// waiting for answer timeout
#define ANSWER_TIMEOUT (1.0)
// wait for exposition ends (between subsequent check calls)
#define WAIT_TIMEOUT (2.0)
// client will disconnect after this time from last server message
#define CLIENT_TIMEOUT (10.0)
extern pthread_mutex_t locmutex;
typedef enum{ typedef enum{
RESULT_OK, // all OK RESULT_OK, // all OK
RESULT_BUSY, // camera busy and no setters can be done RESULT_BUSY, // camera busy and no setters can be done
@ -35,6 +48,7 @@ typedef enum{
RESULT_BADVAL, // bad key's value RESULT_BADVAL, // bad key's value
RESULT_BADKEY, // bad key RESULT_BADKEY, // bad key
RESULT_SILENCE, // send nothing to client RESULT_SILENCE, // send nothing to client
RESULT_DISCONNECTED,// client disconnected
RESULT_NUM RESULT_NUM
} hresult; } hresult;
@ -50,8 +64,8 @@ typedef struct{
} handleritem; } handleritem;
int start_socket(int server, char *path, int isnet); int start_socket(int server, char *path, int isnet);
void sendmessage(int fd, const char *msg, int l); int sendmessage(int fd, const char *msg, int l);
void sendstrmessage(int fd, const char *msg); int sendstrmessage(int fd, const char *msg);
char *get_keyval(char *keyval); char *get_keyval(char *keyval);
int processData(int fd, handleritem *handlers, char *buf, int buflen); int processData(int fd, handleritem *handlers, char *buf, int buflen);