fixed some another bugs, but still have a lot

This commit is contained in:
Edward Emelianov 2023-04-11 16:31:10 +03:00
parent 38dee72b04
commit d3d1f33eac
7 changed files with 176 additions and 161 deletions

104
client.c
View File

@ -32,8 +32,10 @@
#include "socket.h"
static char sendbuf[BUFSIZ];
// send any message and wait any answer
// send message and wait any answer
#define SENDMSG(...) do{snprintf(sendbuf, BUFSIZ-1, __VA_ARGS__); verbose(2, "\t> %s", sendbuf); sendstrmessage(sock, sendbuf); getans(sock, NULL);}while(0)
// send message and wait answer starting with 'cmd'
#define SENDMSGW(cmd, ...) do{snprintf(sendbuf, BUFSIZ-1, cmd __VA_ARGS__); verbose(2, "\t> %s", sendbuf); sendstrmessage(sock, sendbuf); getans(sock, cmd);}while(0)
// send command and wait for answer on it
#define SENDCMDW(cmd) do{strncpy(sendbuf, cmd, BUFSIZ-1); verbose(2, "\t> %s", sendbuf); sendstrmessage(sock, sendbuf); getans(sock, cmd);}while(0)
static volatile atomic_int expstate = CAMERA_CAPTURE;
@ -143,59 +145,63 @@ static void send_headers(int sock){
if(GP->listdevices) SENDMSG(CMD_FOCLIST);
if(GP->focdevno > -1) SENDMSG(CMD_FDEVNO "=%d", GP->focdevno);
if(!isnan(GP->gotopos)){
SENDMSG(CMD_FGOTO "=%g", GP->gotopos);
SENDMSGW(CMD_FGOTO, "=%g", GP->gotopos);
}
// wheel
if(GP->listdevices) SENDMSG(CMD_WLIST);
if(GP->whldevno > -1) SENDMSG(CMD_WDEVNO "=%d", GP->whldevno);
if(GP->setwheel > -1) SENDMSG(CMD_WPOS "=%d", GP->setwheel);
if(GP->listdevices) SENDCMDW(CMD_WLIST);
if(GP->whldevno > -1) SENDMSGW(CMD_WDEVNO, "=%d", GP->whldevno);
if(GP->setwheel > -1) SENDMSGW(CMD_WPOS, "=%d", GP->setwheel);
DBG("nxt");
// CCD/CMOS
if(GP->X0 > -1 || GP->Y0 > -1 || GP->X1 > -1 || GP->Y1 > -1){ // set format
SENDMSG(CMD_FRAMEMAX);
SENDMSG(CMD_FRAMEFORMAT);
if(GP->X0 < 0) GP->X0 = xc0; // default values
if(GP->X0 > INT_MIN || GP->Y0 > INT_MIN || GP->X1 > INT_MIN || GP->Y1 > INT_MIN){ // set format
SENDCMDW(CMD_FRAMEMAX);
SENDCMDW(CMD_FRAMEFORMAT);
// default values
if(GP->X0 == INT_MIN) GP->X0 = xc0;
if(GP->X1 == INT_MIN) GP->X1 = xc1;
if(GP->Y0 == INT_MIN) GP->Y0 = yc0;
if(GP->Y1 == INT_MIN) GP->Y1 = yc1;
// limiting values
if(GP->X0 < 0) GP->X0 = xm0;
else if(GP->X0 > xm1-1) GP->X0 = xm1-1;
if(GP->Y0 < 0) GP->Y0 = yc0;
if(GP->Y0 < 0) GP->Y0 = ym0;
else if(GP->Y0 > ym1-1) GP->Y0 = ym1-1;
if(GP->X1 < GP->X0+1) GP->X1 = xc1;
else if(GP->X1 > xm1) GP->X1 = xm1;
if(GP->Y1 < GP->Y0+1) GP->Y1 = yc1;
else if(GP->Y1 > ym1) GP->Y1 = ym1;
if(GP->X1 < GP->X0+1 || GP->X1 > xm1) GP->X1 = xm1;
if(GP->Y1 < GP->Y0+1 || GP->Y1 > ym1) GP->Y1 = ym1;
DBG("set format: (%d,%d)x(%d,%d)", GP->X0,GP->X1,GP->Y0,GP->Y1);
SENDMSG(CMD_FRAMEFORMAT "=%d,%d,%d,%d", GP->X0, GP->Y0, GP->X1, GP->Y1);
SENDMSGW(CMD_FRAMEFORMAT, "=%d,%d,%d,%d", GP->X0, GP->Y0, GP->X1, GP->Y1);
}
if(GP->cancelexpose) SENDMSG(CMD_EXPSTATE "=%d", CAMERA_IDLE);
if(GP->listdevices) SENDMSG(CMD_CAMLIST);
if(GP->camdevno > -1) SENDMSG(CMD_CAMDEVNO "=%d", GP->camdevno);
if(GP->hbin) SENDMSG(CMD_HBIN "=%d", GP->hbin);
if(GP->vbin) SENDMSG(CMD_VBIN "=%d", GP->vbin);
if(!isnan(GP->temperature)) SENDMSG(CMD_CAMTEMPER "=%g", GP->temperature);
if(GP->shtr_cmd > -1) SENDMSG(CMD_SHUTTER "=%d", GP->shtr_cmd);
if(GP->confio > -1) SENDMSG(CMD_CONFIO "=%d", GP->confio);
if(GP->setio > -1) SENDMSG(CMD_IO "=%d", GP->setio);\
if(!isnan(GP->gain)) SENDMSG(CMD_GAIN "=%g", GP->gain);
if(!isnan(GP->brightness)) SENDMSG(CMD_BRIGHTNESS "=%g", GP->brightness);
if(GP->nflushes > 0) SENDMSG(CMD_NFLUSHES "=%d", GP->nflushes);
if(GP->cancelexpose) SENDMSGW(CMD_EXPSTATE, "=%d", CAMERA_IDLE);
if(GP->listdevices) SENDCMDW(CMD_CAMLIST);
if(GP->camdevno > -1) SENDMSGW(CMD_CAMDEVNO, "=%d", GP->camdevno);
if(GP->hbin) SENDMSGW(CMD_HBIN, "=%d", GP->hbin);
if(GP->vbin) SENDMSGW(CMD_VBIN, "=%d", GP->vbin);
if(!isnan(GP->temperature)) SENDMSGW(CMD_CAMTEMPER, "=%g", GP->temperature);
if(GP->shtr_cmd > -1) SENDMSGW(CMD_SHUTTER, "=%d", GP->shtr_cmd);
if(GP->confio > -1) SENDMSGW(CMD_CONFIO, "=%d", GP->confio);
if(GP->setio > -1) SENDMSGW(CMD_IO, "=%d", GP->setio);\
if(!isnan(GP->gain)) SENDMSGW(CMD_GAIN, "=%g", GP->gain);
if(!isnan(GP->brightness)) SENDMSGW(CMD_BRIGHTNESS, "=%g", GP->brightness);
if(GP->nflushes > 0) SENDMSGW(CMD_NFLUSHES, "=%d", GP->nflushes);
if(GP->outfile || GP->outfileprefix){ // exposition and reading control: only if start of exposition
if(GP->_8bit) SENDMSG(CMD_8BIT "=1");
else SENDMSG(CMD_8BIT "=0");
if(GP->fast) SENDMSG(CMD_FASTSPD "=1");
else SENDMSG(CMD_FASTSPD "=0");
if(GP->dark) SENDMSG(CMD_DARK "=1");
else SENDMSG(CMD_DARK "=0");
if(GP->_8bit) SENDMSGW(CMD_8BIT, "=1");
else SENDMSGW(CMD_8BIT, "=0");
if(GP->fast) SENDMSGW(CMD_FASTSPD, "=1");
else SENDMSGW(CMD_FASTSPD, "=0");
if(GP->dark) SENDMSGW(CMD_DARK, "=1");
else SENDMSGW(CMD_DARK, "=0");
}
if(GP->outfile){
if(!*GP->outfile) SENDMSG(CMD_FILENAME "=");
else SENDMSG(CMD_FILENAME "=%s", makeabspath(GP->outfile, FALSE));
if(GP->rewrite) SENDMSG(CMD_REWRITE "=1");
else SENDMSG(CMD_REWRITE "=0");
if(!*GP->outfile) SENDMSGW(CMD_FILENAME, "=");
else SENDMSGW(CMD_FILENAME, "=%s", makeabspath(GP->outfile, FALSE));
if(GP->rewrite) SENDMSGW(CMD_REWRITE, "=1");
else SENDMSGW(CMD_REWRITE, "=0");
}
if(GP->outfileprefix){
if(!*GP->outfileprefix) SENDMSG(CMD_FILENAMEPREFIX "=");
else SENDMSG(CMD_FILENAMEPREFIX "=%s", makeabspath(GP->outfileprefix, FALSE));
if(!*GP->outfileprefix) SENDMSGW(CMD_FILENAMEPREFIX, "=");
else SENDMSGW(CMD_FILENAMEPREFIX, "=%s", makeabspath(GP->outfileprefix, FALSE));
}
if(GP->exptime > -DBL_EPSILON) SENDMSG(CMD_EXPOSITION "=%g", GP->exptime);
if(GP->exptime > -DBL_EPSILON) SENDMSGW(CMD_EXPOSITION, "=%g", GP->exptime);
// FITS header keywords:
#define CHKHDR(x, cmd) do{if(x) SENDMSG(cmd "=%s", x);}while(0)
CHKHDR(GP->author, CMD_AUTHOR);
@ -216,13 +222,13 @@ static void send_headers(int sock){
int N = snprintf(ptr, L-1, "%s,", *sptr++);
L -= N; ptr += N;
}
SENDMSG(CMD_HEADERFILES "=%s", buf);
SENDMSGW(CMD_HEADERFILES, "=%s", buf);
}
}
void client(int sock){
if(GP->restart){
SENDMSG(CMD_RESTART);
SENDCMDW(CMD_RESTART);
return;
}
send_headers(sock);
@ -233,7 +239,7 @@ void client(int sock){
Nremain = GP->nframes - 1;
if(Nremain < 1) Nremain = 0;
else GP->waitexpend = TRUE; // N>1 - wait for exp ends
SENDMSG(CMD_EXPSTATE "=%d", CAMERA_CAPTURE);
SENDMSGW(CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
}else{
getans(sock, NULL);
DBG("RETURN: no more data");
@ -247,7 +253,7 @@ void client(int sock){
}
while(dtime() - t0 < timeout){
if(GP->waitexpend && dtime() - tw > WAIT_TIMEOUT){
SENDMSG(CMD_TREMAIN); // get remained time
SENDCMDW(CMD_TREMAIN); // get remained time
tw = dtime();
sprintf(sendbuf, "%s", CMD_EXPSTATE);
sendstrmessage(sock, sendbuf);
@ -266,7 +272,7 @@ void client(int sock){
if(GP->pause_len > 0){
double delta, time1 = dtime() + GP->pause_len;
while(1){
SENDMSG(CMD_CAMTEMPER);
SENDCMDW(CMD_CAMTEMPER);
if((delta = time1 - dtime()) < __FLT_EPSILON__) break;
// %d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n
if(delta > 1.) verbose(1, _("%d seconds till pause ends\n"), (int)delta);
@ -277,7 +283,7 @@ void client(int sock){
}
verbose(1, "Exposing frame %d...", ++nframe);
--Nremain;
SENDMSG(CMD_EXPSTATE "=%d", CAMERA_CAPTURE);
SENDMSGW(CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
}else{
GP->waitexpend = 0;
timeout = WAIT_TIMEOUT; // wait for last file name
@ -301,8 +307,8 @@ static void getimage(){
FNAME();
int sock = controlfd;
TIMESTAMP("Get image sizes");
SENDMSG(CMD_IMWIDTH);
SENDMSG(CMD_IMHEIGHT);
SENDCMDW(CMD_IMWIDTH);
SENDCMDW(CMD_IMHEIGHT);
int imsock = open_socket(FALSE, GP->imageport, TRUE);
if(imsock < 0) ERRX("getimage(): can't open image transport socket");
if(imbufsz < imdatalen){
@ -342,7 +348,7 @@ static void *grabnext(void _U_ *arg){ // daemon grabbing images through the net
expstate = CAMERA_CAPTURE;
TIMESTAMP("End of cycle, start new #%d", grabno+1);
TIMEINIT();
SENDMSG(CMD_EXPSTATE "=%d", CAMERA_CAPTURE); // start capture
SENDMSGW(CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); // start capture
double timeout = GP->exptime + CLIENT_TIMEOUT, t0 = dtime();
useconds_t sleept = 500000; // 0.5s
if(GP->exptime < 0.5){

View File

@ -18,8 +18,8 @@ static glob_pars G = {
.instrument = NULL,
.exptime = -1.,
.nframes = 0,
.X0 = -1, .Y0 = -1,
.X1 = -1, .Y1 = -1,
.X0 = INT_MIN, .Y0 = INT_MIN,
.X1 = INT_MIN, .Y1 = INT_MIN,
.focdevno = -1,
.camdevno = -1,
.whldevno = -1,

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-04-11 10:00+0300\n"
"POT-Creation-Date: 2023-04-11 14:57+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -478,12 +478,12 @@ msgstr ""
msgid "Can't set brightness to %g"
msgstr ""
#: ccdfunc.c:725 server.c:236
#: ccdfunc.c:725 server.c:251
#, c-format
msgid "Can't set binning %dx%d"
msgstr ""
#: ccdfunc.c:737 server.c:237
#: ccdfunc.c:737 server.c:252
msgid "Can't set given geometry"
msgstr ""
@ -529,7 +529,7 @@ msgstr ""
msgid "Capture frame %d"
msgstr ""
#: ccdfunc.c:783 ccdfunc.c:857 server.c:122
#: ccdfunc.c:783 ccdfunc.c:857 server.c:137
msgid "Can't start exposition"
msgstr ""
@ -546,7 +546,7 @@ msgid "Can't grab image"
msgstr ""
#. %d секунд до окончания паузы\n
#: ccdfunc.c:807 client.c:272
#: ccdfunc.c:807 client.c:278
#, c-format
msgid "%d seconds till pause ends\n"
msgstr ""
@ -555,15 +555,15 @@ msgstr ""
msgid "Some error when capture"
msgstr ""
#: server.c:170
#: server.c:185
msgid "No camera device"
msgstr ""
#: client.c:259
#: client.c:265
msgid "Can't make exposition"
msgstr ""
#: client.c:288
#: client.c:294
msgid "Server timeout"
msgstr ""

View File

@ -7,7 +7,7 @@
msgid ""
msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-04-11 09:57+0300\n"
"POT-Creation-Date: 2023-04-11 14:24+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -22,7 +22,7 @@ msgid "%.1f seconds till exposition ends"
msgstr "%.1f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ"
#. %d Ñ<>екунд до окончаниÑ<C2B8> паузы\n
#: ccdfunc.c:807 client.c:272
#: ccdfunc.c:807 client.c:278
#, c-format
msgid "%d seconds till pause ends\n"
msgstr "%d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n"
@ -117,7 +117,7 @@ msgstr "
msgid "Can't init mutex!"
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
#: client.c:259
#: client.c:265
msgid "Can't make exposition"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ÜËÓÐÏÚÉÃÉÀ"
@ -162,7 +162,7 @@ msgstr "
msgid "Can't set active wheel number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ"
#: ccdfunc.c:725 server.c:236
#: ccdfunc.c:725 server.c:251
#, c-format
msgid "Can't set binning %dx%d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d"
@ -190,7 +190,7 @@ msgstr "
msgid "Can't set gain to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
#: ccdfunc.c:737 server.c:237
#: ccdfunc.c:737 server.c:252
msgid "Can't set given geometry"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ"
@ -213,7 +213,7 @@ msgstr "
msgid "Can't set wheel position %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ %d"
#: ccdfunc.c:783 ccdfunc.c:857 server.c:122
#: ccdfunc.c:783 ccdfunc.c:857 server.c:137
msgid "Can't start exposition"
msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ"
@ -289,7 +289,7 @@ msgstr "
msgid "N flushes before exposing (default: 1)"
msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)"
#: server.c:170
#: server.c:185
msgid "No camera device"
msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ"
@ -323,7 +323,7 @@ msgstr "
msgid "Readout mode: %s"
msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s"
#: client.c:288
#: client.c:294
msgid "Server timeout"
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"

101
server.c
View File

@ -30,6 +30,8 @@
#include "server.h"
#include "socket.h"
static int processData(int fd, handleritem *handlers, char *buf, int buflen);
static atomic_int camdevno = 0, wheeldevno = 0, focdevno = 0; // current devices numbers
static _Atomic camera_state camstate = CAMERA_IDLE;
#define FLAG_STARTCAPTURE (1<<0)
@ -37,7 +39,6 @@ static _Atomic camera_state camstate = CAMERA_IDLE;
#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 frameformat frmformatmax = {0}, curformat = {0}; // maximal format
static void *camdev = NULL, *focdev = NULL, *wheeldev = NULL;
@ -97,6 +98,20 @@ strpair allcommands[] = {
{NULL, NULL},
};
static pthread_mutex_t locmutex = PTHREAD_MUTEX_INITIALIZER; // mutex for wheel/camera/focuser functions
// return TRUE if `locmutex` can be locked
static int lock(){
if(pthread_mutex_trylock(&locmutex)){
DBG("\n\nAlready locked");
return FALSE;
}
return TRUE;
}
static void unlock(){
if(pthread_mutex_unlock(&locmutex)) ERR("Can't unlock mutex");
}
static IMG ima = {0};
static void fixima(){
FNAME();
@ -176,7 +191,7 @@ static void* processCAM(_U_ void *d){
signals(1);
}
usleep(100);
if(0 == pthread_mutex_trylock(&locmutex)){
if(lock()){
// log
if(dtime() - logt > TLOG_PAUSE){
logt = dtime();
@ -206,7 +221,7 @@ static void* processCAM(_U_ void *d){
// do nothing: when `server` got this state it sends "expstate=3" to all clients and changes state to IDLE
break;
}
pthread_mutex_unlock(&locmutex);
unlock();
}
}
return NULL;
@ -354,7 +369,6 @@ static hresult nameprefixhandler(_U_ int fd, _U_ const char *key, const char *va
char *path = makeabspath(val, FALSE);
if(!path){
LOGERR("Can't create file '%s'", val);
//pthread_mutex_unlock(&locmutex);
return RESULT_BADVAL;
}
FREE(outfile);
@ -676,7 +690,6 @@ static hresult FITSheaderhandler(int fd, _U_ const char *key, const char *val){
FREE(*sptr++);
}
FREE(list);
//pthread_mutex_unlock(&locmutex);
return RESULT_BADVAL;
}
*lptr++ = strdup(newpath);
@ -958,8 +971,8 @@ static handleritem items[] = {
{chkcc, formathandler, CMD_FRAMEMAX},
{chkcc, nflusheshandler, CMD_NFLUSHES},
{chkcam, expstatehandler, CMD_EXPSTATE},
{NULL, imsizehandler, CMD_IMWIDTH},
{NULL, imsizehandler, CMD_IMHEIGHT},
{chktrue,imsizehandler, CMD_IMWIDTH},
{chktrue,imsizehandler, CMD_IMHEIGHT},
{chkcc, nameprefixhandler, CMD_FILENAMEPREFIX},
{chkcc, rewritefilehandler, CMD_REWRITE},
{chkcc, _8bithandler, CMD_8BIT},
@ -1125,3 +1138,77 @@ char *makeabspath(const char *path, int shouldbe){
if(unl) unlink(path);
return ret;
}
// parse string of data (command or key=val)
// the CONTENT of buffer `str` WILL BE BROKEN!
// @return FALSE if client closed (nothing to read)
static int parsestring(int fd, handleritem *handlers, char *str){
if(fd < 1 || !handlers || !handlers->key || !str || !*str) return FALSE;
char *val = get_keyval(str);
if(val){
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){
if(strcmp(str, h->key) == 0){ // found command
hresult r = RESULT_OK;
int l = FALSE;
if(h->chkfunction){
double t0 = dtime();
do{ l = lock(); } while(!l && dtime() - t0 < BUSY_TIMEOUT);
DBG("time: %g", dtime() - t0);
if(!l){
WARN("Can't lock mutex"); //signals(1);
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(h->handler) r = h->handler(fd, str, val);
else r = RESULT_FAIL;
}
if(l) unlock();
if(r == RESULT_DISCONNECTED){
DBG("handler return RESULT_DISCONNECTED");
return FALSE;
}
return sendstrmessage(fd, hresult2str(r));
}
}
DBG("Command not found!");
return sendstrmessage(fd, hresult2str(RESULT_BADKEY));
}
/**
* @brief processData - read (if available) data from fd and run processing, sending to fd messages for each command
* @param fd - socket file descriptor
* @param handlers - NULL-terminated array of handlers
* @param buf (io) - zero-terminated buffer for storing rest of data (without newline), its content will be changed
* @param buflen - its length
* @return FALSE if client closed (nothing to read)
*/
static int processData(int fd, handleritem *handlers, char *buf, int buflen){
int curlen = strlen(buf);
if(curlen == buflen-1) curlen = 0; // buffer overflow - clear old content
ssize_t rd = read(fd, buf + curlen, buflen-1 - curlen);
if(rd <= 0){
//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;
*eptr = 0;
do{
char *nl = strchr(restofdata, '\n');
if(!nl) break;
*nl++ = 0;
if(!parsestring(fd, handlers, restofdata)) return FALSE; // client disconnected
restofdata = nl;
//DBG("rest of data: %s", restofdata);
}while(1);
if(restofdata != buf) memmove(buf, restofdata, eptr - restofdata + 1);
return TRUE;
}

View File

@ -38,8 +38,6 @@
double __t0 = 0.;
#endif
pthread_mutex_t locmutex = PTHREAD_MUTEX_INITIALIZER; // mutex for wheel/camera/focuser functions
/**
* @brief open_socket - create socket and open it
* @param isserver - TRUE for server, FALSE for client
@ -187,7 +185,7 @@ int sendmessage(int fd, const char *msg, int l){
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);
memcpy(tmpbuf, msg, l);
if(msg[l-1] != '\n') tmpbuf[l++] = '\n';
if(l != send(fd, tmpbuf, l, MSG_NOSIGNAL)){
@ -248,79 +246,6 @@ char *get_keyval(char *keyval){
return val;
}
// parse string of data (command or key=val)
// the CONTENT of buffer `str` WILL BE BROKEN!
// @return FALSE if client closed (nothing to read)
static int parsestring(int fd, handleritem *handlers, char *str){
if(fd < 1 || !handlers || !handlers->key || !str || !*str) return FALSE;
char *val = get_keyval(str);
if(val){
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){
if(strcmp(str, h->key) == 0){ // found command
hresult r = RESULT_OK;
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(h->handler) r = h->handler(fd, str, val);
else r = RESULT_FAIL;
}
if(!l) pthread_mutex_unlock(&locmutex);
if(r == RESULT_DISCONNECTED){
DBG("handler return RESULT_DISCONNECTED");
return FALSE;
}
return sendstrmessage(fd, hresult2str(r));
}
}
DBG("Command not found!");
return sendstrmessage(fd, resmessages[RESULT_BADKEY]);
}
/**
* @brief processData - read (if available) data from fd and run processing, sending to fd messages for each command
* @param fd - socket file descriptor
* @param handlers - NULL-terminated array of handlers
* @param buf (io) - zero-terminated buffer for storing rest of data (without newline), its content will be changed
* @param buflen - its length
* @return FALSE if client closed (nothing to read)
*/
int processData(int fd, handleritem *handlers, char *buf, int buflen){
int curlen = strlen(buf);
if(curlen == buflen-1) curlen = 0; // buffer overflow - clear old content
ssize_t rd = read(fd, buf + curlen, buflen-1 - curlen);
if(rd <= 0){
//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;
*eptr = 0;
do{
char *nl = strchr(restofdata, '\n');
if(!nl) break;
*nl++ = 0;
if(!parsestring(fd, handlers, restofdata)) return FALSE; // client disconnected
restofdata = nl;
//DBG("rest of data: %s", restofdata);
}while(1);
if(restofdata != buf) memmove(buf, restofdata, eptr - restofdata + 1);
return TRUE;
}
/**
* check data from fd (polling function for client)
* @param fd - file descriptor

View File

@ -30,7 +30,7 @@
#define MAXCLIENTS (30)
// wait for mutex locking
#define BUSY_TIMEOUT (0.1)
#define BUSY_TIMEOUT (1.0)
// waiting for answer timeout
#define ANSWER_TIMEOUT (1.0)
// wait for exposition ends (between subsequent check calls)
@ -47,16 +47,14 @@ extern double __t0;
#define TIMESTAMP(...)
#endif
extern pthread_mutex_t locmutex;
typedef enum{
RESULT_OK, // all OK
RESULT_BUSY, // camera busy and no setters can be done
RESULT_FAIL, // failed running command
RESULT_BADVAL, // bad key's value
RESULT_BADKEY, // bad key
RESULT_SILENCE, // send nothing to client
RESULT_DISCONNECTED,// client disconnected
RESULT_OK, // 0: all OK
RESULT_BUSY, // 1: camera busy and no setters can be done
RESULT_FAIL, // 2: failed running command
RESULT_BADVAL, // 3: bad key's value
RESULT_BADKEY, // 4: bad key
RESULT_SILENCE, // 5: send nothing to client
RESULT_DISCONNECTED,// 6: client disconnected
RESULT_NUM
} hresult;
@ -78,5 +76,4 @@ int sendmessage(int fd, const char *msg, int l);
int sendstrmessage(int fd, const char *msg);
char *get_keyval(char *keyval);
int processData(int fd, handleritem *handlers, char *buf, int buflen);
int canberead(int fd);