diff --git a/Daemons/10micron_stellarium/libsofa.c b/Daemons/10micron_stellarium/libsofa.c
index b6f4b62..0015fbe 100644
--- a/Daemons/10micron_stellarium/libsofa.c
+++ b/Daemons/10micron_stellarium/libsofa.c
@@ -82,7 +82,7 @@ int get_MJDt(struct timeval *tval, sMJD *MJD){
struct tm tms;
double tSeconds;
if(!tval){
- DBG("MJD for current time");
+ //DBG("MJD for current time");
struct timeval currentTime;
gettimeofday(¤tTime, NULL);
gmtime_r(¤tTime.tv_sec, &tms);
@@ -102,11 +102,11 @@ int get_MJDt(struct timeval *tval, sMJD *MJD){
MJD->MJD = utc1 - 2400000.5 + utc2;
MJD->utc1 = utc1;
MJD->utc2 = utc2;
- DBG("UTC(m): %g, %.8f\n", utc1 - 2400000.5, utc2);
+ //DBG("UTC(m): %g, %.8f\n", utc1 - 2400000.5, utc2);
if(iauUtctai(utc1, utc2, &MJD->tai1, &MJD->tai2)) return -1;
- DBG("TAI");
+ //DBG("TAI");
if(iauTaitt(MJD->tai1, MJD->tai2, &MJD->tt1, &MJD->tt2)) return -1;
- DBG("TT");
+ //DBG("TT");
return 0;
}
diff --git a/Daemons/10micron_stellarium/main.c b/Daemons/10micron_stellarium/main.c
index 349cead..b0a9776 100644
--- a/Daemons/10micron_stellarium/main.c
+++ b/Daemons/10micron_stellarium/main.c
@@ -257,28 +257,29 @@ int proc_data(uint8_t *data, ssize_t len){
/**
* main socket service procedure
*/
-void handle_socket(int sock){
+void *handle_socket(void *sockd){
FNAME();
- if(global_quit) return;
+ if(global_quit) return NULL;
ssize_t rd;
outdata dout;
+ int sock = *(int*)sockd;
dout.len = htole16(sizeof(outdata));
dout.type = 0;
- dout.status = 0;
int (*getcoords)(double*, double*) = get_telescope_coords;
if(GP->emulation) getcoords = get_emul_coords;
while(!global_quit){
// get coordinates
double RA = 0., Decl = 0.;
- if(!getcoords(&RA, &Decl)){
+ if((dout.status = getcoords(&RA, &Decl)) < 0){
WARNX("Error: can't get coordinates");
- // continue;
+ sleep(1);
+ continue;
}
- DBG("got : %g/%g", RA, Decl);
+ //DBG("got : %g/%g", RA, Decl);
dout.ra = htole32(HRS2RA(RA));
dout.dec = (int32_t)htole32(DEG2DEC(Decl));
if(!send_data((uint8_t*)&dout, sizeof(outdata), sock)) break;
- DBG("sent ra = %g, dec = %g", RA2HRS(dout.ra), DEC2DEG(dout.dec));
+ //DBG("sent ra = %g, dec = %g", RA2HRS(dout.ra), DEC2DEG(dout.dec));
fd_set readfds;
struct timeval timeout;
FD_ZERO(&readfds);
@@ -307,6 +308,7 @@ void handle_socket(int sock){
else dout.status = 0;
}
close(sock);
+ return NULL;
}
static void *hdrthread(_U_ void *buf){
@@ -392,9 +394,18 @@ static inline void main_proc(){
close(newsock);
continue;
}*/
- handle_socket(newsock);
+ //handle_socket(newsock);
+ pthread_t rthrd;
+ if(pthread_create(&rthrd, NULL, handle_socket, (void*)&newsock)){
+ putlog("Error creating listen thread");
+ ERR(_("Can't create socket thread"));
+ }else{
+ DBG("Thread created, detouch");
+ pthread_detach(rthrd); // don't care about thread state
+
+ }
}
- pthread_cancel(hthrd); // cancel steppers' thread
+ pthread_cancel(hthrd); // cancel reading thread
pthread_join(hthrd, NULL);
close(sock);
}
diff --git a/Daemons/10micron_stellarium/telescope.c b/Daemons/10micron_stellarium/telescope.c
index 3822e71..88539c2 100644
--- a/Daemons/10micron_stellarium/telescope.c
+++ b/Daemons/10micron_stellarium/telescope.c
@@ -83,13 +83,13 @@ static char *read_string(){
static char *write_cmd(const char *cmd){
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&mutex);
- DBG("Write %s", cmd);
+ //DBG("Write %s", cmd);
if(write_tty(cmd, strlen(cmd))) return NULL;
double t0 = dtime();
static char *ans;
while(dtime() - t0 < T_POLLING_TMOUT){ // read answer
if((ans = read_string())){ // parse new data
- DBG("got answer: %s", ans);
+ // DBG("got answer: %s", ans);
pthread_mutex_unlock(&mutex);
return ans;
}
@@ -101,10 +101,8 @@ static char *write_cmd(const char *cmd){
// write to telescope mount corrections: datetime, pressure and temperature
static void makecorr(){
// write current date&time
- char buf[64], *ans;
-#ifdef EBUG
- write_cmd(":GUDT#");
-#endif
+ char buf[64], *ans;
+ DBG("curtime: %s", write_cmd(":GUDT#"));
write_cmd(":gT#"); // correct time by GPS
ans = write_cmd(":gtg#");
if(!ans || *ans != '1'){
@@ -113,16 +111,15 @@ static void makecorr(){
struct tm *stm = localtime(&t);
struct timeval tv;
gettimeofday(&tv,NULL);
- snprintf(buf, 64, ":SLDT%04d-%02d-%02d,%02d:%02d:%02d.%02ld#", 1900+stm->tm_year, stm->tm_mon, stm->tm_mday,
+ snprintf(buf, 64, ":SLDT%04d-%02d-%02d,%02d:%02d:%02d.%02ld#", 1900+stm->tm_year, stm->tm_mon+1, stm->tm_mday,
stm->tm_hour, stm->tm_min, stm->tm_sec, tv.tv_usec/10000);
+ DBG("write: %s", buf);
ans = write_cmd(buf);
if(!ans || *ans != '1'){
WARNX("Can't write current date/time");
putlog("Can't set system time");
}else putlog("Set system time by command %s", buf);
-#ifdef EBUG
- write_cmd(":GUDT#");
-#endif
+ DBG("curtime: %s", write_cmd(":GUDT#"));
}
placeWeather w;
if(getWeath(&w)) putlog("Can't determine weather data");
@@ -226,10 +223,11 @@ int point_telescope(double ra, double dec){
err = 2;
goto ret;
}
+ DBG("Move");
ans = write_cmd(":MS#");
if(!ans || *ans != '0'){
putlog("move error, answer: %s", ans);
- err = 2;
+ err = 3;
goto ret;
}
ret:
@@ -299,28 +297,26 @@ static int printhdr(int fd, const char *key, const char *val, const char *cmnt){
static double r = 0., d = 0.; // RA/DEC from wrhdr
+static int mountstatus = 0; // return of :Gstat#
static time_t tlast = 0; // last time coordinates were refreshed
/**
* get coordinates
* @param ra (o) - right ascension (hours)
* @param decl (o) - declination (degrees)
- * @return 1 if all OK
+ * @return telescope status or -1 if coordinates are too old
*/
int get_telescope_coords(double *ra, double *decl){
- if(time(NULL) - tlast > COORDS_TOO_OLD_TIME) return 0; // coordinates are too old
+ if(!tlast) tlast = time(NULL);
+ if(time(NULL) - tlast > COORDS_TOO_OLD_TIME) return -1; // coordinates are too old
if(ra) *ra = r;
if(decl) *decl = d;
- return 1;
+ return mountstatus;
}
void stop_telescope(){
- for(int i = 0; i < 3; ++i){
- if(write_cmd(":STOP#")){
- Target = 0;
- return;
- }
- }
- putlog("Can't send command STOP");
+ write_cmd(":RT9#"); // stop tracking
+ write_cmd(":STOP#"); // halt moving
+ Target = 0;
}
// site characteristics
@@ -366,6 +362,33 @@ static void getplace(){
}
}
+static const char *statuses[12] = {
+ [0] = "'Tracking'",
+ [1] = "'Going to stop'",
+ [2] = "'Slewing to park'",
+ [3] = "'Unparking'",
+ [4] = "'Slewing to home'",
+ [5] = "'Parked'",
+ [6] = "'Slewing or going to stop'",
+ [7] = "'Stopped'",
+ [8] = "'Motors inhibited, T too low'",
+ [9] = "'Outside tracking limit'",
+ [10]= "'Following satellite'",
+ [11]= "'Data inconsistency'"
+};
+
+/**
+ * @brief strstatus - return string explanation of mount status
+ * @param status - integer status code
+ * @return statically allocated string with explanation
+ */
+static const char* strstatus(int status){
+ if(status < 0) return "'Signal lost'";
+ if(status < (int)(sizeof(statuses)/sizeof(char*)-1)) return statuses[status];
+ if(status == 99) return "'Error'";
+ return "'Unknown status'";
+}
+
/**
* @brief wrhdr - try to write into header file
*/
@@ -411,6 +434,11 @@ void wrhdr(){
}
}
ans = write_cmd(":pS#"); pS = dups(ans, 1);
+ ans = write_cmd(":Gstat#");
+ if(ans){
+ mountstatus = atoi(ans);
+ //DBG("Status: %d", mountstatus);
+ }
#define WRHDR(k, v, c) do{if(printhdr(hdrfd, k, v, c)){close(hdrfd); return;}}while(0)
char val[22];
if(unlink(hdname)){
@@ -437,6 +465,7 @@ void wrhdr(){
WRHDR("RA", val, "Telescope right ascension, current epoch");
snprintf(val, 22, "%.10f", d);
WRHDR("DEC", val, "Telescope declination, current epoch");
+ WRHDR("TELSTAT", strstatus(mountstatus), "Telescope mount status");
sMJD mjd;
if(!get_MJDt(NULL, &mjd)){
snprintf(val, 22, "%.10f", 2000.+(mjd.MJD-MJD2000)/365.25); // calculate EPOCH/EQUINOX
diff --git a/Daemons/Readme.md b/Daemons/Readme.md
index 234d752..ad871f3 100644
--- a/Daemons/Readme.md
+++ b/Daemons/Readme.md
@@ -1,8 +1,9 @@
-Different daemons
-=================
+Different daemons @ tools
+=========================
- *10micron_stellarium* - simple daemon for 10-micron mount management from stellarium interface
- *domedaemon* - open/close dome by network query
- *netdaemon* - template for net-daemons
-- *teldaemon* - open/close Astrosib-500 scope covers by network query
- *netsocket* - scripts for management of network 220V-socket
+- *send_coordinates* - get/send coordinates to 10-micron mount through stellarium daemon
+- *teldaemon* - open/close Astrosib-500 scope covers by network query
diff --git a/Daemons/astrosib/HWoff b/Daemons/astrosib/HWoff
old mode 100755
new mode 100644
diff --git a/Daemons/astrosib/HWon b/Daemons/astrosib/HWon
old mode 100755
new mode 100644
diff --git a/Daemons/astrosib/STARTobs b/Daemons/astrosib/STARTobs
old mode 100755
new mode 100644
diff --git a/Daemons/astrosib/STOPobs b/Daemons/astrosib/STOPobs
old mode 100755
new mode 100644
diff --git a/Daemons/netsocket/HWpoweroff b/Daemons/netsocket/HWpoweroff
old mode 100644
new mode 100755
diff --git a/Daemons/netsocket/HWpoweron b/Daemons/netsocket/HWpoweron
old mode 100644
new mode 100755
diff --git a/Daemons/netsocket/MOUNTpoweronoff b/Daemons/netsocket/MOUNTpoweronoff
old mode 100644
new mode 100755
diff --git a/Daemons/send_coordinates/Makefile b/Daemons/send_coordinates/Makefile
new file mode 100644
index 0000000..e41fd9c
--- /dev/null
+++ b/Daemons/send_coordinates/Makefile
@@ -0,0 +1,43 @@
+# run `make DEF=...` to add extra defines
+PROGRAM := send_coords
+LDFLAGS := -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all
+LDFLAGS += -lusefull_macros
+SRCS := $(wildcard *.c)
+DEFINES := $(DEF) -D_GNU_SOURCE -D_XOPEN_SOURCE=1111
+OBJDIR := mk
+CFLAGS += -O2 -Wno-trampolines -std=gnu99
+OBJS := $(addprefix $(OBJDIR)/, $(SRCS:%.c=%.o))
+DEPS := $(OBJS:.o=.d)
+CC = gcc
+#CXX = g++
+
+
+all : $(OBJDIR) $(PROGRAM)
+
+debug: CFLAGS += -DEBUG -Werror -Wall -Wextra -W
+debug: all
+
+$(PROGRAM) : $(OBJS)
+ @echo -e "\t\tLD $(PROGRAM)"
+ $(CC) $(LDFLAGS) $(OBJS) -o $(PROGRAM)
+
+$(OBJDIR):
+ mkdir $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+-include $(DEPS)
+endif
+
+$(OBJDIR)/%.o: %.c
+ @echo -e "\t\tCC $<"
+ $(CC) -MD -c $(LDFLAGS) $(CFLAGS) $(DEFINES) -o $@ $<
+
+clean:
+ @echo -e "\t\tCLEAN"
+ @rm -f $(OBJS) $(DEPS)
+ @rmdir $(OBJDIR) 2>/dev/null || true
+
+xclean: clean
+ @rm -f $(PROGRAM)
+
+.PHONY: clean xclean
diff --git a/Daemons/send_coordinates/Readme b/Daemons/send_coordinates/Readme
new file mode 100644
index 0000000..0f1b925
--- /dev/null
+++ b/Daemons/send_coordinates/Readme
@@ -0,0 +1 @@
+A simple tool to send/receive coordinates from telescope
diff --git a/Daemons/send_coordinates/SendCoords.config b/Daemons/send_coordinates/SendCoords.config
new file mode 100644
index 0000000..e0284f4
--- /dev/null
+++ b/Daemons/send_coordinates/SendCoords.config
@@ -0,0 +1,2 @@
+// Add predefined macros for your project here. For example:
+// #define THE_ANSWER 42
diff --git a/Daemons/send_coordinates/SendCoords.creator b/Daemons/send_coordinates/SendCoords.creator
new file mode 100644
index 0000000..e94cbbd
--- /dev/null
+++ b/Daemons/send_coordinates/SendCoords.creator
@@ -0,0 +1 @@
+[General]
diff --git a/Daemons/send_coordinates/SendCoords.creator.user b/Daemons/send_coordinates/SendCoords.creator.user
new file mode 100644
index 0000000..075bf79
--- /dev/null
+++ b/Daemons/send_coordinates/SendCoords.creator.user
@@ -0,0 +1,167 @@
+
+
+
+
+
+ EnvironmentId
+ {cf63021e-ef53-49b0-b03b-2f2570cdf3b6}
+
+
+ ProjectExplorer.Project.ActiveTarget
+ 0
+
+
+ ProjectExplorer.Project.EditorSettings
+
+ true
+ false
+ true
+
+ Cpp
+
+ CppGlobal
+
+
+
+ QmlJS
+
+ QmlJSGlobal
+
+
+ 2
+ KOI8-R
+ false
+ 4
+ false
+ 80
+ true
+ true
+ 1
+ false
+ false
+ 1
+ true
+ true
+ 0
+ 8
+ true
+ 2
+ true
+ true
+ true
+ true
+
+
+
+ ProjectExplorer.Project.PluginSettings
+
+
+
+ ProjectExplorer.Project.Target.0
+
+ Desktop
+ Desktop
+ {91347f2c-5221-46a7-80b1-0a054ca02f79}
+ 0
+ 0
+ 0
+
+ /tmp/as/Doc/C-sources/send_coordinates
+
+
+
+ all
+
+ false
+
+
+ false
+ true
+ Сборка
+
+ GenericProjectManager.GenericMakeStep
+
+ 1
+ Сборка
+
+ ProjectExplorer.BuildSteps.Build
+
+
+
+
+ clean
+
+ false
+
+
+ false
+ true
+ Сборка
+
+ GenericProjectManager.GenericMakeStep
+
+ 1
+ Очистка
+
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ По умолчанию
+ По умолчанию
+ GenericProjectManager.GenericBuildConfiguration
+
+ 1
+
+
+ 0
+ Установка
+
+ ProjectExplorer.BuildSteps.Deploy
+
+ 1
+ Конфигурация установки
+
+ ProjectExplorer.DefaultDeployConfiguration
+
+ 1
+
+
+ false
+ false
+ 1000
+
+ true
+ 2
+
+
+ Особая программа
+
+ ProjectExplorer.CustomExecutableRunConfiguration
+
+ 3768
+ false
+ true
+ false
+ false
+ true
+
+
+
+ 1
+
+
+
+ ProjectExplorer.Project.TargetCount
+ 1
+
+
+ ProjectExplorer.Project.Updater.FileVersion
+ 20
+
+
+ Version
+ 20
+
+
diff --git a/Daemons/send_coordinates/SendCoords.files b/Daemons/send_coordinates/SendCoords.files
new file mode 100644
index 0000000..9b614da
--- /dev/null
+++ b/Daemons/send_coordinates/SendCoords.files
@@ -0,0 +1,5 @@
+cmdlnopts.c
+cmdlnopts.h
+main.c
+stelldaemon.c
+stelldaemon.h
diff --git a/Daemons/send_coordinates/SendCoords.includes b/Daemons/send_coordinates/SendCoords.includes
new file mode 100644
index 0000000..9c558e3
--- /dev/null
+++ b/Daemons/send_coordinates/SendCoords.includes
@@ -0,0 +1 @@
+.
diff --git a/Daemons/send_coordinates/cmdlnopts.c b/Daemons/send_coordinates/cmdlnopts.c
new file mode 100644
index 0000000..4ada3fa
--- /dev/null
+++ b/Daemons/send_coordinates/cmdlnopts.c
@@ -0,0 +1,92 @@
+/*
+ * This file is part of the SendCoords project.
+ * Copyright 2020 Edward V. Emelianov .
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include "cmdlnopts.h"
+#include "usefull_macros.h"
+
+/*
+ * here are global parameters initialisation
+ */
+static int help;
+static glob_pars G;
+
+#define DEFAULT_PIDFILE "/tmp/sendcoords.pid"
+#define DEFAULT_PORT "10000"
+#define DEFAULT_HOST "localhost"
+
+// DEFAULTS
+// default global parameters
+static glob_pars const Gdefault = {
+ .pidfile = DEFAULT_PIDFILE,
+ .port = DEFAULT_PORT,
+ .host = DEFAULT_HOST,
+};
+
+/*
+ * Define command line options by filling structure:
+ * name has_arg flag val type argptr help
+*/
+static myoption cmdlnopts[] = {
+// common options
+ {"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")},
+ {"pidfile", NEED_ARG, NULL, 'p', arg_string, APTR(&G.pidfile), _("pidfile (default: " DEFAULT_PIDFILE ")")},
+ {"port", NEED_ARG, NULL, 'P', arg_string, APTR(&G.port), _("port to connect (default: " DEFAULT_PORT ")")},
+ {"host", NEED_ARG, NULL, 'H', arg_string, APTR(&G.host), _("host to connect (default: " DEFAULT_HOST ")")},
+ {"ra", NEED_ARG, NULL, 'r', arg_string, APTR(&G.ra), _("target RA: HH:MM:SS.SS")},
+ {"dec", NEED_ARG, NULL, 'd', arg_string, APTR(&G.dec), _("target DEC: [+-]DD:MM:SS.SS")},
+ {"quiet", NO_ARGS, NULL, 'q', arg_none, APTR(&G.quiet), _("suppress all messages to stdout")},
+ {"monitor", NO_ARGS, NULL, 'm', arg_none, APTR(&G.monitor), _("monitor coordinates")},
+ end_option
+};
+
+/**
+ * Parse command line options and return dynamically allocated structure
+ * to global parameters
+ * @param argc - copy of argc from main
+ * @param argv - copy of argv from main
+ * @return allocated structure with global parameters
+ */
+glob_pars *parse_args(int argc, char **argv){
+ int i;
+ void *ptr;
+ ptr = memcpy(&G, &Gdefault, sizeof(G)); assert(ptr);
+ size_t hlen = 1024;
+ char helpstring[1024], *hptr = helpstring;
+ snprintf(hptr, hlen, "Usage: %%s [args]\n\n\tWhere args are:\n");
+ // format of help: "Usage: progname [args]\n"
+ change_helpstring(helpstring);
+ // parse arguments
+ parseargs(&argc, &argv, cmdlnopts);
+ if(help) showhelp(-1, cmdlnopts);
+ if(argc > 0){
+ fprintf(stderr, "Undefined extra parameters!\n");
+ showhelp(-1, cmdlnopts);
+ G.rest_pars_num = argc;
+ G.rest_pars = MALLOC(char *, argc);
+ for (i = 0; i < argc; i++)
+ G.rest_pars[i] = strdup(argv[i]);
+ }
+ return &G;
+}
+
diff --git a/Daemons/send_coordinates/cmdlnopts.h b/Daemons/send_coordinates/cmdlnopts.h
new file mode 100644
index 0000000..241bac0
--- /dev/null
+++ b/Daemons/send_coordinates/cmdlnopts.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the SendCoords project.
+ * Copyright 2020 Edward V. Emelianov .
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+#pragma once
+#ifndef CMDLNOPTS_H__
+#define CMDLNOPTS_H__
+
+/*
+ * here are some typedef's for global data
+ */
+typedef struct{
+ char *pidfile; // name of PID file
+ char *port; // port to connect
+ char *host; // hostname
+ char *ra; // RA in string form
+ char *dec; // DEC in string form
+ int rest_pars_num; // number of rest parameters
+ int quiet; // don't show anything
+ int monitor; // monitor status
+ char** rest_pars; // the rest parameters: array of char*
+} glob_pars;
+
+
+glob_pars *parse_args(int argc, char **argv);
+
+#endif // CMDLNOPTS_H__
diff --git a/Daemons/send_coordinates/main.c b/Daemons/send_coordinates/main.c
new file mode 100644
index 0000000..a8935f6
--- /dev/null
+++ b/Daemons/send_coordinates/main.c
@@ -0,0 +1,79 @@
+/*
+ * This file is part of the SendCoords project.
+ * Copyright 2020 Edward V. Emelianov .
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include // signal
+#include // printf
+#include // exit, free
+#include // strdup
+#include // sleep
+#include
+
+#include "cmdlnopts.h"
+#include "stelldaemon.h"
+
+glob_pars *GP = NULL; // for GP->pidfile need in `signals`
+
+/**
+ * We REDEFINE the default WEAK function of signal processing
+ */
+void signals(int sig){
+ if(sig){
+ signal(sig, SIG_IGN);
+ DBG("Get signal %d, quit.\n", sig);
+ }
+ WARNX("Exit with status %d", sig);
+ if(GP->pidfile) // remove unnesessary PID file
+ unlink(GP->pidfile);
+ restore_console();
+ exit(sig);
+}
+
+void iffound_default(pid_t pid){
+ ERRX("Another copy of this process found, pid=%d. Exit.", pid);
+}
+
+int main(int argc, char *argv[]){
+ initial_setup();
+ char *self = strdup(argv[0]);
+ GP = parse_args(argc, argv);
+ if(GP->rest_pars_num){
+ printf("%d extra options:\n", GP->rest_pars_num);
+ for(int i = 0; i < GP->rest_pars_num; ++i)
+ printf("%s\n", GP->rest_pars[i]);
+ }
+ if((GP->ra && !GP->dec) || (!GP->ra && GP->dec))
+ ERRX("You should point both coordinates");
+ check4running(self, GP->pidfile);
+ free(self);
+ signal(SIGTERM, signals); // kill (-15) - quit
+ signal(SIGHUP, SIG_IGN); // hup - ignore
+ signal(SIGINT, signals); // ctrl+C - quit
+ signal(SIGQUIT, signals); // ctrl+\ - quit
+ signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z
+ setup_con();
+ /*
+ if(GP->rest_pars_num){
+ for(int i = 0; i < GP->rest_pars_num; ++i)
+ printf("Extra argument: %s\n", GP->rest_pars[i]);
+ }*/
+ mk_connection();
+ // clean everything
+ signals(0);
+ return 0;
+}
+
diff --git a/Daemons/send_coordinates/stelldaemon.c b/Daemons/send_coordinates/stelldaemon.c
new file mode 100644
index 0000000..85726c0
--- /dev/null
+++ b/Daemons/send_coordinates/stelldaemon.c
@@ -0,0 +1,215 @@
+/*
+ * This file is part of the SendCoords project.
+ * Copyright 2020 Edward V. Emelianov .
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include // inet_ntop
+#include // NAN
+#include //getaddrinfo
+#include
+#include
+#include
+#include // getaddrinfo, connect, socket
+#include // getaddrinfo & socket types
+#include
+#include
+
+#include "cmdlnopts.h"
+#include "stelldaemon.h"
+
+extern glob_pars *GP;
+
+/**
+ * convert RA/DEC to string in forman RA: HH:MM:SS.SS, DEC: DD:MM:SS.S
+ */
+static char *radec2str(double ra, double dec){
+ static char buf[1024];
+ char sign = '+';
+ if(dec < 0){
+ sign = '-';
+ dec = -dec;
+ }
+
+ int h = (int)ra;
+ ra -= h; ra *= 60.;
+ int m = (int)ra;
+ ra -= m; ra *= 60.;
+
+ int d = (int) dec;
+ dec -= d; dec *= 60.;
+ int dm = (int)dec;
+ dec -= dm; dec *= 60.;
+ snprintf(buf, 1024, "RA=%02d:%02d:%05.2f, DEC=%c%02d:%02d:%04.1f", h,m,ra, sign,d,dm,dec);
+ return buf;
+}
+
+/**
+ * @brief print_coords - print received coordinates @ terminal
+ * @param idat (i) - received data
+ */
+static void print_coords(indata *dat){
+ uint16_t len, type;
+ uint32_t ra;
+ int32_t dec, status;
+#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
+ len = le16toh(dat->len); type = le16toh(dat->type);
+ //tim = le64toh(dat->time);
+ ra = le32toh(dat->ra);
+ dec = (int32_t)le32toh((uint32_t)dat->dec);
+ status = (int32_t)le32toh((uint32_t)dat->status);
+#else
+ len = dat->len;
+ type = dat->type;
+ //tim = dat->time;
+ ra = dat->ra;
+ dec = dat->dec;
+ status = dat->status;
+#endif
+ DBG("len=%d, type=%d, ra=%d, dec=%d, status=%d\n",
+ len, type, ra, dec, status);
+ if(len != sizeof(indata)){
+ WARNX("Field `size` of input data not equal to %d", sizeof(indata));
+ return;
+ }
+ double tagRA = RA2HRS(ra), tagDec = DEC2DEG(dec);
+// DBG("RA: %g, DEC: %g, STATUS: %d", tagRA, tagDec, status);
+ printf("%s, STATUS: %d\n", radec2str(tagRA, tagDec), status);
+}
+
+static int waittoread(int sock){
+ fd_set fds;
+ struct timeval timeout;
+ int rc;
+ timeout.tv_sec = 5; // wait not more than 1 second
+ timeout.tv_usec = 0;
+ FD_ZERO(&fds);
+ FD_SET(sock, &fds);
+ rc = select(sock+1, &fds, NULL, NULL, &timeout);
+ if(rc < 0){
+ WARN("select()");
+ return 0;
+ }
+ if(rc > 0 && FD_ISSET(sock, &fds)) return 1;
+ return 0;
+}
+
+/**
+ * @brief str2ha - convert string with angle/hour HH:MM:SS or DD:MM:SS into double value
+ * @param str (i) - input string
+ * @param ha (o) - value
+ * @return 0 if all OK
+ */
+static int str2ha(const char *str, double *ha){
+ if(!str || !ha) return 1;
+ int hd, m, sign = 1; // hours/degrees, minutes
+ float s; // seconds
+ if(3 != sscanf(str, "%d:%d:%f", &hd, &m, &s)){
+ return 1;
+ }
+ if(hd < 0){sign = -1; hd = -hd;}
+ *ha = sign * (hd + m/60. + s/3600.);
+ return 0;
+}
+
+void mk_connection(){
+ int sockfd = 0;
+ int pointing = FALSE; // ==1 if telescope is pointing
+ uint8_t recvBuff[64];
+ double ra = FP_NAN, dec = FP_NAN;
+ if(GP->ra && GP->dec){
+ DBG("Point to %s %s", GP->ra, GP->dec);
+ if(str2ha(GP->ra, &ra)){
+ WARNX("Wrong RA: %s", GP->ra);
+ return;
+ }
+ if(ra < 0. || ra > 24.){
+ WARNX("RA should be in range 0..24h");
+ return;
+ }
+ if(str2ha(GP->dec, &dec)){
+ WARNX("Wrong DEC: %s", GP->dec);
+ return;
+ }
+ if(dec < -90. || dec > 90.){
+ WARNX("DEC should be in range -90..90degr");
+ return;
+ }
+ pointing = TRUE;
+ DBG("RA: %g, DEC: %g", ra, dec);
+ }
+ struct addrinfo h, *r, *p;
+ memset(&h, 0, sizeof(h));
+ h.ai_family = AF_INET;
+ h.ai_socktype = SOCK_STREAM;
+ h.ai_flags = AI_CANONNAME;
+ if(!GP) ERRX("Command line arguments not defined!");
+ if(getaddrinfo(GP->host, GP->port, &h, &r)){WARN("getaddrinfo()"); return;}
+ struct sockaddr_in *ia = (struct sockaddr_in*)r->ai_addr;
+#ifdef EBUG
+ char str[INET_ADDRSTRLEN];
+ inet_ntop(AF_INET, &(ia->sin_addr), str, INET_ADDRSTRLEN);
+ printf("canonname: %s, port: %u, addr: %s\n", r->ai_canonname, ntohs(ia->sin_port), str);
+#endif
+ for(p = r; p; p = p->ai_next){
+ if ((sockfd = socket(p->ai_family, p->ai_socktype,
+ p->ai_protocol)) == -1) {
+ WARN("socket()");
+ continue;
+ }
+ if(connect(sockfd, p->ai_addr, p->ai_addrlen) == -1){
+ close(sockfd);
+ WARN("connect()");
+ continue;
+ }
+ break; // if we get here, we must have connected successfully
+ }
+ if(p == NULL){
+ // looped off the end of the list with no connection
+ WARNX("Failed to connect to socket\n");
+ return;
+ }
+ freeaddrinfo(r);
+
+ if(pointing){
+ outdata dat;
+ dat.len = htole16(sizeof(outdata));
+ dat.type = 0;
+ dat.ra = htole32(HRS2RA(ra));
+ dat.dec = (int32_t)htole32(DEG2DEC(dec));
+ if(send(sockfd, &dat, sizeof(outdata), 0) != sizeof(outdata))
+ WARN("send()");
+ sleep(1);
+ }
+ int tstart = time(NULL);
+ while(waittoread(sockfd)){
+ int n = read(sockfd, recvBuff, sizeof(recvBuff)-1);
+ DBG("got %d bytes", n);
+ if(n < 1) break;
+ if(n == sizeof (indata)){
+ indata *idat = (indata*)recvBuff;
+ if(!GP->quiet) print_coords(idat);
+ if(GP->monitor) continue;
+ if(!pointing) break;
+ if(idat->status == _10U_STATUS_TRACKING && time(NULL) - tstart > 3) break; // start tracking (+3s pause)
+ if(idat->status != _10U_STATUS_SLEWING){
+ if(time(NULL) - tstart > 5) signals(idat->status); // exit with error code after 5 seconds waiting
+ }else tstart = time(NULL); // reset time if status is slewing
+ }
+ }
+ close(sockfd);
+ DBG("End");
+ //FREE(msg);
+}
diff --git a/Daemons/send_coordinates/stelldaemon.h b/Daemons/send_coordinates/stelldaemon.h
new file mode 100644
index 0000000..f01a080
--- /dev/null
+++ b/Daemons/send_coordinates/stelldaemon.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the SendCoords project.
+ * Copyright 2020 Edward V. Emelianov .
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+#ifndef STELLDAEMON_H__
+
+#include
+
+// some statuses
+#define _10U_STATUS_TRACKING (0)
+#define _10U_STATUS_SLEWING (6)
+
+#define DEG2DEC(degr) ((int32_t)(degr / 90. * ((double)0x40000000)))
+#define HRS2RA(hrs) ((uint32_t)(hrs / 12. * ((double)0x80000000)))
+#define DEC2DEG(i32) (((double)i32)*90./((double)0x40000000))
+#define RA2HRS(u32) (((double)u32)*12. /((double)0x80000000))
+
+typedef struct __attribute__((__packed__)){
+ uint16_t len;
+ uint16_t type;
+ uint64_t time;
+ uint32_t ra;
+ int32_t dec;
+} outdata;
+
+typedef struct __attribute__((__packed__)){
+ uint16_t len;
+ uint16_t type;
+ uint64_t time;
+ uint32_t ra;
+ int32_t dec;
+ int32_t status;
+} indata;
+
+void mk_connection();
+
+#define STELLDAEMON_H__
+#endif // STELLDAEMON_H__
diff --git a/Daemons/teldaemon/teldaemon b/Daemons/teldaemon/teldaemon
old mode 100644
new mode 100755
diff --git a/Docs/Alignment/makelist b/Docs/Alignment/makelist
old mode 100644
new mode 100755
diff --git a/Docs/focus b/Docs/focus
old mode 100644
new mode 100755