mirror of
https://github.com/eddyem/CCD_Capture.git
synced 2025-12-06 02:35:13 +03:00
fix some network bugs; send image over other socket
This commit is contained in:
parent
8b6e7435e0
commit
070df2be89
@ -872,6 +872,7 @@ int ccdcaptured(IMG **imgptr){
|
||||
frameformat fmt = camera->geometry;
|
||||
int raw_width = fmt.w / GP->hbin, raw_height = fmt.h / GP->vbin;
|
||||
IMG *ima = NULL;
|
||||
if(*imgptr && ((*imgptr)->w != raw_width || (*imgptr)->h != raw_height)) FREE(*imgptr);
|
||||
if(!*imgptr){
|
||||
uint16_t *img = MALLOC(uint16_t, raw_width * raw_height);
|
||||
DBG("\n\nAllocated image 2x%dx%d=%d", raw_width, raw_height, 2 * raw_width * raw_height);
|
||||
|
||||
90
client.c
90
client.c
@ -19,6 +19,7 @@
|
||||
// client-side functions
|
||||
#include <stdatomic.h>
|
||||
#include <math.h> // isnan
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
@ -30,7 +31,10 @@
|
||||
#include "socket.h"
|
||||
|
||||
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)
|
||||
// send any 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 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;
|
||||
static int xm0,ym0,xm1,ym1; // max format
|
||||
static int xc0,yc0,xc1,yc1; // current format
|
||||
@ -41,36 +45,6 @@ static volatile atomic_int grabends = 0;
|
||||
static int imdatalen = 0, imbufsz = 0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* check data from fd (polling function for client)
|
||||
* @param fd - file descriptor
|
||||
* @return 0 in case of timeout, 1 in case of fd have data, -1 if error
|
||||
*/
|
||||
static int canberead(int fd){
|
||||
fd_set fds;
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 100;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
do{
|
||||
int rc = select(fd+1, &fds, NULL, NULL, &timeout);
|
||||
if(rc < 0){
|
||||
if(errno != EINTR){
|
||||
LOGWARN("select()");
|
||||
WARN("select()");
|
||||
return -1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}while(1);
|
||||
if(FD_ISSET(fd, &fds)){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *readmsg(int fd){
|
||||
static char buf[BUFSIZ] = {0}, line[BUFSIZ];
|
||||
int curlen = strlen(buf);
|
||||
@ -101,7 +75,10 @@ static char *readmsg(int fd){
|
||||
static int parseans(char *ans){
|
||||
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)){
|
||||
WARNX("Server busy");
|
||||
return FALSE;
|
||||
}
|
||||
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
|
||||
@ -130,7 +107,8 @@ static int parseans(char *ans){
|
||||
}
|
||||
|
||||
// read until timeout all messages from server; return FALSE if there was no messages from server
|
||||
static int getans(int sock){
|
||||
// if msg != NULL - wait for it in answer
|
||||
static int getans(int sock, const char *msg){
|
||||
double t0 = dtime();
|
||||
char *ans = NULL;
|
||||
while(dtime() - t0 < ANSWER_TIMEOUT){
|
||||
@ -143,7 +121,10 @@ static int getans(int sock){
|
||||
ans = s;
|
||||
DBG("Got from server: %s", ans);
|
||||
verbose(1, "\t%s", ans);
|
||||
if(parseans(ans)) break;
|
||||
if(parseans(ans)){
|
||||
if(msg && strncmp(ans, msg, strlen(msg))) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DBG("GETANS: timeout, ans: %s", ans);
|
||||
return ((ans) ? TRUE : FALSE);
|
||||
@ -251,8 +232,7 @@ void client(int sock){
|
||||
else GP->waitexpend = TRUE; // N>1 - wait for exp ends
|
||||
SENDMSG(CMD_EXPSTATE "=%d", CAMERA_CAPTURE);
|
||||
}else{
|
||||
double t0 = dtime();
|
||||
while(getans(sock) && dtime() - t0 < WAIT_TIMEOUT);
|
||||
getans(sock, NULL);
|
||||
DBG("RETURN: no more data");
|
||||
return;
|
||||
}
|
||||
@ -269,7 +249,7 @@ void client(int sock){
|
||||
sprintf(sendbuf, "%s", CMD_EXPSTATE);
|
||||
sendstrmessage(sock, sendbuf);
|
||||
}
|
||||
if(getans(sock)){ // got next portion of data
|
||||
if(getans(sock, NULL)){ // got next portion of data
|
||||
DBG("server message");
|
||||
t0 = dtime();
|
||||
if(expstate == CAMERA_ERROR){
|
||||
@ -307,18 +287,20 @@ void client(int sock){
|
||||
}
|
||||
|
||||
#ifdef IMAGEVIEW
|
||||
static int grabsockfd = -1;
|
||||
static int controlfd = -1;
|
||||
void init_grab_sock(int sock){
|
||||
grabsockfd = sock;
|
||||
if(sock < 0) ERRX("Can't run without command socket");
|
||||
controlfd = sock;
|
||||
send_headers(sock);
|
||||
}
|
||||
|
||||
static void getimage(){
|
||||
int sock = grabsockfd;
|
||||
FNAME();
|
||||
int sock = controlfd;
|
||||
SENDMSG(CMD_IMWIDTH);
|
||||
SENDMSG(CMD_IMHEIGHT);
|
||||
while(readmsg(sock)); // clear all incoming data
|
||||
sendstrmessage(sock, CMD_GETIMAGE); // ask for image
|
||||
int imsock = open_socket(FALSE, GP->imageport, TRUE);
|
||||
if(imsock < 0) ERRX("getimage(): can't open image transport socket");
|
||||
if(imbufsz < imdatalen){
|
||||
DBG("Reallocate memory from %d to %d", imbufsz, imdatalen);
|
||||
ima.data = realloc(ima.data, imdatalen);
|
||||
@ -327,9 +309,9 @@ static void getimage(){
|
||||
double t0 = dtime();
|
||||
int got = 0;
|
||||
while(dtime() - t0 < CLIENT_TIMEOUT){
|
||||
if(!canberead(sock)) continue;
|
||||
if(!canberead(imsock)) continue;
|
||||
uint8_t *target = ((uint8_t*)ima.data)+got;
|
||||
int rd = read(sock, target, imdatalen - got);
|
||||
int rd = read(imsock, target, imdatalen - got);
|
||||
if(rd <= 0){
|
||||
WARNX("Server disconnected");
|
||||
signals(1);
|
||||
@ -344,12 +326,13 @@ static void getimage(){
|
||||
}
|
||||
}
|
||||
if(dtime() - t0 > CLIENT_TIMEOUT) WARNX("Timeout, image didn't received");
|
||||
close(imsock);
|
||||
}
|
||||
|
||||
static void *grabnext(void _U_ *arg){ // daemon grabbing images through the net
|
||||
FNAME();
|
||||
if(grabsockfd < 0) return NULL;
|
||||
int sock = grabsockfd;
|
||||
if(controlfd < 0) return NULL;
|
||||
int sock = controlfd;
|
||||
while(1){
|
||||
DBG("WAIT");
|
||||
while(grabends); // wait until image processed
|
||||
@ -366,7 +349,7 @@ static void *grabnext(void _U_ *arg){ // daemon grabbing images through the net
|
||||
DBG("SLEEP!");
|
||||
usleep(sleept);
|
||||
//SENDMSG(CMD_EXPSTATE);
|
||||
getans(sock);
|
||||
getans(sock, NULL);
|
||||
DBG("EXPSTATE ===> %d", expstate);
|
||||
if(expstate != CAMERA_CAPTURE) break;
|
||||
}
|
||||
@ -382,16 +365,18 @@ static void *grabnext(void _U_ *arg){ // daemon grabbing images through the net
|
||||
|
||||
static void *waitimage(void _U_ *arg){ // passive waiting for next image
|
||||
FNAME();
|
||||
if(grabsockfd < 0) return NULL;
|
||||
int sock = grabsockfd;
|
||||
if(controlfd < 0) return NULL;
|
||||
int sock = controlfd;
|
||||
while(1){
|
||||
while(grabends); // wait until image processed
|
||||
getans(sock);
|
||||
getans(sock, NULL);
|
||||
if(expstate != CAMERA_FRAMERDY){
|
||||
usleep(1000);
|
||||
continue;
|
||||
}
|
||||
DBG("Image can be downloaded");
|
||||
getimage();
|
||||
expstate = CAMERA_IDLE;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -400,7 +385,7 @@ static void *waitimage(void _U_ *arg){ // passive waiting for next image
|
||||
int sockcaptured(IMG **imgptr){
|
||||
if(!imgptr) return FALSE;
|
||||
static pthread_t grabthread = 0;
|
||||
if(grabsockfd < 0) return FALSE;
|
||||
if(controlfd < 0) return FALSE;
|
||||
if(imgptr == (void*)-1){ // kill `grabnext`
|
||||
DBG("Wait for grabbing thread");
|
||||
if(grabthread){
|
||||
@ -411,7 +396,7 @@ int sockcaptured(IMG **imgptr){
|
||||
DBG("OK");
|
||||
return FALSE;
|
||||
}
|
||||
if(!grabthread){ // start new grab
|
||||
if(!grabthread || pthread_kill(grabthread, 0)){ // start new grab
|
||||
if(GP->viewer){
|
||||
DBG("\n\n\nStart new waiting");
|
||||
if(pthread_create(&grabthread, NULL, &waitimage, NULL)){
|
||||
@ -428,7 +413,6 @@ int sockcaptured(IMG **imgptr){
|
||||
}else{ // grab in process
|
||||
if(grabends){ // image is ready
|
||||
DBG("Image ready");
|
||||
grabthread = 0;
|
||||
if(*imgptr && (*imgptr != &ima)) free(*imgptr);
|
||||
*imgptr = &ima;
|
||||
grabends = 0;
|
||||
|
||||
@ -100,6 +100,7 @@ myoption cmdlnopts[] = {
|
||||
{"logfile", NEED_ARG, NULL, 0, arg_string, APTR(&G.logfile), N_("logging file name (if run as server)")},
|
||||
{"path", NEED_ARG, NULL, 0, arg_string, APTR(&G.path), N_("UNIX socket name")},
|
||||
{"port", NEED_ARG, NULL, 0, arg_string, APTR(&G.port), N_("local INET socket port")},
|
||||
{"imageport",NEED_ARG, NULL, 0, arg_string, APTR(&G.imageport), N_("local INET socket port to send/receive images")},
|
||||
{"client", NO_ARGS, &G.client,1, arg_none, NULL, N_("run as client")},
|
||||
{"viewer", NO_ARGS, &G.viewer,1, arg_none, NULL, N_("passive viewer (only get last images)")},
|
||||
{"pidfile", NEED_ARG, NULL, 0, arg_string, APTR(&G.pidfile), N_("PID file (default: " DEFAULT_PID_FILE ")")},
|
||||
|
||||
@ -38,6 +38,7 @@ typedef struct{
|
||||
char *logfile; // when run as server log here
|
||||
char *path; // UNIX socket name
|
||||
char *port; // local INET socket port
|
||||
char *imageport; // port to send/receive images (by default == port+1)
|
||||
char *pidfile; // PID file (default: /tmp/CCD_Capture.pid)
|
||||
char **addhdr; // list of files from which to add header records
|
||||
int restart; // restart server
|
||||
|
||||
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-04-04 18:42+0300\n"
|
||||
"POT-Creation-Date: 2023-04-05 18:17+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"
|
||||
@ -230,22 +230,26 @@ msgid "local INET socket port"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:103
|
||||
msgid "run as client"
|
||||
msgid "local INET socket port to send/receive images"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:104
|
||||
msgid "passive viewer (only get last images)"
|
||||
msgid "run as client"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:105
|
||||
msgid "PID file (default: "
|
||||
msgid "passive viewer (only get last images)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:106
|
||||
msgid "PID file (default: "
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:107
|
||||
msgid "restart image server"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:109
|
||||
#: cmdlnopts.c:110
|
||||
msgid "Display image in OpenGL window"
|
||||
msgstr ""
|
||||
|
||||
@ -478,12 +482,12 @@ msgstr ""
|
||||
msgid "Can't set brightness to %g"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:724 server.c:228
|
||||
#: ccdfunc.c:724 server.c:227
|
||||
#, c-format
|
||||
msgid "Can't set binning %dx%d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:736 server.c:229
|
||||
#: ccdfunc.c:736 server.c:228
|
||||
msgid "Can't set given geometry"
|
||||
msgstr ""
|
||||
|
||||
@ -529,7 +533,7 @@ msgstr ""
|
||||
msgid "Capture frame %d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:780 ccdfunc.c:832 server.c:123
|
||||
#: ccdfunc.c:780 ccdfunc.c:832 server.c:122
|
||||
msgid "Can't start exposition"
|
||||
msgstr ""
|
||||
|
||||
@ -546,20 +550,20 @@ msgid "Can't grab image"
|
||||
msgstr ""
|
||||
|
||||
#. %d секунд до окончания паузы\n
|
||||
#: ccdfunc.c:799 client.c:289
|
||||
#: ccdfunc.c:799 client.c:269
|
||||
#, c-format
|
||||
msgid "%d seconds till pause ends\n"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:166
|
||||
#: server.c:165
|
||||
msgid "No camera device"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:276
|
||||
#: client.c:256
|
||||
msgid "Can't make exposition"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:305
|
||||
#: client.c:285
|
||||
msgid "Server timeout"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
msgid ""
|
||||
msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-04-04 18:23+0300\n"
|
||||
"POT-Creation-Date: 2023-04-05 18:17+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:799 client.c:289
|
||||
#: ccdfunc.c:799 client.c:269
|
||||
#, 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:276
|
||||
#: client.c:256
|
||||
msgid "Can't make exposition"
|
||||
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ÜËÓÐÏÚÉÃÉÀ"
|
||||
|
||||
@ -162,7 +162,7 @@ msgstr "
|
||||
msgid "Can't set active wheel number"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ"
|
||||
|
||||
#: ccdfunc.c:724 server.c:228
|
||||
#: ccdfunc.c:724 server.c:227
|
||||
#, 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:736 server.c:229
|
||||
#: ccdfunc.c:736 server.c:228
|
||||
msgid "Can't set given geometry"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ"
|
||||
|
||||
@ -213,7 +213,7 @@ msgstr "
|
||||
msgid "Can't set wheel position %d"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ %d"
|
||||
|
||||
#: ccdfunc.c:780 ccdfunc.c:832 server.c:123
|
||||
#: ccdfunc.c:780 ccdfunc.c:832 server.c:122
|
||||
msgid "Can't start exposition"
|
||||
msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ"
|
||||
|
||||
@ -228,7 +228,7 @@ msgstr "
|
||||
msgid "Current format: %s"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:109
|
||||
#: cmdlnopts.c:110
|
||||
msgid "Display image in OpenGL window"
|
||||
msgstr "ïÔÏÂÒÁÖÅÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ × ÏËÎÅ OpenGL"
|
||||
|
||||
@ -289,7 +289,7 @@ msgstr "
|
||||
msgid "N flushes before exposing (default: 1)"
|
||||
msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)"
|
||||
|
||||
#: server.c:166
|
||||
#: server.c:165
|
||||
msgid "No camera device"
|
||||
msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ"
|
||||
|
||||
@ -309,7 +309,7 @@ msgstr "
|
||||
msgid "Only show statistics"
|
||||
msgstr "ôÏÌØËÏ ÏÔÏÂÒÁÚÉÔØ ÓÔÁÔÉÓÔÉËÕ"
|
||||
|
||||
#: cmdlnopts.c:105
|
||||
#: cmdlnopts.c:106
|
||||
msgid "PID file (default: "
|
||||
msgstr "PID-ÆÁÊÌ (ÐÏ ÕÍÏÌÞÁÎÉÀ: "
|
||||
|
||||
@ -327,7 +327,7 @@ msgstr "
|
||||
msgid "Readout mode: %s"
|
||||
msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s"
|
||||
|
||||
#: client.c:305
|
||||
#: client.c:285
|
||||
msgid "Server timeout"
|
||||
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
|
||||
|
||||
@ -460,6 +460,11 @@ msgstr "
|
||||
msgid "local INET socket port"
|
||||
msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ"
|
||||
|
||||
#: cmdlnopts.c:103
|
||||
#, fuzzy
|
||||
msgid "local INET socket port to send/receive images"
|
||||
msgstr "饉鹿 卿個景卦하 膽旽凜하 遝愾讀"
|
||||
|
||||
#: cmdlnopts.c:100
|
||||
msgid "logging file name (if run as server)"
|
||||
msgstr "ÉÍÑ ÆÁÊÌÁ ÌÏÇÇÉÒÏ×ÁÎÉÑ (ÅÓÌÉ ÚÁÐÕÝÅÎ ÓÅÒ×ÅÒ)"
|
||||
@ -521,7 +526,7 @@ msgstr "
|
||||
msgid "output file name"
|
||||
msgstr "ÉÍÑ ÆÁÊÌÁ"
|
||||
|
||||
#: cmdlnopts.c:104
|
||||
#: cmdlnopts.c:105
|
||||
msgid "passive viewer (only get last images)"
|
||||
msgstr ""
|
||||
|
||||
@ -529,7 +534,7 @@ msgstr ""
|
||||
msgid "program author"
|
||||
msgstr "Á×ÔÏÒ ÐÒÏÇÒÁÍÍÙ"
|
||||
|
||||
#: cmdlnopts.c:106
|
||||
#: cmdlnopts.c:107
|
||||
msgid "restart image server"
|
||||
msgstr "ÐÅÒÅÚÁÐÕÓË ÓÅÒ×ÅÒÁ"
|
||||
|
||||
@ -537,7 +542,7 @@ msgstr "
|
||||
msgid "rewrite output file if exists"
|
||||
msgstr "ÐÅÒÅÚÁÐÉÓØ ×ÙÈÏÄÎÏÇÏ ÆÁÊÌÁ"
|
||||
|
||||
#: cmdlnopts.c:103
|
||||
#: cmdlnopts.c:104
|
||||
msgid "run as client"
|
||||
msgstr "ÚÁÐÕÓÔÉÔØ ËÌÉÅÎÔ"
|
||||
|
||||
|
||||
12
main.c
12
main.c
@ -108,6 +108,12 @@ int main(int argc, char **argv){
|
||||
if(!GP->client) isserver = TRUE;
|
||||
}
|
||||
if(GP->path && !GP->client) isserver = TRUE;
|
||||
if((isserver || GP->client) && !GP->imageport){
|
||||
GP->imageport = MALLOC(char, 32);
|
||||
if(!GP->port) sprintf(GP->imageport, "12345");
|
||||
else snprintf(GP->imageport, 31, "%d", 1+atoi(GP->port));
|
||||
verbose(1, "Set image port to %s", GP->imageport);
|
||||
}
|
||||
if(GP->client && (GP->commondev || GP->focuserdev || GP->cameradev || GP->wheeldev))
|
||||
ERRX("Can't be client and standalone in same time!");
|
||||
if(GP->logfile){
|
||||
@ -134,8 +140,7 @@ int main(int argc, char **argv){
|
||||
wheels();
|
||||
camerainit = prepare_ccds();
|
||||
}else{ // client mode
|
||||
if(GP->path) return start_socket(isserver, GP->path, FALSE);
|
||||
if(GP->port) return start_socket(isserver, GP->port, TRUE);
|
||||
return start_socket(isserver);
|
||||
}
|
||||
#ifdef IMAGEVIEW
|
||||
if(GP->showimage){ // activate image vindow in capture or simple viewer mode
|
||||
@ -169,7 +174,6 @@ int main(int argc, char **argv){
|
||||
}
|
||||
#endif
|
||||
|
||||
if(GP->path) return start_socket(isserver, GP->path, FALSE);
|
||||
if(GP->port) return start_socket(isserver, GP->port, TRUE);
|
||||
return start_socket(isserver);
|
||||
}
|
||||
|
||||
|
||||
111
server.c
111
server.c
@ -70,7 +70,6 @@ strpair allcommands[] = {
|
||||
{ CMD_FGOTO, "focuser position" },
|
||||
{ CMD_FRAMEFORMAT, "camera frame format (X0,Y0,X1,Y1)" },
|
||||
{ CMD_GAIN, "camera gain" },
|
||||
{ CMD_GETIMAGE, "get image (binary data 2*w*h bytes)" },
|
||||
{ CMD_HBIN, "horizontal binning" },
|
||||
{ CMD_HEADERFILES, "add FITS records from these files (comma-separated list)" },
|
||||
{ CMD_HELP, "show this help" },
|
||||
@ -528,6 +527,7 @@ static hresult formathandler(int fd, const char *key, const char *val){
|
||||
int r = camera->setgeometry(&fmt);
|
||||
if(!r) return RESULT_FAIL;
|
||||
curformat = fmt;
|
||||
DBG("curformat: w=%d, h=%d", curformat.w, curformat.h);
|
||||
fixima();
|
||||
}
|
||||
if(0 == strcmp(key, CMD_FRAMEMAX)) snprintf(buf, 63, CMD_FRAMEMAX "=%d,%d,%d,%d",
|
||||
@ -886,14 +886,6 @@ static hresult helphandler(int fd, _U_ const char *key, _U_ const char *val){
|
||||
return RESULT_SILENCE;
|
||||
}
|
||||
|
||||
// sent to client last image
|
||||
static hresult imsendhandler(int fd, _U_ const char *key, _U_ const char *val){
|
||||
if(!ima.data || !ima.h || !ima.w) return RESULT_FAIL;
|
||||
// send image as raw data w*h*2
|
||||
if(!sendimage(fd, ima.data, 2*ima.h*ima.w)) return RESULT_DISCONNECTED;
|
||||
return RESULT_SILENCE;
|
||||
}
|
||||
|
||||
static hresult imsizehandler(int fd, const char *key, _U_ const char *val){
|
||||
char buf[64];
|
||||
// send image width/height in pixels
|
||||
@ -920,6 +912,10 @@ static hresult chkcam(char *val){
|
||||
if(camera) return RESULT_OK;
|
||||
return RESULT_FAIL;
|
||||
}
|
||||
static hresult chkcc(_U_ char *val){ // just check that camera connected
|
||||
if(camera) return RESULT_OK;
|
||||
return RESULT_FAIL;
|
||||
}
|
||||
static hresult chkwhl(char *val){
|
||||
if(val && CAMbusy()) return RESULT_BUSY;
|
||||
if(wheel) return RESULT_OK;
|
||||
@ -934,31 +930,30 @@ static handleritem items[] = {
|
||||
{chktrue,infohandler, CMD_INFO},
|
||||
{NULL, helphandler, CMD_HELP},
|
||||
{NULL, restarthandler, CMD_RESTART},
|
||||
{chkcam, camlisthandler, CMD_CAMLIST},
|
||||
{chkcam, camsetNhandler, CMD_CAMDEVNO},
|
||||
{chkcam, camfanhandler, CMD_CAMFANSPD},
|
||||
{chkcam, exphandler, CMD_EXPOSITION},
|
||||
{chkcam, namehandler, CMD_FILENAME},
|
||||
{chkcam, binhandler, CMD_HBIN},
|
||||
{chkcam, binhandler, CMD_VBIN},
|
||||
{chkcam, temphandler, CMD_CAMTEMPER},
|
||||
{chkcc, camlisthandler, CMD_CAMLIST},
|
||||
{chkcc, camsetNhandler, CMD_CAMDEVNO},
|
||||
{chkcc, camfanhandler, CMD_CAMFANSPD},
|
||||
{chkcc, exphandler, CMD_EXPOSITION},
|
||||
{chkcc, namehandler, CMD_FILENAME},
|
||||
{chkcc, binhandler, CMD_HBIN},
|
||||
{chkcc, binhandler, CMD_VBIN},
|
||||
{chkcc, temphandler, CMD_CAMTEMPER},
|
||||
{chkcam, shutterhandler, CMD_SHUTTER},
|
||||
{chkcam, confiohandler, CMD_CONFIO},
|
||||
{chkcam, iohandler, CMD_IO},
|
||||
{chkcam, gainhandler, CMD_GAIN},
|
||||
{chkcam, brightnesshandler, CMD_BRIGHTNESS},
|
||||
{chkcam, formathandler, CMD_FRAMEFORMAT},
|
||||
{chkcam, formathandler, CMD_FRAMEMAX},
|
||||
{chkcam, nflusheshandler, CMD_NFLUSHES},
|
||||
{NULL, expstatehandler, CMD_EXPSTATE},
|
||||
{NULL, imsendhandler, CMD_GETIMAGE},
|
||||
{chkcc, confiohandler, CMD_CONFIO},
|
||||
{chkcc, iohandler, CMD_IO},
|
||||
{chkcc, gainhandler, CMD_GAIN},
|
||||
{chkcc, brightnesshandler, CMD_BRIGHTNESS},
|
||||
{chkcc, formathandler, CMD_FRAMEFORMAT},
|
||||
{chkcc, formathandler, CMD_FRAMEMAX},
|
||||
{chkcc, nflusheshandler, CMD_NFLUSHES},
|
||||
{chkcam, expstatehandler, CMD_EXPSTATE},
|
||||
{NULL, imsizehandler, CMD_IMWIDTH},
|
||||
{NULL, imsizehandler, CMD_IMHEIGHT},
|
||||
{chkcam, nameprefixhandler, CMD_FILENAMEPREFIX},
|
||||
{chkcam, rewritefilehandler, CMD_REWRITE},
|
||||
{chkcam, _8bithandler, CMD_8BIT},
|
||||
{chkcam, fastspdhandler, CMD_FASTSPD},
|
||||
{chkcam, darkhandler, CMD_DARK},
|
||||
{chkcc, nameprefixhandler, CMD_FILENAMEPREFIX},
|
||||
{chkcc, rewritefilehandler, CMD_REWRITE},
|
||||
{chkcc, _8bithandler, CMD_8BIT},
|
||||
{chkcc, fastspdhandler, CMD_FASTSPD},
|
||||
{chkcc, darkhandler, CMD_DARK},
|
||||
{NULL, tremainhandler, CMD_TREMAIN},
|
||||
{NULL, FITSparhandler, CMD_AUTHOR},
|
||||
{NULL, FITSparhandler, CMD_INSTRUMENT},
|
||||
@ -979,7 +974,20 @@ static handleritem items[] = {
|
||||
|
||||
#define CLBUFSZ BUFSIZ
|
||||
|
||||
void server(int sock){
|
||||
void server(int sock, int imsock){
|
||||
DBG("sockfd=%d, imsockfd=%d", sock, imsock);
|
||||
if(sock < 0) ERRX("server(): need at least command socket fd");
|
||||
if(imsock < 0) WARNX("Server run without image transport support");
|
||||
else if(listen(imsock, MAXCLIENTS) == -1){
|
||||
WARN("listen()");
|
||||
LOGWARN("listen()");
|
||||
return;
|
||||
}
|
||||
if(listen(sock, MAXCLIENTS) == -1){
|
||||
WARN("listen()");
|
||||
LOGWARN("listen()");
|
||||
return;
|
||||
}
|
||||
// init everything
|
||||
startFocuser(&focdev);
|
||||
focdevini(0);
|
||||
@ -987,29 +995,45 @@ void server(int sock){
|
||||
wheeldevini(0);
|
||||
startCCD(&camdev);
|
||||
camdevini(0);
|
||||
if(listen(sock, MAXCLIENTS) == -1){
|
||||
WARN("listen");
|
||||
LOGWARN("listen");
|
||||
return;
|
||||
}
|
||||
// start camera thread
|
||||
pthread_t camthread;
|
||||
if(camera){
|
||||
if(pthread_create(&camthread, NULL, processCAM, NULL)) ERR("pthread_create()");
|
||||
}
|
||||
int nfd = 1; // only one socket @start
|
||||
struct pollfd poll_set[MAXCLIENTS+1];
|
||||
int nfd = 2; // only one socket @start
|
||||
struct pollfd poll_set[MAXCLIENTS+2];
|
||||
char buffers[MAXCLIENTS][CLBUFSZ]; // buffers for data reading
|
||||
bzero(poll_set, sizeof(poll_set));
|
||||
// ZERO - listening server socket
|
||||
poll_set[0].fd = sock;
|
||||
poll_set[0].events = POLLIN;
|
||||
poll_set[1].fd = imsock;
|
||||
poll_set[1].events = POLLIN;
|
||||
while(1){
|
||||
poll(poll_set, nfd, 1); // max timeout - 1ms
|
||||
//if(imsock > -1 && canberead(imsock) > 0){
|
||||
if(imsock > -1 && (poll_set[1].revents & POLLIN)){
|
||||
//uint8_t buf[32];
|
||||
//int l = read(imsock, buf, 32);
|
||||
DBG("Somebody wants an image");
|
||||
struct sockaddr_in addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
int client = accept(imsock, (struct sockaddr*)&addr, &len);
|
||||
DBG("client=%d", client);
|
||||
if(client > -1){
|
||||
DBG("client fd: %d", client);
|
||||
// send image as raw data w*h*2
|
||||
if(ima.data && ima.h > 0 && ima.w > 0)
|
||||
sendimage(client, ima.data, 2*ima.h*ima.w);
|
||||
close(client);
|
||||
DBG("%d closed", client);
|
||||
}else{WARN("accept()"); DBG("disconnected");}
|
||||
}
|
||||
if(poll_set[0].revents & POLLIN){ // check main for accept()
|
||||
struct sockaddr_in addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
int client = accept(sock, (struct sockaddr*)&addr, &len);
|
||||
if(client > -1){
|
||||
DBG("New connection");
|
||||
LOGMSG("SERVER got connection, fd=%d", client);
|
||||
if(nfd == MAXCLIENTS + 1){
|
||||
@ -1023,22 +1047,23 @@ void server(int sock){
|
||||
++nfd;
|
||||
}
|
||||
}
|
||||
}
|
||||
// process some data & send messages to ALL
|
||||
if(camstate == CAMERA_FRAMERDY || camstate == CAMERA_ERROR){
|
||||
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)
|
||||
DBG("Send %s to %d clients", buff, nfd - 2);
|
||||
for(int i = 2; 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)
|
||||
for(int i = 2; i < nfd; ++i)
|
||||
sendstrmessage(poll_set[i].fd, buff);
|
||||
}
|
||||
camstate = CAMERA_IDLE;
|
||||
}
|
||||
// scan connections
|
||||
for(int fdidx = 1; fdidx < nfd; ++fdidx){
|
||||
for(int fdidx = 2; fdidx < nfd; ++fdidx){
|
||||
if((poll_set[fdidx].revents & POLLIN) == 0) continue;
|
||||
int fd = poll_set[fdidx].fd;
|
||||
if(!processData(fd, items, buffers[fdidx-1], CLBUFSZ)){ // socket closed
|
||||
|
||||
4
server.h
4
server.h
@ -29,7 +29,7 @@ typedef enum{
|
||||
#define TLOG_PAUSE 60.
|
||||
|
||||
// server-side functions
|
||||
void server(int fd);
|
||||
void server(int fd, int imsock);
|
||||
char *makeabspath(const char *path, int shouldbe);
|
||||
|
||||
// common information about everything
|
||||
@ -37,8 +37,6 @@ char *makeabspath(const char *path, int shouldbe);
|
||||
#define CMD_HELP "help"
|
||||
// restart server
|
||||
#define CMD_RESTART "restartTheServer"
|
||||
// get last exposed image
|
||||
#define CMD_GETIMAGE "getimage"
|
||||
// get image size in pixels
|
||||
#define CMD_IMWIDTH "imwidth"
|
||||
#define CMD_IMHEIGHT "imheight"
|
||||
|
||||
71
socket.c
71
socket.c
@ -17,11 +17,13 @@
|
||||
*/
|
||||
|
||||
#include <ctype.h> // isspace
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/un.h> // unix socket
|
||||
#include <unistd.h>
|
||||
#include <usefull_macros.h>
|
||||
|
||||
#include "client.h"
|
||||
@ -35,13 +37,14 @@
|
||||
pthread_mutex_t locmutex = PTHREAD_MUTEX_INITIALIZER; // mutex for wheel/camera/focuser functions
|
||||
|
||||
/**
|
||||
* @brief start_socket - create socket and run client or server
|
||||
* @brief open_socket - create socket and open it
|
||||
* @param isserver - TRUE for server, FALSE for client
|
||||
* @param path - UNIX-socket path or local INET socket port
|
||||
* @param isnet - TRUE for INET socket, FALSE for UNIX
|
||||
* @return 0 if OK
|
||||
* @return socket FD or -1 if failed
|
||||
*/
|
||||
int start_socket(int isserver, char *path, int isnet){
|
||||
int open_socket(int isserver, char *path, int isnet){
|
||||
DBG("isserver=%d, path=%s, isnet=%d", isserver, path, isnet);
|
||||
if(!path) return 1;
|
||||
DBG("path/port: %s", path);
|
||||
int sock = -1;
|
||||
@ -89,6 +92,7 @@ int start_socket(int isserver, char *path, int isnet){
|
||||
close(sock); sock = -1;
|
||||
continue;
|
||||
}
|
||||
//fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||
if(bind(sock, p->ai_addr, p->ai_addrlen) == -1){
|
||||
WARN("bind()");
|
||||
LOGWARN("bind()");
|
||||
@ -111,13 +115,30 @@ int start_socket(int isserver, char *path, int isnet){
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(isnet) freeaddrinfo(res);
|
||||
return sock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief start_socket - create socket and run client or server
|
||||
* @param isserver - TRUE for server, FALSE for client
|
||||
* @return 0 if OK
|
||||
*/
|
||||
int start_socket(int isserver){
|
||||
char *path = NULL;
|
||||
int isnet = FALSE;
|
||||
if(GP->path) path = GP->path;
|
||||
else if(GP->port){ path = GP->port; isnet = TRUE; }
|
||||
else ERRX("Point network port or UNIX-socket path");
|
||||
int sock = open_socket(isserver, path, isnet), imsock = -1;
|
||||
if(sock < 0){
|
||||
LOGERR("Can't open socket");
|
||||
ERRX("Can't open socket");
|
||||
ERRX("start_socket(): can't open socket");
|
||||
}
|
||||
if(isnet) freeaddrinfo(res);
|
||||
if(isserver) server(sock);
|
||||
else{
|
||||
if(isserver){
|
||||
imsock = open_socket(TRUE, GP->imageport, TRUE);
|
||||
server(sock, imsock);
|
||||
}else{
|
||||
#ifdef IMAGEVIEW
|
||||
if(GP->showimage){
|
||||
if(!GP->viewer && GP->exptime < 0.00001) ERRX("Need exposition time!");
|
||||
@ -129,12 +150,16 @@ int start_socket(int isserver, char *path, int isnet){
|
||||
}
|
||||
DBG("Close socket");
|
||||
close(sock);
|
||||
if(isserver) signals(0);
|
||||
if(isserver){
|
||||
close(imsock);
|
||||
signals(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// send image data to client
|
||||
int sendimage(int fd, uint16_t *data, int l){
|
||||
DBG("fd=%d, l=%d", fd, l);
|
||||
if(fd < 1 || !data || l < 1) return TRUE; // empty message
|
||||
DBG("send new image (size=%d) to fd %d", l, fd);
|
||||
//strncpy((char*)data, "TEST image data\n", 17);
|
||||
@ -291,3 +316,33 @@ int processData(int fd, handleritem *handlers, char *buf, int buflen){
|
||||
if(restofdata != buf) memmove(buf, restofdata, eptr - restofdata + 1);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* check data from fd (polling function for client)
|
||||
* @param fd - file descriptor
|
||||
* @return 0 in case of timeout, 1 in case of fd have data, -1 if error
|
||||
*/
|
||||
int canberead(int fd){
|
||||
fd_set fds;
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 100;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
do{
|
||||
int rc = select(fd+1, &fds, NULL, NULL, &timeout);
|
||||
if(rc < 0){
|
||||
if(errno != EINTR){
|
||||
LOGWARN("select()");
|
||||
WARN("select()");
|
||||
return -1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}while(1);
|
||||
if(FD_ISSET(fd, &fds)){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
4
socket.h
4
socket.h
@ -61,10 +61,12 @@ typedef struct{
|
||||
const char *key; // keyword
|
||||
} handleritem;
|
||||
|
||||
int start_socket(int server, char *path, int isnet);
|
||||
int open_socket(int isserver, char *path, int isnet);
|
||||
int start_socket(int server);
|
||||
int sendimage(int fd, uint16_t *data, int l);
|
||||
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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user