From 290934f798e996a624e58902ba4bc36f0f088504 Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Tue, 22 Mar 2022 17:31:03 +0300 Subject: [PATCH] fix some little bugs, add some more functions, start testing on ZWO --- ccdfunc.c | 1 + client.c | 134 +++++++++++++--------- cmdlnopts.c | 5 +- cmdlnopts.h | 1 + locale/ru/messages.po | 32 +++--- locale/ru/ru.po | 32 +++--- main.c | 4 +- server.c | 260 +++++++++++++++++++++++------------------- server.h | 2 + socket.c | 19 +-- socket.h | 6 +- 11 files changed, 285 insertions(+), 211 deletions(-) diff --git a/ccdfunc.c b/ccdfunc.c index de448c7..8c15cba 100644 --- a/ccdfunc.c +++ b/ccdfunc.c @@ -748,6 +748,7 @@ void ccds(){ pthread_create(&mainwin->thread, NULL, &image_thread, (void*)&ima); } #endif + if(GP->nframes < 1) GP->nframes = 1; for(int j = 0; j < GP->nframes; ++j){ // %d\n verbose(1, _("Capture frame %d"), j); diff --git a/client.c b/client.c index 6d0092f..a8ad8fc 100644 --- a/client.c +++ b/client.c @@ -29,7 +29,8 @@ #include "socket.h" static char sendbuf[BUFSIZ]; -#define SENDMSG(...) do{snprintf(sendbuf, BUFSIZ-1, __VA_ARGS__); verbose(2, "%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; /** * check data from fd (polling function for client) @@ -61,30 +62,59 @@ static int canberead(int fd){ return 0; } -static char *getans(int sock){ - static char buf[BUFSIZ]; +static char *readmsg(int fd){ + static char buf[BUFSIZ] = {0}, line[BUFSIZ]; + int curlen = strlen(buf); + if(curlen == BUFSIZ-1) curlen = 0; // buffer overflow - clear old content + ssize_t rd = 0; + if(1 == canberead(fd)){ + rd = read(fd, buf + curlen, BUFSIZ-1 - curlen); + if(rd <= 0){ + WARNX("Server disconnected"); + signals(1); + } + } + curlen += rd; + buf[curlen] = 0; + if(curlen == 0) return NULL; + DBG("cur buffer: ----%s----", buf); + char *nl = strchr(buf, '\n'); + if(!nl) return NULL; + *nl++ = 0; + strcpy(line, buf); + int rest = curlen - (int)(nl-buf); + if(rest > 0) memmove(buf, nl, rest+1); + else *buf = 0; + return line; +} + +// parser of CCD server messages; return TRUE to exit from polling cycle of `getans` (if receive 'FAIL', 'OK' or 'BUSY') +static int parseans(char *ans){ + if(!ans) return FALSE; + if(0 == strcmp(hresult2str(RESULT_BUSY), ans)) ERRX("Server busy"); + if(0 == strcmp(hresult2str(RESULT_FAIL), 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 + if(0 == strcmp(CMD_EXPSTATE, ans)) expstate = atoi(val); + return FALSE; +} + +// read until timeout all messages from server; return FALSE if there was no messages from server +static int getans(int sock){ double t0 = dtime(); char *ans = NULL; while(dtime() - t0 < ANSWER_TIMEOUT){ - if(1 != canberead(sock)) continue; - int n = read(sock, buf, BUFSIZ-1); - if(n == 0){ - WARNX("Server disconnected"); - signals(1); - } - ans = buf; - buf[n] = 0; - DBG("Got from server: %s", buf); - verbose(1, "%s", buf); - if(buf[n-1] == '\n'){ - buf[n-1] = 0; - break; + char *s = readmsg(sock); + if(!s){ // buffer is empty, return last message or wait for it + if(ans) return TRUE; + else continue; } + ans = s; + DBG("Got from server: %s", ans); + verbose(1, "\t%s", ans); + if(parseans(ans)) break; } - if(0 == strcmp(hresult2str(RESULT_BUSY), buf)){ - ERRX("Server busy"); - } - return ans; + return ((ans) ? TRUE : FALSE); } /** @@ -156,6 +186,10 @@ static void process_data(int sock){ } void client(int sock){ + if(GP->restart){ + SENDMSG(CMD_RESTART); + return; + } process_data(sock); double t0 = dtime(), tw = t0; int Nremain = 0, nframe = 1; @@ -165,9 +199,12 @@ void client(int sock){ if(Nremain < 1) Nremain = 0; else GP->waitexpend = TRUE; // N>1 - wait for exp ends SENDMSG(CMD_EXPSTATE "=%d", CAMERA_CAPTURE); + } else { + getans(sock); + return; } double timeout = GP->waitexpend ? CLIENT_TIMEOUT : 0.1; - verbose(1, "Exposing frame 1"); + verbose(1, "Exposing frame 1..."); if(GP->waitexpend) verbose(2, "Wait for exposition end"); while(dtime() - t0 < timeout){ if(GP->waitexpend && dtime() - tw > WAIT_TIMEOUT){ @@ -176,39 +213,34 @@ void client(int sock){ sprintf(sendbuf, "%s", CMD_EXPSTATE); sendstrmessage(sock, sendbuf); } - char *ans = getans(sock); - if(ans){ + if(getans(sock)){ // got next portion of data t0 = dtime(); - char *val = get_keyval(ans); - if(val && 0 == strcmp(ans, CMD_EXPSTATE)){ - int state = atoi(val); - if(state == CAMERA_ERROR){ - WARNX(_("Can't make exposition")); - return; - } - if(state != CAMERA_CAPTURE){ - verbose(2, "Frame ready!"); - SENDMSG(CMD_LASTFNAME); - if(Nremain){ - if(GP->pause_len > 0){ - double delta, time1 = dtime() + GP->pause_len; - while(1){ - SENDMSG(CMD_CAMTEMPER); - if((delta = time1 - dtime()) < __FLT_EPSILON__) break; - // %d \n - 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)); - } + if(expstate == CAMERA_ERROR){ + WARNX(_("Can't make exposition")); + return; + } + if(expstate != CAMERA_CAPTURE){ + verbose(2, "Frame ready!"); + if(Nremain){ + verbose(1, "\n"); + if(GP->pause_len > 0){ + double delta, time1 = dtime() + GP->pause_len; + while(1){ + SENDMSG(CMD_CAMTEMPER); + if((delta = time1 - dtime()) < __FLT_EPSILON__) break; + // %d \n + if(delta > 1.) verbose(1, _("%d seconds till pause ends\n"), (int)delta); + if(delta > 6.) sleep(5); + else if(delta > 1.) sleep((int)delta); + else usleep((int)(delta*1e6 + 1)); } - verbose(1, "Exposing frame %d", ++nframe); - --Nremain; - SENDMSG(CMD_EXPSTATE "=%d", CAMERA_CAPTURE); - }else{ - GP->waitexpend = 0; - timeout = 0.2; // wait for last file name } + verbose(1, "Exposing frame %d...", ++nframe); + --Nremain; + SENDMSG(CMD_EXPSTATE "=%d", CAMERA_CAPTURE); + }else{ + GP->waitexpend = 0; + timeout = 0.2; // wait for last file name } } } diff --git a/cmdlnopts.c b/cmdlnopts.c index 3fc802e..86a68c3 100644 --- a/cmdlnopts.c +++ b/cmdlnopts.c @@ -18,7 +18,7 @@ glob_pars *GP = NULL; static glob_pars G = { .instrument = NULL, .exptime = -1., - .nframes = 1, + .nframes = 0, .X0 = -1, .Y0 = -1, .X1 = -1, .Y1 = -1, .focdevno = -1, @@ -49,7 +49,7 @@ myoption cmdlnopts[] = { {"focdevno",NEED_ARG, NULL, 0, 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 (each -v increase it)")}, + {"verbose", NO_ARGS, NULL, 'V', arg_none, APTR(&G.verbose), N_("verbose level (-V - messages, -VV - debug, -VVV - all shit)")}, {"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")}, @@ -101,6 +101,7 @@ myoption cmdlnopts[] = { {"port", NEED_ARG, NULL, 0, arg_string, APTR(&G.port), N_("local INET socket port")}, {"client", NO_ARGS, &G.client,1, arg_none, NULL, N_("run as client")}, {"pidfile", NEED_ARG, NULL, 0, arg_string, APTR(&G.pidfile), N_("PID file (default: " DEFAULT_PID_FILE ")")}, + {"restart", NO_ARGS, &G.restart,1, arg_none, NULL, N_("restart image server")}, #ifdef IMAGEVIEW {"display", NO_ARGS, NULL, 'D', arg_int, APTR(&G.showimage), N_("Display image in OpenGL window")}, diff --git a/cmdlnopts.h b/cmdlnopts.h index 2f5fb0a..833cc00 100644 --- a/cmdlnopts.h +++ b/cmdlnopts.h @@ -44,6 +44,7 @@ typedef struct{ char *port; // local INET socket port char *pidfile; // PID file (default: /tmp/CCD_Capture.pid) char **addhdr; // list of files from which to add header records + int restart; // restart server int waitexpend; // wait while exposition ends int cancelexpose; // cancel exp int client; // run as client diff --git a/locale/ru/messages.po b/locale/ru/messages.po index 1150899..fc50e3d 100644 --- a/locale/ru/messages.po +++ b/locale/ru/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-03-21 18:20+0300\n" +"POT-Creation-Date: 2022-03-22 17:17+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -58,7 +58,7 @@ msgid "rewrite output file if exists" msgstr "" #: cmdlnopts.c:52 -msgid "verbose level (each -v increase it)" +msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)" msgstr "" #: cmdlnopts.c:53 @@ -237,7 +237,11 @@ msgstr "" msgid "PID file (default: " msgstr "" -#: cmdlnopts.c:106 +#: cmdlnopts.c:104 +msgid "restart image server" +msgstr "" + +#: cmdlnopts.c:107 msgid "Display image in OpenGL window" msgstr "" @@ -469,12 +473,12 @@ msgstr "" msgid "Can't set brightness to %g" msgstr "" -#: ccdfunc.c:703 server.c:209 +#: ccdfunc.c:703 server.c:219 #, c-format msgid "Can't set binning %dx%d" msgstr "" -#: ccdfunc.c:713 server.c:210 +#: ccdfunc.c:713 server.c:220 msgid "Can't set given geometry" msgstr "" @@ -519,42 +523,42 @@ msgid "Can't open OpenGL window, image preview will be inaccessible" msgstr "" #. Захват кадра %d\n -#: ccdfunc.c:753 +#: ccdfunc.c:754 #, c-format msgid "Capture frame %d" msgstr "" -#: ccdfunc.c:755 server.c:118 +#: ccdfunc.c:756 server.c:120 msgid "Can't start exposition" msgstr "" -#: ccdfunc.c:759 ccdfunc.c:781 ccdfunc.c:822 +#: ccdfunc.c:760 ccdfunc.c:782 ccdfunc.c:823 msgid "Can't capture image" msgstr "" -#: ccdfunc.c:762 +#: ccdfunc.c:763 msgid "Read grabbed image" msgstr "" -#: ccdfunc.c:765 ccdfunc.c:785 ccdfunc.c:826 +#: ccdfunc.c:766 ccdfunc.c:786 ccdfunc.c:827 msgid "Can't grab image" msgstr "" #. %d секунд до окончания паузы\n -#: ccdfunc.c:802 client.c:199 +#: ccdfunc.c:803 client.c:232 #, c-format msgid "%d seconds till pause ends\n" msgstr "" -#: server.c:156 +#: server.c:161 msgid "No camera device" msgstr "" -#: client.c:186 +#: client.c:219 msgid "Can't make exposition" msgstr "" -#: client.c:216 +#: client.c:248 msgid "Server timeout" msgstr "" diff --git a/locale/ru/ru.po b/locale/ru/ru.po index 99262b3..d7e8449 100644 --- a/locale/ru/ru.po +++ b/locale/ru/ru.po @@ -7,7 +7,7 @@ msgid "" msgstr "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" - "POT-Creation-Date: 2022-03-21 18:20+0300\n" + "POT-Creation-Date: 2022-03-22 17:17+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -22,7 +22,7 @@ msgid "%.1f seconds till exposition ends" msgstr "" #. %d секунд до окончания паузы\n -#: ccdfunc.c:802 client.c:199 +#: ccdfunc.c:803 client.c:232 #, c-format msgid "%d seconds till pause ends\n" msgstr "" @@ -52,7 +52,7 @@ msgstr "" msgid "Camera model: %s" msgstr "" -#: ccdfunc.c:759 ccdfunc.c:781 ccdfunc.c:822 +#: ccdfunc.c:760 ccdfunc.c:782 ccdfunc.c:823 msgid "Can't capture image" msgstr "" @@ -105,7 +105,7 @@ msgstr "" msgid "Can't get max wheel position" msgstr "" -#: ccdfunc.c:765 ccdfunc.c:785 ccdfunc.c:826 +#: ccdfunc.c:766 ccdfunc.c:786 ccdfunc.c:827 msgid "Can't grab image" msgstr "" @@ -117,7 +117,7 @@ msgstr "" msgid "Can't init mutex!" msgstr "" -#: client.c:186 +#: client.c:219 msgid "Can't make exposition" msgstr "" @@ -162,7 +162,7 @@ msgstr "" msgid "Can't set active wheel number" msgstr "" -#: ccdfunc.c:703 server.c:209 +#: ccdfunc.c:703 server.c:219 #, c-format msgid "Can't set binning %dx%d" msgstr "" @@ -190,7 +190,7 @@ msgstr "" msgid "Can't set gain to %g" msgstr "" -#: ccdfunc.c:713 server.c:210 +#: ccdfunc.c:713 server.c:220 msgid "Can't set given geometry" msgstr "" @@ -213,17 +213,17 @@ msgstr "" msgid "Can't set wheel position %d" msgstr "" -#: ccdfunc.c:755 server.c:118 +#: ccdfunc.c:756 server.c:120 msgid "Can't start exposition" msgstr "" #. Захват кадра %d\n -#: ccdfunc.c:753 +#: ccdfunc.c:754 #, c-format msgid "Capture frame %d" msgstr "" -#: cmdlnopts.c:106 +#: cmdlnopts.c:107 msgid "Display image in OpenGL window" msgstr "" @@ -288,7 +288,7 @@ msgstr "" msgid "Neither filename nor filename prefix pointed!" msgstr "" -#: server.c:156 +#: server.c:161 msgid "No camera device" msgstr "" @@ -317,7 +317,7 @@ msgstr "" msgid "Pixel size: %g x %g" msgstr "" -#: ccdfunc.c:762 +#: ccdfunc.c:763 msgid "Read grabbed image" msgstr "" @@ -326,7 +326,7 @@ msgstr "" msgid "Readout mode: %s" msgstr "" -#: client.c:216 +#: client.c:248 msgid "Server timeout" msgstr "" @@ -521,6 +521,10 @@ msgstr "" msgid "program author" msgstr "" +#: cmdlnopts.c:104 +msgid "restart image server" +msgstr "" + #: cmdlnopts.c:51 msgid "rewrite output file if exists" msgstr "" @@ -566,7 +570,7 @@ msgid "show this help" msgstr "" #: cmdlnopts.c:52 -msgid "verbose level (each -v increase it)" +msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)" msgstr "" #: cmdlnopts.c:71 diff --git a/main.c b/main.c index 89e0263..1aaf02a 100644 --- a/main.c +++ b/main.c @@ -48,7 +48,7 @@ void signals(int signo){ return; } DBG("Master killed with sig=%d", signo); - LOGWARN("Master killed with sig=%d", signo); + LOGERR("Master killed with sig=%d", signo); if(!GP->client){ DBG("Unlink pid file"); unlink(GP->pidfile); @@ -129,7 +129,7 @@ int main(int argc, char **argv){ double t0 = dtime(); LOGMSG("Created child with pid %d", childpid); wait(NULL); - LOGWARN("Child %d died", childpid); + LOGERR("Child %d died", childpid); if(dtime() - t0 < 1.) pause += 5; else pause = 1; if(pause > 900) pause = 900; diff --git a/server.c b/server.c index 6b090ed..442c32d 100644 --- a/server.c +++ b/server.c @@ -34,9 +34,10 @@ static atomic_int camdevno = 0, wheeldevno = 0, focdevno = 0; // current devices static _Atomic camera_state camstate = CAMERA_IDLE; #define FLAG_STARTCAPTURE (1<<0) #define FLAG_CANCEL (1<<1) +#define FLAG_RESTARTSERVER (1<<2) static atomic_int camflags = 0, camfanspd = 0, confio = 0, nflushes; static char *outfile = NULL, *lastfile = NULL; // current output file name/prefix; last name of saved file -static pthread_mutex_t locmutex = PTHREAD_MUTEX_INITIALIZER; // mutex for wheel/camera/focuser functions +//static pthread_mutex_t locmutex = PTHREAD_MUTEX_INITIALIZER; // mutex for wheel/camera/focuser functions static frameformat frmformatmax = {0}, curformat = {0}; // maximal format static void *camdev = NULL, *focdev = NULL, *wheeldev = NULL; @@ -75,6 +76,7 @@ strpair allcommands[] = { { "info", "connected devices state" }, { "instrument", "FITS 'INSTRUME' field" }, { "io", "get/set camera IO" }, + { "lastfilename", "path to last saved file"}, { "maxformat", "camera maximal available format" }, { "nflushes", "camera number of preflushes" }, { "object", "FITS 'OBJECT' field" }, @@ -141,6 +143,7 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends else{ calculate_stat(&ima); if(saveFITS(&ima, &lastfile)){ + DBG("LAST file name changed"); camstate = CAMERA_FRAMERDY; return; } @@ -153,9 +156,16 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends // base camera thread static void* processCAM(_U_ void *d){ - if(!camera) ERRX(_("No camera device")); + if(!camera){ + LOGERR("No camera device"); + ERRX(_("No camera device")); + } double logt = 0; while(1){ + if(camflags & FLAG_RESTARTSERVER){ + LOGERR("User asks to restart"); + signals(1); + } // log if(dtime() - logt > TLOG_PAUSE){ logt = dtime(); @@ -192,10 +202,10 @@ static void* processCAM(_U_ void *d){ // functions running @ each devno change static int camdevini(int n){ if(!camera) return FALSE; - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); if(!camera->setDevNo(n)){ LOGERR("Can't set active camera number"); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return FALSE; } camdevno = n; @@ -208,45 +218,53 @@ static int camdevini(int n){ fixima(); 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")); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return TRUE; } static int focdevini(int n){ if(!focuser) return FALSE; - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); if(!focuser->setDevNo(n)){ LOGERR("Can't set active focuser number"); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return FALSE; } focdevno = n; LOGMSG("Set focuser device number to %d", focdevno); focuser->getMaxPos(&focmaxpos); focuser->getMinPos(&focminpos); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return TRUE; } static int wheeldevini(int n){ if(!wheel) return FALSE; - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!wheel->setDevNo(n)){ LOGERR("Can't set active wheel number"); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return FALSE; } wheeldevno = n; LOGMSG("Set wheel device number to %d", wheeldevno); wheel->getMaxPos(&wmaxpos); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return TRUE; } +/******************************************************************************* + *************************** Service handlers ********************************** + ******************************************************************************/ +static hresult restarthandler(_U_ int fd, _U_ const char *key, _U_ const char *val){ + camflags |= FLAG_RESTARTSERVER; + return RESULT_OK; +} + /******************************************************************************* *************************** CCD/CMOS handlers ********************************* ******************************************************************************/ static hresult camlisthandler(int fd, _U_ const char *key, _U_ const char *val){ char buf[BUFSIZ], modname[256]; - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); for(int i = 0; i < camera->Ndevices; ++i){ if(!camera->setDevNo(i)) continue; camera->getModelName(modname, 255); @@ -254,7 +272,7 @@ static hresult camlisthandler(int fd, _U_ const char *key, _U_ const char *val){ sendstrmessage(fd, buf); } if(camdevno > -1) camera->setDevNo(camdevno); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return RESULT_SILENCE; } static hresult camsetNhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){ @@ -276,13 +294,11 @@ static hresult exphandler(int fd, _U_ const char *key, const char *val){ if(val){ double v = atof(val); if(v < DBL_EPSILON) return RESULT_BADVAL; - if(camstate != CAMERA_CAPTURE){ - pthread_mutex_lock(&locmutex); - if(camera->setexp(v)){ - GP->exptime = v; - }else LOGWARN("Can't set exptime to %g", v); - pthread_mutex_unlock(&locmutex); - }else return RESULT_BUSY; + //pthread_mutex_lock(&locmutex); + if(camera->setexp(v)){ + GP->exptime = v; + }else LOGWARN("Can't set exptime to %g", v); + //pthread_mutex_unlock(&locmutex); } snprintf(buf, 63, CMD_EXPOSITION "=%g", GP->exptime); sendstrmessage(fd, buf); @@ -290,54 +306,54 @@ static hresult exphandler(int fd, _U_ const char *key, const char *val){ } // show last filename of saved FITS static hresult lastfnamehandler(int fd, _U_ const char *key, _U_ const char *val){ - char buf[PATH_MAX+1]; - pthread_mutex_lock(&locmutex); - snprintf(buf, PATH_MAX, CMD_LASTFNAME "=%s", lastfile); + char buf[PATH_MAX+32]; + //pthread_mutex_lock(&locmutex); + snprintf(buf, PATH_MAX+31, CMD_LASTFNAME "=%s", lastfile); sendstrmessage(fd, buf); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return RESULT_SILENCE; } // filename setter/getter static hresult namehandler(int fd, _U_ const char *key, const char *val){ - char buf[PATH_MAX+1]; + char buf[PATH_MAX+32]; if(val){ - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); char *path = makeabspath(val, FALSE); if(!path){ LOGERR("Can't create file '%s'", val); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return RESULT_BADVAL; } FREE(outfile); outfile = strdup(path); GP->outfile = outfile; GP->outfileprefix = NULL; - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); } if(!GP->outfile) return RESULT_FAIL; - snprintf(buf, PATH_MAX, CMD_FILENAME "=%s", GP->outfile); + snprintf(buf, PATH_MAX+31, CMD_FILENAME "=%s", GP->outfile); sendstrmessage(fd, buf); return RESULT_SILENCE; } // filename prefix static hresult nameprefixhandler(_U_ int fd, _U_ const char *key, const char *val){ - char buf[PATH_MAX+1]; + char buf[PATH_MAX+32]; if(val){ - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); char *path = makeabspath(val, FALSE); if(!path){ LOGERR("Can't create file '%s'", val); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return RESULT_BADVAL; } FREE(outfile); outfile = strdup(path); GP->outfileprefix = outfile; GP->outfile = NULL; - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); } if(!GP->outfileprefix) return RESULT_FAIL; - snprintf(buf, PATH_MAX, CMD_FILENAMEPREFIX "=%s", GP->outfileprefix); + snprintf(buf, PATH_MAX+31, CMD_FILENAMEPREFIX "=%s", GP->outfileprefix); sendstrmessage(fd, buf); return RESULT_SILENCE; } @@ -347,9 +363,9 @@ static hresult rewritefilehandler(_U_ int fd, _U_ const char *key, const char *v if(val){ int n = atoi(val); if(n < 0 || n > 1) return RESULT_BADVAL; - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); GP->rewrite = n; - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); } snprintf(buf, 63, CMD_REWRITE "=%d", GP->rewrite); sendstrmessage(fd, buf); @@ -362,17 +378,17 @@ static hresult binhandler(_U_ int fd, const char *key, const char *val){ if(b < 1) return RESULT_BADVAL; if(0 == strcmp(key, CMD_HBIN)) GP->hbin = b; else GP->vbin = b; - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); if(!camera->setbin(GP->hbin, GP->vbin)){ - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return RESULT_BADVAL; } fixima(); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); } - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); int r = camera->getbin(&GP->hbin, &GP->vbin); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(r){ if(0 == strcmp(key, CMD_HBIN)) snprintf(buf, 63, "%s=%d", key, GP->hbin); else snprintf(buf, 63, "%s=%d", key, GP->vbin); @@ -387,31 +403,31 @@ static hresult temphandler(_U_ int fd, _U_ const char *key, const char *val){ int r; if(val){ f = atof(val); - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); r = camera->setT((float)f); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!r){ LOGWARN("Can't set camera T to %.1f", f); return RESULT_FAIL; } LOGMSG("Set camera T to %.1f", f); } - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); r = camera->getTcold(&f); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(r){ snprintf(buf, 63, CMD_CAMTEMPER "=%.1f", f); sendstrmessage(fd, buf); - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); r = camera->getTbody(&f); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(r){ snprintf(buf, 63, "tbody=%.1f", f); sendstrmessage(fd, buf); } - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); r = camera->getThot(&f); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(r){ snprintf(buf, 63, "thot=%.1f", f); sendstrmessage(fd, buf); @@ -425,9 +441,9 @@ static hresult camfanhandler(_U_ int fd, _U_ const char *key, _U_ const char *va int spd = atoi(val); if(spd < 0) return RESULT_BADVAL; if(spd > FAN_HIGH) spd = FAN_HIGH; - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); int r = camera->setfanspeed((fan_speed)spd); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!r) return RESULT_FAIL; camfanspd = spd; } @@ -440,9 +456,9 @@ static hresult shutterhandler(_U_ int fd, _U_ const char *key, const char *val){ if(val){ int x = atoi(val); if(x < 0 || x >= SHUTTER_AMOUNT) return RESULT_BADVAL; - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); int r = camera->shuttercmd((shutter_op)x); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(r){ LOGMSG("Shutter command '%s'", shutterstr[x]); }else{ @@ -456,9 +472,9 @@ static hresult confiohandler(_U_ int fd, _U_ const char *key, _U_ const char *va char buf[64]; if(val){ int io = atoi(val); - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); int r = camera->confio(io); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!r) return RESULT_FAIL; confio = io; } @@ -471,14 +487,14 @@ static hresult iohandler(_U_ int fd, _U_ const char *key, _U_ const char *val){ int io; if(val){ io = atoi(val); - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); int r = camera->setio(io); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!r) return RESULT_FAIL; } - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); int r = camera->getio(&io); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!r) return RESULT_FAIL; snprintf(buf, 63, CMD_IO "=%d", io); sendstrmessage(fd, buf); @@ -489,14 +505,14 @@ static hresult gainhandler(_U_ int fd, _U_ const char *key, _U_ const char *val) float f; if(val){ f = atof(val); - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); int r = camera->setgain(f); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!r) return RESULT_FAIL; } - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); int r = camera->getgain(&f); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!r) return RESULT_FAIL; snprintf(buf, 63, CMD_GAIN "=%.1f", f); sendstrmessage(fd, buf); @@ -507,14 +523,14 @@ static hresult brightnesshandler(_U_ int fd, _U_ const char *key, _U_ const char float b; if(val){ b = atof(val); - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); int r = camera->setbrightness(b); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!r) return RESULT_FAIL; } - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); int r = camera->getbrightness(&b); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!r) return RESULT_FAIL; snprintf(buf, 63, CMD_BRIGHTNESS "=%.1f", b); sendstrmessage(fd, buf); @@ -529,9 +545,9 @@ static hresult formathandler(int fd, const char *key, const char *val){ 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; fmt.w -= fmt.xoff; fmt.h -= fmt.yoff; - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); int r = camera->setgeometry(&fmt); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!r) return RESULT_FAIL; curformat = fmt; fixima(); @@ -548,13 +564,13 @@ static hresult nflusheshandler(_U_ int fd, _U_ const char *key, _U_ const char * if(val){ int n = atoi(val); if(n < 1) return RESULT_BADVAL; - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); if(!camera->setnflushes(n)){ - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return RESULT_FAIL; } nflushes = n; - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); } snprintf(buf, 63, CMD_NFLUSHES "=%d", nflushes); sendstrmessage(fd, buf); @@ -653,7 +669,7 @@ static hresult FITSheaderhandler(int fd, _U_ const char *key, const char *val){ static int firstrun = 1; if(val){ int sz = 10, amount = 0; - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); // first we should check `val` char b2[BUFSIZ], *bptr = buf; snprintf(b2, BUFSIZ-1, "%s", val); @@ -675,7 +691,7 @@ static hresult FITSheaderhandler(int fd, _U_ const char *key, const char *val){ FREE(*sptr++); } FREE(list); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return RESULT_BADVAL; } *lptr++ = strdup(newpath); @@ -701,7 +717,7 @@ static hresult FITSheaderhandler(int fd, _U_ const char *key, const char *val){ FREE(curhdr); if(*val && *val != ',') curhdr = strdup(buf); DBG("curhdr now: %s", curhdr); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); } if(!curhdr && firstrun){ firstrun = 0; @@ -732,7 +748,7 @@ 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){ if(wheel->Ndevices < 1) return RESULT_FAIL; - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); for(int i = 0; i < wheel->Ndevices; ++i){ if(!wheel->setDevNo(i)) continue; char modname[256], buf[BUFSIZ]; @@ -741,7 +757,7 @@ static hresult wlisthandler(int fd, _U_ const char *key, _U_ const char *val){ sendstrmessage(fd, buf); } if(wheeldevno > -1) wheel->setDevNo(wheeldevno); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return RESULT_SILENCE; } static hresult wsetNhandler(int fd, _U_ const char *key, const char *val){ @@ -763,14 +779,14 @@ static hresult wgotohandler(_U_ int fd, _U_ const char *key, _U_ const char *val int pos; if(val){ pos = atoi(val); - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); int r = wheel->setPos(pos); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!r) return RESULT_BADVAL; } - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); int r = wheel->getPos(&pos); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!r) return RESULT_FAIL; snprintf(buf, 63, CMD_WPOS "=%d", pos); sendstrmessage(fd, buf); @@ -783,7 +799,7 @@ 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){ if(focuser->Ndevices < 1) return RESULT_FAIL; - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); for(int i = 0; i < focuser->Ndevices; ++i){ char modname[256], buf[BUFSIZ]; if(!focuser->setDevNo(i)) continue; @@ -792,7 +808,7 @@ static hresult foclisthandler(int fd, _U_ const char *key, _U_ const char *val){ sendstrmessage(fd, buf); } if(focdevno > -1) focuser->setDevNo(focdevno); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); return RESULT_SILENCE; } static hresult fsetNhandler(int fd, _U_ const char *key, const char *val){ @@ -815,18 +831,18 @@ static hresult fgotohandler(int fd, _U_ const char *key, const char *val){ if(val){ f = atof(val); if(f < focminpos || f > focmaxpos) return RESULT_BADVAL; - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); if(f - focminpos < __FLT_EPSILON__){ r = focuser->home(1); }else{ r = focuser->setAbsPos(1, f); } - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!r) return RESULT_FAIL; } - pthread_mutex_lock(&locmutex); + //pthread_mutex_lock(&locmutex); r = focuser->getPos(&f); - pthread_mutex_unlock(&locmutex); + //pthread_mutex_unlock(&locmutex); if(!r) return RESULT_FAIL; snprintf(buf, 63, CMD_FGOTO "=%g", f); sendstrmessage(fd, buf); @@ -852,6 +868,8 @@ static hresult infohandler(int fd, _U_ const char *key, _U_ const char *val){ binhandler(fd, CMD_VBIN, NULL); temphandler(fd, CMD_CAMTEMPER, NULL); exphandler(fd, CMD_EXPOSITION, NULL); + lastfnamehandler(fd, CMD_LASTFNAME, NULL); + expstatehandler(fd, CMD_EXPSTATE, NULL); } if(wheel){ if(wheel->getModelName(buf1, 255)){ @@ -903,31 +921,32 @@ static hresult helphandler(int fd, _U_ const char *key, _U_ const char *val){ // for setters: do nothing when camera not in idle state static int CAMbusy(){ - if(camera && camstate != CAMERA_IDLE) return TRUE; - return TRUE; + if(camera && camstate != CAMERA_IDLE){ + DBG("Camera busy"); + return TRUE; + } + return FALSE; } -static int chktrue(_U_ char *val){ - return TRUE; -} -static int chkcam(char *val){ +static hresult chkcam(char *val){ if(val && CAMbusy()) return RESULT_BUSY; - if(camera) return TRUE; - return FALSE; + if(camera) return RESULT_OK; + return RESULT_FAIL; } -static int chkwheel(char *val){ +static hresult chkwhl(char *val){ if(val && CAMbusy()) return RESULT_BUSY; - if(wheel) return TRUE; - return FALSE; + if(wheel) return RESULT_OK; + return RESULT_FAIL; } -static int chkfoc(char *val){ +static hresult chkfoc(char *val){ if(val && CAMbusy()) return RESULT_BUSY; - if(focuser) return TRUE; - return FALSE; + if(focuser) return RESULT_OK; + return RESULT_FAIL; } static handleritem items[] = { - {chktrue, infohandler, CMD_INFO}, - {chktrue, helphandler, CMD_HELP}, + {NULL, infohandler, CMD_INFO}, + {NULL, helphandler, CMD_HELP}, + {NULL, restarthandler, CMD_RESTART}, {chkcam, camlisthandler, CMD_CAMLIST}, {chkcam, camsetNhandler, CMD_CAMDEVNO}, {chkcam, camfanhandler, CMD_CAMFANSPD}, @@ -944,27 +963,27 @@ static handleritem items[] = { {chkcam, formathandler, CMD_FRAMEFORMAT}, {chkcam, formathandler, CMD_FRAMEMAX}, {chkcam, nflusheshandler, CMD_NFLUSHES}, - {chktrue, expstatehandler, CMD_EXPSTATE}, + {NULL, expstatehandler, CMD_EXPSTATE}, {chkcam, nameprefixhandler, CMD_FILENAMEPREFIX}, {chkcam, rewritefilehandler, CMD_REWRITE}, {chkcam, _8bithandler, CMD_8BIT}, {chkcam, fastspdhandler, CMD_FASTSPD}, {chkcam, darkhandler, CMD_DARK}, - {chktrue, tremainhandler, CMD_TREMAIN}, - {chktrue, FITSparhandler, CMD_AUTHOR}, - {chktrue, FITSparhandler, CMD_INSTRUMENT}, - {chktrue, FITSparhandler, CMD_OBSERVER}, - {chktrue, FITSparhandler, CMD_OBJECT}, - {chktrue, FITSparhandler, CMD_PROGRAM}, - {chktrue, FITSparhandler, CMD_OBJTYPE}, - {chktrue, FITSheaderhandler, CMD_HEADERFILES}, - {chktrue, lastfnamehandler, CMD_LASTFNAME}, + {NULL, tremainhandler, CMD_TREMAIN}, + {NULL, FITSparhandler, CMD_AUTHOR}, + {NULL, FITSparhandler, CMD_INSTRUMENT}, + {NULL, FITSparhandler, CMD_OBSERVER}, + {NULL, FITSparhandler, CMD_OBJECT}, + {NULL, FITSparhandler, CMD_PROGRAM}, + {NULL, FITSparhandler, CMD_OBJTYPE}, + {NULL, FITSheaderhandler, CMD_HEADERFILES}, + {NULL, lastfnamehandler, CMD_LASTFNAME}, {chkfoc, foclisthandler, CMD_FOCLIST}, {chkfoc, fsetNhandler, CMD_FDEVNO}, {chkfoc, fgotohandler, CMD_FGOTO}, - {chkwheel, wlisthandler, CMD_WLIST}, - {chkwheel, wsetNhandler, CMD_WDEVNO}, - {chkwheel, wgotohandler, CMD_WPOS}, + {chkwhl, wlisthandler, CMD_WLIST}, + {chkwhl, wsetNhandler, CMD_WDEVNO}, + {chkwhl, wgotohandler, CMD_WPOS}, {NULL, NULL, NULL}, }; @@ -1016,11 +1035,16 @@ void server(int sock){ } // process some data & send messages to ALL if(camstate == CAMERA_FRAMERDY || camstate == CAMERA_ERROR){ - char buff[32]; - snprintf(buff, 31, CMD_EXPSTATE "=%d", camstate); + char buff[PATH_MAX+32]; + snprintf(buff, PATH_MAX, CMD_EXPSTATE "=%d", camstate); DBG("Send %s to %d clients", buff, nfd - 1); for(int i = 1; i < nfd; ++i) sendstrmessage(poll_set[i].fd, buff); + if(camstate == CAMERA_FRAMERDY){ // send to all last file name + snprintf(buff, PATH_MAX+31, CMD_LASTFNAME "=%s", lastfile); + for(int i = 1; i < nfd; ++i) + sendstrmessage(poll_set[i].fd, buff); + } camstate = CAMERA_IDLE; } // scan connections diff --git a/server.h b/server.h index 676fe52..845158b 100644 --- a/server.h +++ b/server.h @@ -37,6 +37,8 @@ char *makeabspath(const char *path, int shouldbe); // common information about everything #define CMD_INFO "info" #define CMD_HELP "help" +// restart server +#define CMD_RESTART "restartTheServer" // CCD/CMOS #define CMD_CAMLIST "camlist" diff --git a/socket.c b/socket.c index 9fe16bb..170542e 100644 --- a/socket.c +++ b/socket.c @@ -18,6 +18,7 @@ #include // isspace #include +#include #include #include #include @@ -29,6 +30,8 @@ #include "server.h" #include "socket.h" +static pthread_mutex_t locmutex = PTHREAD_MUTEX_INITIALIZER; // mutex for wheel/camera/focuser functions + /** * @brief start_socket - create socket and run client or server * @param isserver - TRUE for server, FALSE for client @@ -152,7 +155,7 @@ static const char *resmessages[] = { }; const char *hresult2str(hresult r){ - if(r >= RESULT_NUM) return "BADRESULT"; + if(r < 0 || r >= RESULT_NUM) return "BADRESULT"; return resmessages[r]; } @@ -188,13 +191,15 @@ static void parsestring(int fd, handleritem *handlers, char *str){ else LOGDBG("RECEIVE '%s'", str); for(handleritem *h = handlers; h->key; ++h){ if(strcmp(str, h->key) == 0){ // found command - if(h->chkfunction && !h->chkfunction(val)) sendstrmessage(fd, resmessages[RESULT_FAIL]); - else{ - if(h->handler){ - hresult r = h->handler(fd, str, val); - sendstrmessage(fd, hresult2str(r)); - }else sendstrmessage(fd, resmessages[RESULT_FAIL]); + pthread_mutex_lock(&locmutex); + hresult r = RESULT_OK; + if(h->chkfunction) r = h->chkfunction(val); + if(r == RESULT_OK){ // no test function or it returns TRUE + if(h->handler) r = h->handler(fd, str, val); + else r = RESULT_FAIL; } + pthread_mutex_unlock(&locmutex); + sendstrmessage(fd, hresult2str(r)); return; } } diff --git a/socket.h b/socket.h index 2a0a4d1..5212aee 100644 --- a/socket.h +++ b/socket.h @@ -44,9 +44,9 @@ const char *hresult2str(hresult r); typedef hresult (*mesghandler)(int fd, const char *key, const char *val); typedef struct{ - int (*chkfunction)(char *val); // function to check device is ready - mesghandler handler; // handler function - const char *key; // keyword + hresult (*chkfunction)(char *val); // function to check device is ready + mesghandler handler; // handler function + const char *key; // keyword } handleritem; int start_socket(int server, char *path, int isnet);