Changeset 501
- Timestamp:
- Nov 7, 2010, 11:24:13 PM (14 years ago)
- Location:
- BAORadio
- Files:
-
- 10 added
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
BAORadio/libindi/libindi/BAOTest/simple_server_main.cpp
r490 r501 10 10 { 11 11 // Create the socket 12 ServerSocket server ( 8000);12 ServerSocket server ( 7624 ); 13 13 14 14 while ( true ) -
BAORadio/libindi/libindi/CMakeLists.txt
r490 r501 1 1 cmake_minimum_required(VERSION 2.4.7) 2 2 3 if(COMMAND cmake_policy) 4 cmake_policy(SET CMP0003 NEW) 5 endif(COMMAND cmake_policy) 6 7 3 8 4 9 ################## INDI version ################################ 5 set(INDI_VERSION "0.6")6 10 set(INDI_SOVERSION "0") 7 8 11 set(CMAKE_INDI_VERSION_MAJOR 0) 9 set(CMAKE_INDI_VERSION_MINOR 6)10 set(CMAKE_INDI_VERSION_RELEASE 1)12 set(CMAKE_INDI_VERSION_MINOR 7) 13 set(CMAKE_INDI_VERSION_RELEASE 0) 11 14 set(CMAKE_INDI_VERSION_STRING "${CMAKE_INDI_VERSION_MAJOR}.${CMAKE_INDI_VERSION_MINOR}.${CMAKE_INDI_VERSION_RELEASE}") 12 15 … … 51 54 macro_log_feature(FLI_FOUND "libfli" "Finger Lakes Instrument Library" "http://indi.sourceforge.net/" FALSE "1.71" "Provides INDI with support for controlling FLI CCDS & Filter Wheels.") 52 55 53 54 56 macro_optional_find_package(Nova) 55 57 macro_bool_to_01(NOVA_FOUND HAVE_NOVA_H) … … 59 61 check_include_files(termios.h TERMIOS_FOUND) 60 62 macro_bool_to_01(TERMIOS_FOUND HAVE_TERMIOS_H) 61 62 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h )63 63 64 64 include_directories( ${CMAKE_CURRENT_BINARY_DIR}) … … 95 95 96 96 set (indimain_SRCS 97 ${CMAKE_SOURCE_DIR}/indidriver.c 97 98 ${CMAKE_SOURCE_DIR}/indidrivermain.c 98 99 ${CMAKE_SOURCE_DIR}/eventloop.c 99 100 ) 100 101 102 set (indibase_SRCS 103 ${CMAKE_SOURCE_DIR}/libs/indibase/basedriver.cpp 104 ${CMAKE_SOURCE_DIR}/libs/indibase/baseclient.cpp 105 ) 106 107 set (indidefaultdevice_SRCS 108 ${CMAKE_SOURCE_DIR}/libs/indibase/basedriver.cpp 109 ${CMAKE_SOURCE_DIR}/libs/indibase/defaultdriver.cpp 110 ) 111 112 101 113 ###################################### 102 114 ########### INDI SERVER ############## … … 115 127 install(TARGETS indiserver RUNTIME DESTINATION bin ) 116 128 117 ######################################118 ######## INDI Static Library #########119 ######################################120 add_library(indidriver STATIC ${indimain_SRCS})121 install(TARGETS indidriver ARCHIVE DESTINATION lib${LIB_POSTFIX})122 129 123 130 ###################################### … … 138 145 139 146 install(TARGETS indi LIBRARY DESTINATION lib${LIB_POSTFIX}) 140 set_target_properties(indi PROPERTIES VERSION ${INDI_VERSION} SOVERSION ${INDI_SOVERSION}) 147 set_target_properties(indi PROPERTIES VERSION ${CMAKE_INDI_VERSION_STRING} SOVERSION ${INDI_SOVERSION}) 148 149 150 ###################################### 151 ######## INDI Static Library ######### 152 ###################################### 153 add_library(indidriver STATIC ${indimain_SRCS}) 154 install(TARGETS indidriver ARCHIVE DESTINATION lib${LIB_POSTFIX}) 155 156 ############################################## 157 ######## INDI Default Driver Library ######### 158 ############################################## 159 add_library(indidefaultdriver STATIC ${indimain_SRCS} ${indidefaultdevice_SRCS}) 160 install(TARGETS indidefaultdriver ARCHIVE DESTINATION lib${LIB_POSTFIX}) 161 162 ############################################## 163 ######## INDI Client Library ######### 164 ############################################## 165 add_library(indiclient STATIC ${indibase_SRCS}) 166 target_link_libraries(indiclient indi) 167 install(TARGETS indiclient ARCHIVE DESTINATION lib${LIB_POSTFIX}) 141 168 142 169 ##################################### … … 202 229 target_link_libraries(indi_celestron_gps m ) 203 230 231 204 232 if (NOVA_FOUND) 205 233 target_link_libraries(indi_celestron_gps ${NOVA_LIBRARIES}) … … 601 629 endif (NOVA_FOUND) 602 630 631 ########### Tutorial four ############## 632 set(tutorialfour_SRCS 633 ${indimain_SRCS} 634 ${CMAKE_SOURCE_DIR}/examples/tutorial_four.cpp 635 ) 636 637 add_executable(tutorial_four ${tutorialfour_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS}) 638 639 target_link_libraries(tutorial_four indidefaultdriver indiclient m z pthread) 640 641 if (NOVA_FOUND) 642 target_link_libraries(tutorial_four ${NOVA_LIBRARIES}) 643 endif (NOVA_FOUND) 644 645 603 646 ########### Tutorial dome ############## 604 647 set(tutorialdome_SRCS … … 633 676 install( FILES drivers.xml DESTINATION ${DATA_INSTALL_DIR}) 634 677 635 install( FILES indiapi.h indidevapi.h base64.h eventloop.h ${CMAKE_SOURCE_DIR}/libs/lilxml.h 636 ${CMAKE_SOURCE_DIR}/libs/indicom.h DESTINATION ${INCLUDE_INSTALL_DIR}/libindi COMPONENT Devel) 678 install( FILES indiapi.h indidevapi.h base64.h eventloop.h indidriver.h ${CMAKE_SOURCE_DIR}/libs/lilxml.h ${CMAKE_SOURCE_DIR}/libs/indibase/indibase.h 679 ${CMAKE_SOURCE_DIR}/libs/indibase/basedriver.h ${CMAKE_SOURCE_DIR}/libs/indibase/defaultdriver.h 680 ${CMAKE_SOURCE_DIR}/libs/indibase/baseclient.h ${CMAKE_SOURCE_DIR}/libs/indicom.h 681 DESTINATION ${INCLUDE_INSTALL_DIR}/libindi COMPONENT Devel) 637 682 638 683 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libindi.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libindi.pc @ONLY) -
BAORadio/libindi/libindi/ChangeLog
r490 r501 1 From 0.6.2 to 0.7.0 2 3 # Dynamic renaming of drivers upon run time. 4 # Standard helper API to create and utilize INDI clients. 5 # Ability to load driver properties from an external XML file. 6 # Ability to write/read XML configuration files for driver values to be loaded at run time. 7 # Facilitating debugging and simulation of drivers. 8 # New C++ framework to facilitate the development of new INDI drivers. 9 # Several bug fixes for current drivers and framework. 10 11 From 0.6.1 to 0.6.2 12 13 # Build related updates. 14 15 From 0.6 to 0.6.1 16 17 # Updating drivers.xml to comply to new XML structure for group and devices metadata descriptions. 18 1 19 From 0.5 to 0.6 2 20 -
BAORadio/libindi/libindi/Doxyfile
r490 r501 1 # Doxyfile 1. 4.1-KDevelop1 # Doxyfile 1.7.1 2 2 3 3 #--------------------------------------------------------------------------- 4 4 # Project related configuration options 5 5 #--------------------------------------------------------------------------- 6 DOXYFILE_ENCODING = UTF-8 6 7 PROJECT_NAME = "Instrument Neutral Distributed Interface INDI" 7 8 PROJECT_NUMBER = 0.7 … … 9 10 CREATE_SUBDIRS = NO 10 11 OUTPUT_LANGUAGE = English 11 USE_WINDOWS_ENCODING = NO12 12 BRIEF_MEMBER_DESC = YES 13 13 REPEAT_BRIEF = YES 14 ABBREVIATE_BRIEF = 14 ABBREVIATE_BRIEF = 15 15 ALWAYS_DETAILED_SEC = NO 16 16 INLINE_INHERITED_MEMB = NO 17 17 FULL_PATH_NAMES = NO 18 STRIP_FROM_PATH = 19 STRIP_FROM_INC_PATH = 18 STRIP_FROM_PATH = 19 STRIP_FROM_INC_PATH = 20 20 SHORT_NAMES = NO 21 21 JAVADOC_AUTOBRIEF = NO 22 QT_AUTOBRIEF = NO 22 23 MULTILINE_CPP_IS_BRIEF = NO 23 DETAILS_AT_TOP = NO24 24 INHERIT_DOCS = YES 25 DISTRIBUTE_GROUP_DOC= NO25 SEPARATE_MEMBER_PAGES = NO 26 26 TAB_SIZE = 8 27 ALIASES = 27 ALIASES = 28 28 OPTIMIZE_OUTPUT_FOR_C = NO 29 29 OPTIMIZE_OUTPUT_JAVA = NO 30 OPTIMIZE_FOR_FORTRAN = NO 31 OPTIMIZE_OUTPUT_VHDL = NO 32 EXTENSION_MAPPING = 33 BUILTIN_STL_SUPPORT = NO 34 CPP_CLI_SUPPORT = NO 35 SIP_SUPPORT = NO 36 IDL_PROPERTY_SUPPORT = YES 37 DISTRIBUTE_GROUP_DOC = NO 30 38 SUBGROUPING = YES 39 TYPEDEF_HIDES_STRUCT = NO 40 SYMBOL_CACHE_SIZE = 0 31 41 #--------------------------------------------------------------------------- 32 42 # Build related configuration options … … 37 47 EXTRACT_LOCAL_CLASSES = YES 38 48 EXTRACT_LOCAL_METHODS = NO 49 EXTRACT_ANON_NSPACES = NO 39 50 HIDE_UNDOC_MEMBERS = YES 40 51 HIDE_UNDOC_CLASSES = YES … … 45 56 HIDE_SCOPE_NAMES = NO 46 57 SHOW_INCLUDE_FILES = YES 58 FORCE_LOCAL_INCLUDES = NO 47 59 INLINE_INFO = YES 48 60 SORT_MEMBER_DOCS = YES 49 61 SORT_BRIEF_DOCS = NO 62 SORT_MEMBERS_CTORS_1ST = NO 63 SORT_GROUP_NAMES = NO 50 64 SORT_BY_SCOPE_NAME = NO 51 65 GENERATE_TODOLIST = YES … … 53 67 GENERATE_BUGLIST = YES 54 68 GENERATE_DEPRECATEDLIST= YES 55 ENABLED_SECTIONS = 69 ENABLED_SECTIONS = 56 70 MAX_INITIALIZER_LINES = 30 57 71 SHOW_USED_FILES = YES 58 72 SHOW_DIRECTORIES = YES 59 FILE_VERSION_FILTER = 73 SHOW_FILES = YES 74 SHOW_NAMESPACES = YES 75 FILE_VERSION_FILTER = 76 LAYOUT_FILE = 60 77 #--------------------------------------------------------------------------- 61 78 # configuration options related to warning and progress messages … … 67 84 WARN_NO_PARAMDOC = NO 68 85 WARN_FORMAT = "$file:$line: $text" 69 WARN_LOGFILE = 86 WARN_LOGFILE = 70 87 #--------------------------------------------------------------------------- 71 88 # configuration options related to the input files 72 89 #--------------------------------------------------------------------------- 73 INPUT = /home/jasem/Projects/trunk/libindi 90 INPUT = /home/jasem/Projects/indi/trunk/libindi 91 INPUT_ENCODING = UTF-8 74 92 FILE_PATTERNS = *.c \ 75 93 *.cc \ … … 103 121 *.dox 104 122 RECURSIVE = YES 105 EXCLUDE = /home/jasem/Projects/ trunk/libindi/drivers \106 /home/jasem/Projects/ trunk/libindi/tools \107 /home/jasem/Projects/ trunk/libindi/libs/webcam \108 /home/jasem/Projects/ trunk/libindi/libs/base64.c \109 /home/jasem/Projects/ trunk/libindi/libs/fq.c \110 /home/jasem/Projects/ trunk/libindi/indidrivermain.c \111 /home/jasem/Projects/ trunk/libindi/indiserver.c123 EXCLUDE = /home/jasem/Projects/indi/trunk/libindi/drivers \ 124 /home/jasem/Projects/indi/trunk/libindi/tools \ 125 /home/jasem/Projects/indi/trunk/libindi/libs/webcam \ 126 /home/jasem/Projects/indi/trunk/libindi/libs/base64.c \ 127 /home/jasem/Projects/indi/trunk/libindi/libs/fq.c \ 128 /home/jasem/Projects/indi/trunk/libindi/indidrivermain.c \ 129 /home/jasem/Projects/indi/trunk/libindi/indiserver.c 112 130 EXCLUDE_SYMLINKS = NO 113 EXCLUDE_PATTERNS = 114 EXAMPLE_PATH = 131 EXCLUDE_PATTERNS = 132 EXCLUDE_SYMBOLS = 133 EXAMPLE_PATH = 115 134 EXAMPLE_PATTERNS = * 116 135 EXAMPLE_RECURSIVE = NO 117 IMAGE_PATH = 118 INPUT_FILTER = 119 FILTER_PATTERNS = 136 IMAGE_PATH = 137 INPUT_FILTER = 138 FILTER_PATTERNS = 120 139 FILTER_SOURCE_FILES = NO 121 140 #--------------------------------------------------------------------------- … … 127 146 REFERENCED_BY_RELATION = NO 128 147 REFERENCES_RELATION = NO 148 REFERENCES_LINK_SOURCE = YES 149 USE_HTAGS = NO 129 150 VERBATIM_HEADERS = NO 130 151 #--------------------------------------------------------------------------- … … 133 154 ALPHABETICAL_INDEX = YES 134 155 COLS_IN_ALPHA_INDEX = 5 135 IGNORE_PREFIX = 156 IGNORE_PREFIX = 136 157 #--------------------------------------------------------------------------- 137 158 # configuration options related to the HTML output … … 140 161 HTML_OUTPUT = doc 141 162 HTML_FILE_EXTENSION = .html 142 HTML_HEADER = 143 HTML_FOOTER = 144 HTML_STYLESHEET = 163 HTML_HEADER = 164 HTML_FOOTER = 165 HTML_STYLESHEET = 166 HTML_COLORSTYLE_HUE = 220 167 HTML_COLORSTYLE_SAT = 100 168 HTML_COLORSTYLE_GAMMA = 80 169 HTML_TIMESTAMP = YES 145 170 HTML_ALIGN_MEMBERS = YES 171 HTML_DYNAMIC_SECTIONS = NO 172 GENERATE_DOCSET = NO 173 DOCSET_FEEDNAME = "Doxygen generated docs" 174 DOCSET_BUNDLE_ID = org.doxygen.Project 175 DOCSET_PUBLISHER_ID = org.doxygen.Publisher 176 DOCSET_PUBLISHER_NAME = Publisher 146 177 GENERATE_HTMLHELP = NO 147 CHM_FILE = 148 HHC_LOCATION = 178 CHM_FILE = 179 HHC_LOCATION = 149 180 GENERATE_CHI = NO 181 CHM_INDEX_ENCODING = 150 182 BINARY_TOC = NO 151 183 TOC_EXPAND = NO 184 GENERATE_QHP = NO 185 QCH_FILE = 186 QHP_NAMESPACE = org.doxygen.Project 187 QHP_VIRTUAL_FOLDER = doc 188 QHP_CUST_FILTER_NAME = 189 QHP_CUST_FILTER_ATTRS = 190 QHP_SECT_FILTER_ATTRS = 191 QHG_LOCATION = 192 GENERATE_ECLIPSEHELP = NO 193 ECLIPSE_DOC_ID = org.doxygen.Project 152 194 DISABLE_INDEX = NO 153 195 ENUM_VALUES_PER_LINE = 4 154 196 GENERATE_TREEVIEW = NO 197 USE_INLINE_TREES = NO 155 198 TREEVIEW_WIDTH = 250 199 EXT_LINKS_IN_WINDOW = NO 200 FORMULA_FONTSIZE = 10 201 FORMULA_TRANSPARENT = YES 202 SEARCHENGINE = NO 203 SERVER_BASED_SEARCH = NO 156 204 #--------------------------------------------------------------------------- 157 205 # configuration options related to the LaTeX output … … 163 211 COMPACT_LATEX = NO 164 212 PAPER_TYPE = a4wide 165 EXTRA_PACKAGES = 166 LATEX_HEADER = 213 EXTRA_PACKAGES = 214 LATEX_HEADER = 167 215 PDF_HYPERLINKS = NO 168 216 USE_PDFLATEX = NO 169 217 LATEX_BATCHMODE = NO 170 218 LATEX_HIDE_INDICES = NO 219 LATEX_SOURCE_CODE = NO 171 220 #--------------------------------------------------------------------------- 172 221 # configuration options related to the RTF output … … 176 225 COMPACT_RTF = NO 177 226 RTF_HYPERLINKS = NO 178 RTF_STYLESHEET_FILE = 179 RTF_EXTENSIONS_FILE = 227 RTF_STYLESHEET_FILE = 228 RTF_EXTENSIONS_FILE = 180 229 #--------------------------------------------------------------------------- 181 230 # configuration options related to the man page output … … 190 239 GENERATE_XML = NO 191 240 XML_OUTPUT = xml 192 XML_SCHEMA = 193 XML_DTD = 241 XML_SCHEMA = 242 XML_DTD = 194 243 XML_PROGRAMLISTING = YES 195 244 #--------------------------------------------------------------------------- … … 203 252 PERLMOD_LATEX = NO 204 253 PERLMOD_PRETTY = YES 205 PERLMOD_MAKEVAR_PREFIX = 206 #--------------------------------------------------------------------------- 207 # Configuration options related to the preprocessor 254 PERLMOD_MAKEVAR_PREFIX = 255 #--------------------------------------------------------------------------- 256 # Configuration options related to the preprocessor 208 257 #--------------------------------------------------------------------------- 209 258 ENABLE_PREPROCESSING = YES … … 211 260 EXPAND_ONLY_PREDEF = NO 212 261 SEARCH_INCLUDES = YES 213 INCLUDE_PATH = 214 INCLUDE_FILE_PATTERNS = 215 PREDEFINED = 216 EXPAND_AS_DEFINED = 262 INCLUDE_PATH = 263 INCLUDE_FILE_PATTERNS = 264 PREDEFINED = 265 EXPAND_AS_DEFINED = 217 266 SKIP_FUNCTION_MACROS = YES 218 267 #--------------------------------------------------------------------------- 219 # Configuration::additions related to external references 220 #--------------------------------------------------------------------------- 221 TAGFILES = 222 GENERATE_TAGFILE = 268 # Configuration::additions related to external references 269 #--------------------------------------------------------------------------- 270 TAGFILES = 271 GENERATE_TAGFILE = 223 272 ALLEXTERNALS = NO 224 273 EXTERNAL_GROUPS = YES 225 274 PERL_PATH = /usr/bin/perl 226 275 #--------------------------------------------------------------------------- 227 # Configuration options related to the dot tool 276 # Configuration options related to the dot tool 228 277 #--------------------------------------------------------------------------- 229 278 CLASS_DIAGRAMS = YES 279 MSCGEN_PATH = 230 280 HIDE_UNDOC_RELATIONS = YES 231 281 HAVE_DOT = NO 282 DOT_NUM_THREADS = 0 283 DOT_FONTNAME = FreeSans.ttf 284 DOT_FONTSIZE = 10 285 DOT_FONTPATH = 232 286 CLASS_GRAPH = YES 233 287 COLLABORATION_GRAPH = YES … … 238 292 INCLUDED_BY_GRAPH = YES 239 293 CALL_GRAPH = NO 294 CALLER_GRAPH = NO 240 295 GRAPHICAL_HIERARCHY = YES 241 296 DIRECTORY_GRAPH = YES 242 297 DOT_IMAGE_FORMAT = png 243 DOT_PATH = 244 DOTFILE_DIRS = 245 MAX_DOT_GRAPH_WIDTH = 1024 246 MAX_DOT_GRAPH_HEIGHT = 1024 298 DOT_PATH = 299 DOTFILE_DIRS = 300 DOT_GRAPH_MAX_NODES = 50 247 301 MAX_DOT_GRAPH_DEPTH = 1000 248 302 DOT_TRANSPARENT = NO … … 250 304 GENERATE_LEGEND = YES 251 305 DOT_CLEANUP = YES 252 #---------------------------------------------------------------------------253 # Configuration::additions related to the search engine254 #---------------------------------------------------------------------------255 SEARCHENGINE = NO -
BAORadio/libindi/libindi/INSTALL
r490 r501 1 INDI Library Setup 0. 6.11 INDI Library Setup 0.7.0 2 2 ======================== 3 3 -
BAORadio/libindi/libindi/NEWS
r490 r501 3 3 ------------------------------------------------------------------------- 4 4 5 For the latest news on INDI, refer to INDI's website @ http:// indi.sf.net5 For the latest news on INDI, refer to INDI's website @ http://www.indilib.org 6 6 -
BAORadio/libindi/libindi/README
r490 r501 1 libindi v0.6.2 2 ============== 3 1 4 The code here demonstrates the use of INDI, an Instrument-Neutral Device 2 5 Interface protocol. See http://www.clearskyinstitute.com/INDI/INDI.pdf. -
BAORadio/libindi/libindi/cmake_modules/FindINDI.cmake
r490 r501 5 5 # INDI_INCLUDE_DIR - the INDI include directory 6 6 # INDI_LIBRARIES - Link these to use INDI 7 # INDI_DEVICE_LIBRARY - The indi default device library 8 # INDI_DATA_DIR - INDI shared data dir. 7 9 8 # Copyright (c) 20 06, Jasem Mutlaq <mutlaqja@ikarustech.com>10 # Copyright (c) 2010, Jasem Mutlaq <mutlaqja@ikarustech.com> 9 11 # Based on FindLibfacile by Carsten Niehaus, <cniehaus@gmx.de> 10 12 # … … 27 29 ) 28 30 31 find_path(INDI_DATA_DIR drivers.xml 32 PATH_SUFFIXES indi 33 /usr 34 /usr/local 35 /opt 36 ${GNUWIN32_DIR}/share 37 ) 38 29 39 find_library(INDI_DRIVER_LIBRARIES NAMES indidriver 30 40 PATHS … … 32 42 ${GNUWIN32_DIR}/lib 33 43 ) 44 45 find_library(INDI_DEVICE_LIBRARIES NAMES indidefaultdevice 46 PATHS 47 ${_obLinkDir} 48 ${GNUWIN32_DIR}/lib 49 ) 50 34 51 35 52 find_library(INDI_LIBRARIES NAMES indi … … 52 69 else (INDI_FOUND) 53 70 if (INDI_FIND_REQUIRED) 54 message(FATAL_ERROR "indi-devel not found. Cannot compile INDI drivers. Please install indi-devel and try again. http:// indi.sf.net")71 message(FATAL_ERROR "indi-devel not found. Cannot compile INDI drivers. Please install indi-devel and try again. http://www.indilib.org") 55 72 endif (INDI_FIND_REQUIRED) 56 73 endif (INDI_FOUND) 57 74 58 mark_as_advanced(INDI_INCLUDE_DIR INDI_LIBRARIES INDI_DRIVER_LIBRARIES )75 mark_as_advanced(INDI_INCLUDE_DIR INDI_LIBRARIES INDI_DRIVER_LIBRARIES INDI_DEVICE_LIBRARIES INDI_DATA_DIR) 59 76 60 77 endif (INDI_INCLUDE_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES) -
BAORadio/libindi/libindi/drivers/filter_wheel/trutech_wheel.c
r490 r501 70 70 #define FIRST_FILTER 1 71 71 72 #define DEBUG_ON 0 73 #define SIMULATION_ON 0 74 72 75 73 76 /*INDI controls */ … … 166 169 unsigned char chksum = COMM_INIT + type + COMM_FILL; 167 170 /*char filter_command[5] = { COMM_PRE, COMM_INIT, type, COMM_FILL, chksum };*/ 168 171 unsigned char filter_command[CMD_SIZE]; 169 172 snprintf(filter_command, CMD_SIZE, "%c%c%c%c%c", COMM_PRE, COMM_INIT, type, COMM_FILL, chksum); 170 173 … … 172 175 return; 173 176 174 err = tty_write(fd, filter_command, CMD_SIZE, &nbytes); 175 177 if (!SIMULATION_ON) 178 err = tty_write(fd, filter_command, CMD_SIZE, &nbytes); 179 180 181 if (DEBUG_ON) 182 { 183 IDLog("Home Search Command (int): #%d#%d#%d#%d#%d#\n",COMM_PRE, COMM_INIT, type, COMM_FILL, chksum); 184 IDLog("Home Search Command (char): #%c#%c#%c#%c#%c#\n",COMM_PRE, COMM_INIT, type, COMM_FILL, chksum); 185 } 186 176 187 /* Send Home Command */ 177 188 if (err != TTY_OK) … … 247 258 targetFilter = values[0]; 248 259 int nbytes=0; 249 250 char chksum = COMM_INIT + type + (char) targetFilter;260 unsigned char type = 0x01; 261 unsigned char chksum = COMM_INIT + type + (unsigned char) targetFilter; 251 262 /*char filter_command[5] = { COMM_PRE, COMM_INIT, type, targetFilter, chksum };*/ 252 char filter_command[CMD_SIZE]; 253 254 snprintf(filter_command, CMD_SIZE, "%c%c%c%c%c", COMM_PRE, COMM_INIT, type, COMM_FILL, chksum); 263 unsigned char filter_command[CMD_SIZE]; 264 255 265 256 266 if (targetFilter < FilterPositionN[0].min || targetFilter > FilterPositionN[0].max) … … 262 272 263 273 IUUpdateNumber(&FilterPositionNP, values, names, n); 264 err = tty_write(fd, filter_command, CMD_SIZE, &nbytes); 274 275 snprintf(filter_command, CMD_SIZE, "%c%c%c%c%c", COMM_PRE, COMM_INIT, type, targetFilter, chksum); 276 277 if (DEBUG_ON) 278 { 279 IDLog("Filter Position Command (int): #%d#%d#%d#%d#%d#\n",COMM_PRE, COMM_INIT, type, targetFilter, chksum); 280 IDLog("Filter Position Command (char): #%c#%c#%c#%c#%c#\n",COMM_PRE, COMM_INIT, type, targetFilter, chksum); 281 } 282 283 if (!SIMULATION_ON) 284 err = tty_write(fd, filter_command, CMD_SIZE, &nbytes); 285 265 286 266 287 FilterPositionNP.s = IPS_OK; … … 385 406 { 386 407 case ISS_ON: 408 if (SIMULATION_ON) 409 { 410 PowerSP.s = IPS_OK; 411 IDSetSwitch(&PowerSP, "Simulated Filter Wheel is online."); 412 return; 413 } 414 387 415 if ( (err = tty_connect(PortT[0].text, 9600, 8, 0, 1, &fd)) != TTY_OK) 388 416 { … … 394 422 } 395 423 424 396 425 PowerSP.s = IPS_OK; 397 426 IDSetSwitch(&PowerSP, "Filter Wheel is online. True Technology filter wheel suffers from several bugs. Please refer to http://indi.sf.net/profiles/trutech.html for more details."); … … 399 428 400 429 case ISS_OFF: 430 if (SIMULATION_ON) 431 { 432 PowerSP.s = IPS_OK; 433 IDSetSwitch(&PowerSP, "Simulated Filter Wheel is offline."); 434 return; 435 } 436 401 437 if ( (err = tty_disconnect(fd)) != TTY_OK) 402 438 { -
BAORadio/libindi/libindi/drivers/telescope/BAO.cpp
r499 r501 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 1 #if 0 2 3 ############################# 4 ## 5 ## BAORadio Indi driver 6 ## Franck RICHARD 7 ## Mai 2010 8 ## 9 ############################# 10 #endif 11 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <string.h> 15 #include <stdarg.h> 16 #include <math.h> 17 #include <unistd.h> 18 #include <time.h> 19 #include <memory> 20 #include <pthread.h> 21 #include <iostream> 22 #include <time.h> 23 #include <unistd.h> 24 #include <sys/time.h> 25 26 #include <config.h> 27 28 #include "indicom.h" 29 30 #include "Socket.h" 31 32 #include "BAO.h" 33 34 using namespace std; 35 36 auto_ptr<BAO> telescope(0); 37 38 const int POLLMS = 1; // Period of update, 1 ms. 39 40 const char *mydev = "BAO"; // Name of our device. 41 42 const char *BASIC_GROUP = "Main Control"; // Main Group 43 const char *OPTIONS_GROUP = "Options"; // Options Group 44 45 /* Handy Macros */ 46 //#define currentRA EquatorialCoordsRN[0].value 47 //#define currentDEC EquatorialCoordsRN[1].value 48 #define targetRA EquatorialCoordsWN[0].value 49 #define targetDEC EquatorialCoordsWN[1].value 50 51 52 static void ISPoll(void *); 53 54 static void retry_connection(void *); 55 56 /************************************************************************************** 57 ** 58 ***************************************************************************************/ 59 void *pThreadSocket (void * arg) 60 { 61 61 try 62 62 { 63 int pos = SocketsNumber;64 65 // Trouver éventuellement un emplacement disponible dans l'intervalle [1..SocketsNumber]66 67 /*68 for (int i=1; i<SocketsNumber; i++)69 {70 71 72 73 74 }75 }*/76 77 server.accept ( Sockets[pos].new_sock );78 79 Sockets[pos].IP=server.recupip(Sockets[pos].new_sock);80 81 Sockets[pos].Connected=true;82 83 if (pos == SocketsNumber ) SocketsNumber++;84 85 InitThreadOK=true;63 int pos = SocketsNumber; 64 65 // Trouver éventuellement un emplacement disponible dans l'intervalle [1..SocketsNumber] 66 67 /* 68 for (int i=1; i<SocketsNumber; i++) 69 { 70 if (!Sockets[i].Connected) 71 { 72 pos = i; 73 break; 74 } 75 }*/ 76 77 server.accept ( Sockets[pos].new_sock ); 78 79 Sockets[pos].IP=server.recupip(Sockets[pos].new_sock); 80 81 Sockets[pos].Connected=true; 82 83 if (pos == SocketsNumber ) SocketsNumber++; 84 85 InitThreadOK=true; 86 86 } 87 87 catch ( SocketException& e ) 88 88 { 89 //A activer pour vérif90 91 /*std::string oss;92 oss="pThreadSocket exception : " + e.description() + "\n";93 size_t size = oss.size() + 1;94 char* buffer = new char[size];95 strncpy(buffer, oss.c_str(), size);96 97 IDLog(buffer);98 99 delete [] buffer;*/100 } 101 89 //A activer pour vérif 90 91 /*std::string oss; 92 oss="pThreadSocket exception : " + e.description() + "\n"; 93 size_t size = oss.size() + 1; 94 char* buffer = new char[size]; 95 strncpy(buffer, oss.c_str(), size); 96 97 IDLog(buffer); 98 99 delete [] buffer;*/ 100 } 101 102 102 return NULL; 103 104 105 106 107 108 109 110 111 112 103 } 104 105 106 /************************************************************************************** 107 ** Utilisation d'un thread pour éviter de bloquer l'execution du pilote 108 ** avec la commande accept 109 ***************************************************************************************/ 110 111 void BAO::InitThread() 112 { 113 113 if (pthread_create (&th1, NULL, pThreadSocket, NULL) < 0) 114 114 { 115 IDLog("pthread_create error for threadSocket\n");116 } 117 115 IDLog("pthread_create error for threadSocket\n"); 116 } 117 118 118 pthread_join (th1, NULL); 119 120 121 122 123 124 125 119 } 120 121 /************************************************************************************** 122 ** Initialisation du pilote BAO 123 ***************************************************************************************/ 124 void ISInit() 125 { 126 126 static int isInit=0; 127 127 128 128 if (isInit) return; 129 129 130 130 if (telescope.get() == 0) telescope.reset(new BAO()); 131 131 132 132 isInit = 1; 133 133 134 134 IEAddTimer (POLLMS, ISPoll, NULL); 135 136 137 138 139 140 141 135 } 136 137 /************************************************************************************** 138 ** 139 ***************************************************************************************/ 140 void ISGetProperties (const char *dev) 141 { 142 142 ISInit(); 143 143 telescope->ISGetProperties(dev); 144 145 146 147 148 149 150 144 } 145 146 /************************************************************************************** 147 ** 148 ***************************************************************************************/ 149 void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) 150 { 151 151 ISInit(); 152 152 telescope->ISNewSwitch(dev, name, states, names, n); 153 154 155 156 157 158 159 153 } 154 155 /************************************************************************************** 156 ** 157 ***************************************************************************************/ 158 void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) 159 { 160 160 ISInit(); 161 161 telescope->ISNewText(dev, name, texts, names, n); 162 163 164 165 166 167 168 162 } 163 164 /************************************************************************************** 165 ** 166 ***************************************************************************************/ 167 void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) 168 { 169 169 ISInit(); 170 170 telescope->ISNewNumber(dev, name, values, names, n); 171 172 173 174 175 176 177 171 } 172 173 /************************************************************************************** 174 ** 175 ***************************************************************************************/ 176 void ISPoll (void *p) 177 { 178 178 INDI_UNUSED(p); 179 179 180 180 telescope->ISPoll(); 181 181 IEAddTimer (POLLMS, ISPoll, NULL); 182 183 184 185 186 187 188 189 182 } 183 184 185 /************************************************************************************** 186 ** 187 ***************************************************************************************/ 188 void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n) 189 { 190 190 INDI_UNUSED(dev); 191 191 INDI_UNUSED(name); … … 196 196 INDI_UNUSED(names); 197 197 INDI_UNUSED(n); 198 199 200 201 202 203 204 198 } 199 200 /************************************************************************************** 201 ** 202 ***************************************************************************************/ 203 void ISSnoopDevice (XMLEle *root) 204 { 205 205 INDI_UNUSED(root); 206 207 208 209 210 211 212 206 } 207 208 /************************************************************************************** 209 ** Initialisation de la classe BAO 210 ***************************************************************************************/ 211 BAO::BAO() 212 { 213 213 init_properties(); 214 214 215 215 ConnectSP.s = IPS_IDLE; 216 216 217 217 lastSet = -1; 218 218 fd = -1; … … 222 222 currentSet = 0; 223 223 JJAnc = 0.0; 224 224 225 225 SocketsNumber = 1; 226 226 227 227 ActualisationTM1 = 15.0*60.0; 228 228 229 229 ActualisationTM2 = 5.0; 230 230 231 231 InitThreadOK=false; 232 232 LecturePosition=false; … … 235 235 Goto=false; 236 236 LastGotoOK=true; 237 237 238 238 TrackingMode=1; 239 239 240 240 for (int i=0; i<MAXHOSTNAME; i++) 241 241 { 242 Sockets[i].Connected=false;243 Sockets[i].IP="";244 } 245 242 Sockets[i].Connected=false; 243 Sockets[i].IP=""; 244 } 245 246 246 InitAntennes(); 247 248 247 248 249 249 IDLog("Initilizing from BAO device...\n"); 250 IDLog("Driver Version: 2010- 05-12\n");251 250 IDLog("Driver Version: 2010-11-10\n"); 251 252 252 //enableSimulation(true); 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 253 } 254 255 /************************************************************************************** 256 ** 257 ***************************************************************************************/ 258 BAO::~BAO() 259 { 260 261 } 262 263 /************************************************************************************** 264 ** Initialisation des boutons et des zones d'affichage dans la boîte de dialogue INDI 265 ***************************************************************************************/ 266 void BAO::init_properties() 267 { 268 268 // Connection 269 269 IUFillSwitch(&ConnectS[0], "CONNECT", "Connect", ISS_OFF); 270 270 IUFillSwitch(&ConnectS[1], "DISCONNECT", "Disconnect", ISS_ON); 271 271 IUFillSwitchVector(&ConnectSP, ConnectS, NARRAY(ConnectS), mydev, "CONNECTION", "Connection", BASIC_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE); 272 272 273 273 // Coord Set 274 274 IUFillSwitch(&OnCoordSetS[0], "TRANSIT", "Transit", ISS_ON); 275 275 IUFillSwitch(&OnCoordSetS[1], "TRACKING", "Tracking", ISS_OFF); 276 276 IUFillSwitchVector(&OnCoordSetSP, OnCoordSetS, NARRAY(OnCoordSetS), mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE); 277 277 278 278 // Abort 279 279 IUFillSwitch(&AbortSlewS[0], "ABORT", "Abort", ISS_OFF); 280 280 IUFillSwitchVector(&AbortSlewSP, AbortSlewS, NARRAY(AbortSlewS), mydev, "ABORT_MOTION", "Abort", BASIC_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE); 281 281 282 282 // Park 283 283 IUFillSwitch(&ParkS[0], "PARK", "Park", ISS_OFF); 284 284 IUFillSwitchVector(&ParkSP, ParkS, NARRAY(ParkS), mydev, "", "Park", BASIC_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE); 285 285 286 286 // Object Name 287 287 IUFillText(&ObjectT[0], "OBJECT_NAME", "Name", "--"); 288 288 IUFillTextVector(&ObjectTP, ObjectT, NARRAY(ObjectT), mydev, "OBJECT_INFO", "Object", BASIC_GROUP, IP_RW, 0, IPS_IDLE); 289 290 289 290 291 291 // Equatorial Coords - SET 292 292 IUFillNumber(&EquatorialCoordsWN[0], "RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0.); 293 293 IUFillNumber(&EquatorialCoordsWN[1], "DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0.); 294 294 IUFillNumberVector(&EquatorialCoordsWNP, EquatorialCoordsWN, NARRAY(EquatorialCoordsWN), mydev, "EQUATORIAL_EOD_COORD_REQUEST" , "Equatorial JNow", BASIC_GROUP, IP_WO, 0, IPS_IDLE); 295 295 296 296 // Equatorial Coords - READ 297 297 // IUFillNumber(&EquatorialCoordsRN[0], "RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0.); 298 298 // IUFillNumber(&EquatorialCoordsRN[1], "DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0.); 299 299 // IUFillNumberVector(&EquatorialCoordsRNP, EquatorialCoordsRN, NARRAY(EquatorialCoordsRN), mydev, "EQUATORIAL_EOD_COORD" , "Equatorial JNow", BASIC_GROUP, IP_RO, 0, IPS_IDLE); 300 300 301 301 // Geographic coord - SET 302 302 IUFillNumber(&GeographicCoordsWN[0], "LAT", "Lat D", "%10.6m", -90., 90., 0., 0.); 303 303 IUFillNumber(&GeographicCoordsWN[1], "LONG", "Long D", "%10.6m", 0., 360., 0., 0.); 304 304 IUFillNumberVector(&GeographicCoordsWNP, GeographicCoordsWN, NARRAY(GeographicCoordsWN), mydev, "GEOGRAPHIC_COORD" , "Geographic coords", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE); 305 305 306 306 // Actualisation - SET 307 307 IUFillNumber(&ActualisationN1[0], "DELAY", "Transit mode delay (Sec)", "%10.6m", 0., 3600., 0., 0.); 308 308 IUFillNumberVector(&ActualisationNP1, ActualisationN1, NARRAY(ActualisationN1), mydev, "DELAY1" , "", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE); 309 309 310 310 IUFillNumber(&ActualisationN2[0], "DELAY", "Tracking mode delay (Sec)", "%10.6m", 0., 3600., 0., 0.); 311 311 IUFillNumberVector(&ActualisationNP2, ActualisationN2, NARRAY(ActualisationN2), mydev, "DELAY2" , "", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE); 312 312 313 313 // Transit threshold 314 314 //IUFillNumber(&SlewAccuracyN[0], "TransitRA", "RA (arcmin)", "%10.6m", 0., 60., 1., 3.0); 315 315 //IUFillNumber(&SlewAccuracyN[1], "TransitDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0); 316 316 //IUFillNumberVector(&SlewAccuracyNP, SlewAccuracyN, NARRAY(SlewAccuracyN), mydev, "Transit Accuracy", "", OPTIONS_GROUP, IP_RW, 0, IPS_IDLE); 317 317 318 318 // Tracking threshold 319 319 //IUFillNumber(&TrackAccuracyN[0], "TrackingRA", "RA (arcmin)", "%10.6m", 0., 60., 1., 3.0); 320 320 //IUFillNumber(&TrackAccuracyN[1], "TrackingDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0); 321 321 //IUFillNumberVector(&TrackAccuracyNP, TrackAccuracyN, NARRAY(TrackAccuracyN), mydev, "Tracking Accuracy", "", OPTIONS_GROUP, IP_RW, 0, IPS_IDLE); 322 323 324 325 326 327 328 329 330 322 323 } 324 325 /************************************************************************************** 326 ** Initialisation de la boîte de dialogue INDI (suite) 327 ***************************************************************************************/ 328 void BAO::ISGetProperties(const char *dev) 329 { 330 331 331 if (dev && strcmp (mydev, dev)) 332 return;333 332 return; 333 334 334 // Main Control 335 335 IDDefSwitch(&ConnectSP, NULL); … … 341 341 IDDefSwitch(&AbortSlewSP, NULL); 342 342 IDDefSwitch(&ParkSP, NULL); 343 343 344 344 // Options 345 345 //IDDefNumber(&SlewAccuracyNP, NULL); 346 //IDDefNumber(&TrackAccuracyNP, NULL); 346 //IDDefNumber(&TrackAccuracyNP, NULL); 347 347 IDDefNumber(&ActualisationNP1, NULL); 348 348 IDDefNumber(&ActualisationNP2, NULL); 349 350 351 352 353 354 355 356 349 350 } 351 352 /************************************************************************************** 353 ** En cas de changement de texte dans la boîte de dialogue 354 ***************************************************************************************/ 355 void BAO::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) 356 { 357 357 // Ignore if not ours 358 358 if (strcmp (dev, mydev)) 359 return;360 359 return; 360 361 361 if (is_connected() == false) 362 362 { 363 IDMessage(mydev, "BAORadio.Please connect before issuing any commands.");364 reset_all_properties();365 return;366 } 367 363 IDMessage(mydev, "Error ! Please connect before issuing any commands."); 364 reset_all_properties(); 365 return; 366 } 367 368 368 // =================================== 369 369 // Object Name … … 371 371 if (!strcmp (name, ObjectTP.name)) 372 372 { 373 if (IUUpdateText(&ObjectTP, texts, names, n) < 0)374 375 376 ObjectTP.s = IPS_OK;377 IDSetText(&ObjectTP, NULL);378 return;379 } 380 381 382 383 384 385 386 387 373 if (IUUpdateText(&ObjectTP, texts, names, n) < 0) 374 return; 375 376 ObjectTP.s = IPS_OK; 377 IDSetText(&ObjectTP, NULL); 378 return; 379 } 380 } 381 382 /************************************************************************************** 383 ** En cas de changement d'une valeur numérique dans la boîte de dialogue Indi 384 ***************************************************************************************/ 385 void BAO::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) 386 { 387 388 388 // Ignore if not ours 389 389 if (strcmp (dev, mydev)) 390 return;391 390 return; 391 392 392 if (is_connected() == false) 393 393 { 394 IDMessage(mydev, "BAO is offline. Please connect before issuing any commands.");395 reset_all_properties();396 return;397 } 398 399 394 IDMessage(mydev, "Error ! BAO is offline. Please connect before issuing any commands."); 395 reset_all_properties(); 396 return; 397 } 398 399 400 400 // =================================== 401 401 // Geographic Coords … … 403 403 if (!strcmp (name, GeographicCoordsWNP.name)) 404 404 { 405 int i=0, nset=0, error_code=0;406 407 Latitude=0.0;408 Longitude=0.0;409 410 for (nset = i = 0; i < n; i++)411 {412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 }428 429 if (nset == 2)430 {431 432 433 434 435 436 }437 else438 {439 440 441 442 443 444 }445 446 return;447 } 448 449 405 int i=0, nset=0, error_code=0; 406 407 Latitude=0.0; 408 Longitude=0.0; 409 410 for (nset = i = 0; i < n; i++) 411 { 412 INumber *eqp = IUFindNumber (&GeographicCoordsWNP, names[i]); 413 if (eqp == &GeographicCoordsWN[0]) 414 { 415 Latitude = values[i]; 416 nset += Latitude >= -90.0 && Latitude <= 90.0; 417 418 Latitude*=Pidiv180; 419 } 420 else if (eqp == &GeographicCoordsWN[1]) 421 { 422 Longitude = values[i]; 423 nset += Longitude >= 0.0 && Longitude <= 360.0; 424 425 Longitude*=-Pidiv180; 426 } 427 } 428 429 if (nset == 2) 430 { 431 //Vérification 432 //IDLog("Geographic : RA %5.2f - DEC %5.2f\n", Latitude, Longitude); 433 434 GeographicCoordsWNP.s = IPS_OK; 435 IDSetNumber(&GeographicCoordsWNP, NULL); 436 } 437 else 438 { 439 GeographicCoordsWNP.s = IPS_ALERT; 440 IDSetNumber(&GeographicCoordsWNP, "Latitude or Longitude missing or invalid"); 441 442 Latitude=0.0; 443 Longitude=0.0; 444 } 445 446 return; 447 } 448 449 450 450 // =================================== 451 451 // Equatorial Coords … … 453 453 if (!strcmp (name, EquatorialCoordsWNP.name)) 454 454 { 455 int i=0, nset=0, error_code=0;456 double newRA =0, newDEC =0;457 458 for (nset = i = 0; i < n; i++)459 {460 461 462 463 newRA = values[i]; 464 465 466 467 468 469 470 471 }472 473 targetRA = newRA;474 targetDEC = newDEC;475 476 if (nset == 2)477 {478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 }497 else498 {499 500 IDSetNumber(&EquatorialCoordsWNP, "RA or Dec missing or invalid");501 }502 503 return;504 } 505 455 int i=0, nset=0, error_code=0; 456 double newRA =0, newDEC =0; 457 458 for (nset = i = 0; i < n; i++) 459 { 460 INumber *eqp = IUFindNumber (&EquatorialCoordsWNP, names[i]); 461 if (eqp == &EquatorialCoordsWN[0]) 462 { 463 newRA = values[i]; 464 nset += newRA >= 0 && newRA <= 24.0; 465 } 466 else if (eqp == &EquatorialCoordsWN[1]) 467 { 468 newDEC = values[i]; 469 nset += newDEC >= -90.0 && newDEC <= 90.0; 470 } 471 } 472 473 targetRA = newRA; 474 targetDEC = newDEC; 475 476 if (nset == 2) 477 { 478 char RAStr[32], DecStr[32]; 479 double targetAZ, targetAlt; 480 481 fs_sexa(RAStr, newRA, 2, 3600); 482 fs_sexa(DecStr, newDEC, 2, 3600); 483 484 IDLog("We received JNow RA %s - DEC %s\n", RAStr, DecStr); 485 486 // on convertit les coordonnées équatoriales de la zone du ciel observée 487 // en unités de codeurs des moteurs 488 489 ADDEC2Motor(newRA, newDEC); 490 491 if (process_coords() == false) 492 { 493 EquatorialCoordsWNP.s = IPS_ALERT; 494 IDSetNumber(&EquatorialCoordsWNP, NULL); 495 } 496 } 497 else 498 { 499 EquatorialCoordsWNP.s = IPS_ALERT; 500 IDSetNumber(&EquatorialCoordsWNP, "Error ! RA or Dec missing or invalid"); 501 } 502 503 return; 504 } 505 506 506 // =================================== 507 507 // Actualisation … … 509 509 if (!strcmp (name, ActualisationNP1.name)) 510 510 { 511 int i=0, nset=0, error_code=0; 512 double newAct1 =0; 513 514 for (nset = i = 0; i < n; i++) 515 { 516 INumber *eqp = IUFindNumber (&ActualisationNP1, names[i]); 517 if (eqp == &ActualisationN1[0]) 518 { 519 newAct1 = values[i]; 520 521 if (newAct1 >= 0.0 && newAct1 <= 3600.0) 522 { 523 ActualisationTM1=newAct1; 524 525 ActualisationNP1.s = IPS_OK; 526 IDSetNumber(&ActualisationNP1, NULL); 527 } 528 else 529 { 530 ActualisationNP1.s = IPS_ALERT; 531 IDSetNumber(&ActualisationNP1, "Delay invalid"); 532 } 533 } 534 } 535 536 } 537 511 int i=0, nset=0, error_code=0; 512 double newAct1 =0; 513 514 for (nset = i = 0; i < n; i++) 515 { 516 INumber *eqp = IUFindNumber (&ActualisationNP1, names[i]); 517 if (eqp == &ActualisationN1[0]) 518 { 519 newAct1 = values[i]; 520 521 if (newAct1 >= 0.0 && newAct1 <= 3600.0) 522 { 523 ActualisationTM1=newAct1; 524 525 ActualisationNP1.s = IPS_OK; 526 IDSetNumber(&ActualisationNP1, NULL); 527 } 528 else 529 { 530 ActualisationNP1.s = IPS_ALERT; 531 IDSetNumber(&ActualisationNP1, "Error ! Delay invalid"); 532 } 533 } 534 } 535 } 536 538 537 if (!strcmp (name, ActualisationNP2.name)) 539 538 { 540 int i=0, nset=0, error_code=0;541 double newAct2 =0;542 543 for (nset = i = 0; i < n; i++)544 {545 546 547 548 549 550 551 552 553 554 555 556 }557 else558 {559 560 IDSetNumber(&ActualisationNP2, "Delay invalid");561 }562 563 }564 539 int i=0, nset=0, error_code=0; 540 double newAct2 =0; 541 542 for (nset = i = 0; i < n; i++) 543 { 544 INumber *eqp = IUFindNumber (&ActualisationNP2, names[i]); 545 if (eqp == &ActualisationN2[0]) 546 { 547 newAct2 = values[i]; 548 549 if (newAct2 >= 0.0 && newAct2 <= 3600.0) 550 { 551 ActualisationTM2=newAct2; 552 553 ActualisationNP2.s = IPS_OK; 554 IDSetNumber(&ActualisationNP2, NULL); 555 } 556 else 557 { 558 ActualisationNP2.s = IPS_ALERT; 559 IDSetNumber(&ActualisationNP2, "Error ! Delay invalid"); 560 } 561 } 562 } 563 565 564 } /* end EquatorialCoordsWNP */ 566 567 568 569 570 571 572 565 } 566 567 /************************************************************************************** 568 ** L'utilisateur clique sur l'un des boutons de la boîte Indi 569 ***************************************************************************************/ 570 void BAO::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) 571 { 573 572 // ignore if not ours // 574 573 if (strcmp (mydev, dev)) 575 return;576 574 return; 575 577 576 // =================================== 578 577 // Connect Switch … … 580 579 if (!strcmp (name, ConnectSP.name)) 581 580 { 582 if (IUUpdateSwitch(&ConnectSP, states, names, n) < 0)583 584 585 connect_telescope();586 return;587 } 588 581 if (IUUpdateSwitch(&ConnectSP, states, names, n) < 0) 582 return; 583 584 connect_telescope(); 585 return; 586 } 587 589 588 if (is_connected() == false) 590 589 { 591 IDMessage(mydev, "BAORadio is offline. Please connect before issuing any commands.");592 reset_all_properties();593 return;594 } 595 590 IDMessage(mydev, "Error ! BAORadio is offline. Please connect before issuing any commands."); 591 reset_all_properties(); 592 return; 593 } 594 596 595 // =================================== 597 596 // Coordinate Set … … 599 598 if (!strcmp(name, OnCoordSetSP.name)) 600 599 { 601 if (IUUpdateSwitch(&OnCoordSetSP, states, names, n) < 0)602 603 604 currentSet = get_switch_index(&OnCoordSetSP);605 OnCoordSetSP.s = IPS_OK;606 IDSetSwitch(&OnCoordSetSP, NULL);607 } 608 600 if (IUUpdateSwitch(&OnCoordSetSP, states, names, n) < 0) 601 return; 602 603 currentSet = get_switch_index(&OnCoordSetSP); 604 OnCoordSetSP.s = IPS_OK; 605 IDSetSwitch(&OnCoordSetSP, NULL); 606 } 607 609 608 // =================================== 610 609 // Abort slew … … 612 611 if (!strcmp (name, AbortSlewSP.name)) 613 612 { 614 Abort=true;615 616 IUResetSwitch(&AbortSlewSP);617 618 /*619 if (EquatorialCoordsWNP.s == IPS_BUSY)620 {621 622 623 624 625 626 627 628 629 630 }631 */632 return;633 } 634 635 613 Abort=true; 614 615 IUResetSwitch(&AbortSlewSP); 616 617 /* 618 if (EquatorialCoordsWNP.s == IPS_BUSY) 619 { 620 621 AbortSlewSP.s = IPS_OK; 622 EquatorialCoordsWNP.s = IPS_IDLE; 623 EquatorialCoordsRNP.s = IPS_IDLE; 624 HorizontalCoordsWNP.s = IPS_IDLE; 625 IDSetSwitch(&AbortSlewSP, "Slew aborted."); 626 IDSetNumber(&EquatorialCoordsWNP, NULL); 627 IDSetNumber(&EquatorialCoordsRNP, NULL); 628 IDSetNumber(&HorizontalCoordsWNP, NULL); 629 } 630 */ 631 return; 632 } 633 634 636 635 // =================================== 637 636 // Park … … 639 638 if (!strcmp (name, ParkSP.name)) 640 639 { 641 Park=true;642 643 IUResetSwitch(&ParkSP);644 645 /*646 if (EquatorialCoordsWNP.s == IPS_BUSY)647 {648 649 650 651 652 653 654 655 656 657 }658 */659 return;660 } 661 662 663 664 665 666 667 640 Park=true; 641 642 IUResetSwitch(&ParkSP); 643 644 /* 645 if (EquatorialCoordsWNP.s == IPS_BUSY) 646 { 647 648 AbortSlewSP.s = IPS_OK; 649 EquatorialCoordsWNP.s = IPS_IDLE; 650 EquatorialCoordsRNP.s = IPS_IDLE; 651 HorizontalCoordsWNP.s = IPS_IDLE; 652 IDSetSwitch(&AbortSlewSP, "Slew aborted."); 653 IDSetNumber(&EquatorialCoordsWNP, NULL); 654 IDSetNumber(&EquatorialCoordsRNP, NULL); 655 IDSetNumber(&HorizontalCoordsWNP, NULL); 656 } 657 */ 658 return; 659 } 660 } 661 662 /************************************************************************************** 663 ** fct peut-être inutile 664 ***************************************************************************************/ 665 void BAO::handle_error(INumberVectorProperty *nvp, int err, const char *msg) 666 { 668 667 nvp->s = IPS_ALERT; 669 668 670 669 /* If the error is a time out, then the device doesn't support this property */ 671 670 if (err == -2) 672 671 { 673 nvp->s = IPS_ALERT;674 IDSetNumber(nvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);672 nvp->s = IPS_ALERT; 673 IDSetNumber(nvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg); 675 674 } 676 675 else 677 /* Changing property failed, user should retry. */678 IDSetNumber( nvp , "%s failed.", msg);679 676 /* Changing property failed, user should retry. */ 677 IDSetNumber( nvp , "%s failed.", msg); 678 680 679 fault = true; 681 682 683 684 685 686 687 680 } 681 682 /************************************************************************************** 683 ** Initialisation des vecteurs INDI 684 ***************************************************************************************/ 685 void BAO::reset_all_properties() 686 { 688 687 ConnectSP.s = IPS_IDLE; 689 688 OnCoordSetSP.s = IPS_IDLE; … … 698 697 ActualisationNP1.s = IPS_IDLE; 699 698 ActualisationNP2.s = IPS_IDLE; 700 699 701 700 IUResetSwitch(&OnCoordSetSP); 702 701 IUResetSwitch(&AbortSlewSP); 703 702 IUResetSwitch(&ParkSP); 704 703 705 704 OnCoordSetS[0].s = ISS_ON; 706 705 ConnectS[0].s = ISS_OFF; 707 706 ConnectS[1].s = ISS_ON; 708 707 709 708 IDSetSwitch(&ConnectSP, NULL); 710 709 IDSetSwitch(&OnCoordSetSP, NULL); … … 719 718 IDSetNumber(&ActualisationNP1, NULL); 720 719 IDSetNumber(&ActualisationNP2, NULL); 721 722 723 724 725 726 727 728 720 721 } 722 723 /************************************************************************************** 724 ** 725 ***************************************************************************************/ 726 void BAO::correct_fault() 727 { 729 728 fault = false; 730 729 IDMessage(mydev, "Telescope is online."); 731 732 733 734 735 736 737 730 } 731 732 /************************************************************************************** 733 ** 734 ***************************************************************************************/ 735 bool BAO::is_connected() 736 { 738 737 if (simulation) return true; 739 738 740 739 // return (ConnectSP.sp[0].s == ISS_ON); 741 740 return (ConnectSP.s == IPS_OK); 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 741 } 742 743 /************************************************************************************** 744 ** 745 ***************************************************************************************/ 746 static void retry_connection(void * p) 747 { 748 749 } 750 751 752 /************************************************************************************** 753 ** Extraction de la position de l'antenne 754 ** dans le retour de la commande POS 755 ** POS/Valeur az/Valeur alt 756 ***************************************************************************************/ 757 758 Position BAO::ExtractPosition(std::string str) 759 { 761 760 Position result; 762 761 763 762 std::string str2; 764 763 765 764 result.x = -1; 766 765 result.y = -1; 767 766 768 767 int pos = str.find("/"); 769 768 770 769 if (pos != string::npos) 771 770 { 772 str2 = str.substr(pos+1);773 774 pos = str2.find("/");775 776 if (pos != string::npos)777 {778 779 780 781 }782 } 783 771 str2 = str.substr(pos+1); 772 773 pos = str2.find("/"); 774 775 if (pos != string::npos) 776 { 777 result.x = atoi(str2.substr(0, pos).c_str()); 778 779 result.y = atoi(str2.substr(pos+1).c_str()); 780 } 781 } 782 784 783 return result; 785 786 787 788 789 790 791 792 793 794 784 } 785 786 787 788 /************************************************************************************ 789 * cette procédure convertit les coordonnées equatoriales de l'objet visé 790 * en unités de codeurs des paraboles (nb de tours des deux axes moteurs depuis la position PARK) 791 ************************************************************************************/ 792 void BAO::ADDEC2Motor(double newRA, double newDEC) 793 { 795 794 double targetAz; 796 795 double targetAlt; 797 796 char AzStr[32]; 798 797 char AltStr[32]; 799 798 800 799 // Calcule la hauteur et l'azimut de la zone du ciel pointée (en fonction de la date et du lieu) 801 800 802 801 Azimut(tsl, Latitude, newRA * 15.0 * Pidiv180, newDEC * Pidiv180, &targetAz, &targetAlt); 803 802 804 803 // En degrés 805 804 806 805 targetAlt *= N180divPi; 807 806 targetAz *= N180divPi; 808 807 809 808 // Affichage dans les logs 810 809 811 810 fs_sexa(AzStr, targetAz, 2, 3600); 812 811 fs_sexa(AltStr, targetAlt, 2, 3600); 813 812 814 813 IDLog("Horizontal coords : az %s - Alt %s\n", AzStr, AltStr); 815 814 816 815 // Le calcul est ici trÚs sommaire et arbitraire : 817 816 // Je considÚre qu'il y a 100 positions possibles sur les deux axes 818 817 // De plus, je considÚre qu'il n'est pas possible de viser un objet à 819 818 // moins de 30° de hauteur au-dessus de l'horizon 820 819 821 820 TargetPosition.x=(int)(targetAz*100.0/360.0); 822 821 823 822 targetAlt=((90.0-targetAlt)/60.0); 824 825 if (targetAlt>=1.0) 826 { 827 828 829 830 IDSetSwitch(&OnCoordSetSP, "Erreur : l objet suivi est situé à moins de 30° en-dessus de l horizon. Goto annulé.");831 832 833 834 835 836 837 } 838 823 824 if (targetAlt>=1.0) 825 { 826 targetAlt=1.0; //on ne peut pas viser un objet situé à moins de 30° 827 //au-dessus de l'horizon 828 829 IDSetSwitch(&OnCoordSetSP, "Erreur ! L objet suivi est situe a moins de 30° au-dessus de l horizon. Goto annule."); 830 831 Goto=false; 832 833 LecturePosition=false; 834 835 InitAntennes(); 836 } 837 839 838 TargetPosition.y=(int)(100.0*targetAlt); 840 841 842 843 844 845 846 847 848 849 839 } 840 841 842 /************************************************************************************ 843 * Retourne simplement le nombre d'antennes connectées 844 * et capables de communiquer 845 ************************************************************************************/ 846 847 int BAO::AntennesConnectees() 848 { 850 849 int num=0; 851 850 852 851 for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected) num++; 853 852 854 853 return num; 855 856 857 858 859 860 861 862 863 854 } 855 856 857 /************************************************************************************ 858 * Initialisation des paramÚtres des antennes 859 * 860 ************************************************************************************/ 861 void BAO::InitAntennes() 862 { 864 863 for (int i=0; i < MAXHOSTNAME ; i++) 865 864 { 866 Sockets[i].status=0;867 Sockets[i].sendalertes=0;868 Sockets[i].AttenteExecution=0;869 Sockets[i].AnomaliesExecution=0;870 Sockets[i].etape=0;871 872 Sockets[i].ack_status=false;873 Sockets[i].ack_pos=false;874 Sockets[i].ack_park=false;875 Sockets[i].ack_abort=false;876 Sockets[i].ack_goto=false;877 878 Sockets[i].PosValides=false;879 Sockets[i].GotoOk=false;880 } 881 882 883 884 885 886 887 888 889 865 Sockets[i].status=0; 866 Sockets[i].sendalertes=0; 867 Sockets[i].AttenteExecution=0; 868 Sockets[i].AnomaliesExecution=0; 869 Sockets[i].etape=0; 870 871 Sockets[i].ack_status=false; 872 Sockets[i].ack_pos=false; 873 Sockets[i].ack_park=false; 874 Sockets[i].ack_abort=false; 875 Sockets[i].ack_goto=false; 876 877 Sockets[i].PosValides=false; 878 Sockets[i].GotoOk=false; 879 } 880 } 881 882 883 /************************************************************************************** 884 ** Procédure principale 885 ** Elle est appelée toutes les POLLMS ms (ici 1 ms) 886 ***************************************************************************************/ 887 void BAO::ISPoll() 888 { 890 889 static bool ISPOLLRunning=false; 891 890 static int memSocketsNumber=-1; 892 891 static unsigned int compt=100; 893 892 894 893 int pos; 895 894 896 895 struct tm date; 897 896 time_t t; 898 897 struct timeval tv; 899 898 struct timezone tz; 900 899 901 900 if (is_connected() == false) return; 902 901 903 902 if (ISPOLLRunning) return; 904 903 905 904 ISPOLLRunning=true; 906 905 907 906 compt++; 908 909 907 908 910 909 //toutes les 100 millisec 911 910 912 911 if ( compt%100 == 0) 913 912 { 914 //Récupération de la date et de l'heure915 916 time(&t);917 date=*gmtime(&t);918 gettimeofday(&tv, &tz);919 920 Annee=(double)(date.tm_year+1900);921 Mois=(double)(date.tm_mon+1);922 Jour=(double)date.tm_mday;923 Heu=(double)date.tm_hour;924 Min=(double)date.tm_min;925 Sec=(double)date.tm_sec+tv.tv_usec/1.0E6;926 UTCP=0.0;//(double)date.tm_isdst;927 928 929 //Calcul du temps sidéral local930 931 CalculTSL();932 933 934 //Y a-t-il de nouvelles tentatives de connexion sur le serveur ?935 936 InitThread();937 } 938 939 940 941 913 //Récupération de la date et de l'heure 914 915 time(&t); 916 date=*gmtime(&t); 917 gettimeofday(&tv, &tz); 918 919 Annee=(double)(date.tm_year+1900); 920 Mois=(double)(date.tm_mon+1); 921 Jour=(double)date.tm_mday; 922 Heu=(double)date.tm_hour; 923 Min=(double)date.tm_min; 924 Sec=(double)date.tm_sec+tv.tv_usec/1.0E6; 925 UTCP=0.0;//(double)date.tm_isdst; 926 927 928 //Calcul du temps sidéral local 929 930 CalculTSL(); 931 932 933 //Y a-t-il de nouvelles tentatives de connexion sur le serveur ? 934 935 InitThread(); 936 } 937 938 939 940 942 941 if (InitThreadOK) // Il faut qu'il y ait eu au moins une connexion détectée par le thread pour continuer 943 942 { 944 945 // Nouvelle connexion sur le socket ! 946 947 if (SocketsNumber>memSocketsNumber) 948 { 949 memSocketsNumber=SocketsNumber; 950 951 IDSetSwitch(&ConnectSP, "Connexion de l antenne %s. (Antennes connectées : %i)", 952 Sockets[SocketsNumber-1].IP.c_str(), AntennesConnectees()); 953 } 954 955 956 957 // Début des échanges avec les microcontrÃŽleurs 958 959 // Analyse des réponses des microcontrÃŽleurs 960 961 for (int i=1; i<SocketsNumber; i++) /*if (Sockets[i].Connected)*/ 962 { 963 try 964 { 965 std::string reponse, memreponse; 966 // on récupÚre la réponse du microcontrÃŽleur 967 968 Sockets[i].new_sock >> reponse; 969 970 //IDSetSwitch(&OnCoordSetSP, "Réponse ISPOLL : %s\n", reponse.c_str()); // pour vérif 971 972 //Dans le cas où plusieurs trames seraient arrivées entre deux appels de POLLMS 973 //les traiter successivement 974 975 pos=reponse.find("\n"); // d'où l'intérêt de mettre un '\n' à la fin des trames 976 //pour différencier une trame de la précédente 977 while ((pos!=string::npos) && (reponse.length()>1)) 978 { 979 memreponse=reponse.substr(pos+1); 980 981 reponse=reponse.substr(0, pos); 982 983 984 // On traite ici les acknowledges 985 986 if ((reponse.find("ACK")!=string::npos) && (reponse.find("NACK")==string::npos)) 987 { 988 if (reponse.find("POS")!=string::npos) 989 { 990 Sockets[i].ack_pos=true; 991 } 992 else if (reponse.find("GOTO")!=string::npos) 993 { 994 Sockets[i].ack_goto=true; 995 } 996 else if (reponse.find("PARK")!=string::npos) 997 { 998 Sockets[i].ack_park=true; 999 } 1000 else if (reponse.find("ABORT")!=string::npos) 1001 { 1002 Sockets[i].ack_abort=true; 1003 } 1004 } 1005 else 1006 { 1007 1008 //réponse à la requête POSITION 1009 if (reponse.find("POS")!=string::npos) 1010 { 1011 if (reponse.find("NACK")!=string::npos) 1012 { 1013 OnCoordSetSP.s = IPS_ALERT; 1014 IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : position de l antenne inconnue !\n", 1015 Sockets[i].IP.c_str()); 1016 Sockets[i].PosValides=false; 1017 // Si la position de l'antenne est inconnue, on déconnecte l'antenne 1018 Sockets[i].Connected=false; 1019 } 1020 else if (Sockets[i].ack_pos) 1021 { 1022 OnCoordSetSP.s = IPS_OK; 1023 Sockets[i].Pos = ExtractPosition(reponse); 1024 Sockets[i].PosValides = true; 1025 IDSetSwitch(&ParkSP, "Antenne %s : POSITION OK (x=%i, y=%i)\n", 1026 Sockets[i].IP.c_str(), Sockets[i].Pos.x, Sockets[i].Pos.y); 1027 } 1028 1029 }//réponse à la requête PARK 1030 else if (reponse.find("PARK")!=string::npos) 1031 { 1032 if (reponse.find("NACK")!=string::npos) 1033 { 1034 ParkSP.s = IPS_ALERT; 1035 IDSetSwitch(&ParkSP, "ALERTE antenne %s : erreur PARK !\n", Sockets[i].IP.c_str()); 1036 } 1037 else if (reponse.find("OK")!=string::npos) 1038 { 1039 ParkSP.s = IPS_OK; 1040 IDSetSwitch(&ParkSP, "Antenne %s : PARK OK\n", Sockets[i].IP.c_str()); 1041 } 1042 1043 }//réponse à la requête ABORT 1044 else if (reponse.find("ABORT")!=string::npos) 1045 { 1046 if (reponse.find("NACK")!=string::npos) 1047 { 1048 AbortSlewSP.s = IPS_ALERT; 1049 IDSetSwitch(&AbortSlewSP, "ALERTE antenne %s : erreur ABORT !\n", Sockets[i].IP.c_str()); 1050 } 1051 1052 if (reponse.find("OK")!=string::npos) 1053 { 1054 AbortSlewSP.s = IPS_OK; 1055 IDSetSwitch(&AbortSlewSP, "Antenne %s : ABORT OK\n", Sockets[i].IP.c_str()); 1056 } 1057 1058 } //réponse à la requête GOTO 1059 else if (reponse.find("GOTO")!=string::npos) 1060 { 1061 if (reponse.find("NACK")!=string::npos) 1062 { 1063 OnCoordSetSP.s = IPS_ALERT; 1064 IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : Erreur GOTO !\n", Sockets[i].IP.c_str()); 1065 Sockets[i].Connected=false; 1066 } 1067 else if (Sockets[i].ack_goto) 1068 { 1069 if (reponse.find("OK")!=string::npos) 1070 { 1071 OnCoordSetSP.s = IPS_OK; 1072 1073 Sockets[i].GotoOk=true; 1074 1075 IDSetSwitch(&ParkSP, "Antenne %s : GOTO OK.\n", Sockets[i].IP.c_str()); 1076 1077 lastRA = targetRA; 1078 lastDEC = targetDEC; 1079 1080 //IDLog("We received JNow RA %s - DEC %s\n", RAStr, DecStr);*/ 1081 1082 EquatorialCoordsWNP.s = IPS_OK; 1083 IDSetNumber (&EquatorialCoordsWNP, NULL); 1084 1085 // Fin du Goto pour toutes les antennes ? 1086 1087 int num=0; 1088 1089 for (int j=1; j<SocketsNumber; j++) if (Sockets[j].Connected) 1090 { 1091 if (Sockets[j].GotoOk) num++; 1092 } 1093 1094 if ((num == AntennesConnectees()) && (num>0)) 1095 { 1096 LecturePosition=false; 1097 1098 InitAntennes(); 1099 1100 LastGotoOK=true; 1101 1102 IDSetSwitch(&OnCoordSetSP, "GOTO OK !"); 1103 } 1104 } 1105 } 1106 } 1107 } 1108 1109 // On passe éventuellement à la trame suivante 1110 1111 reponse=memreponse; 1112 pos=reponse.find("\n"); 1113 1114 } 1115 } 1116 catch (SocketException& e) //Aïe 1117 { 1118 Sockets[i].new_sock.shutdown(); 1119 Sockets[i].new_sock.create(); 1120 Sockets[i].Connected = Sockets[i].new_sock.connect((std::string)Sockets[i].IP); 1121 1122 if (Sockets[i].Connected) 1123 { 1124 Sockets[i].AttenteExecution=0; 1125 Sockets[i].AnomaliesExecution=0; 1126 } 1127 1128 std::string oss; 1129 oss="SocketException IsPoll : " + e.description() + "\n"; 1130 size_t size = oss.size() + 1; 1131 char* buffer = new char[size]; 1132 strncpy(buffer, oss.c_str(), size); 1133 IDLog(buffer); 1134 delete [] buffer; 1135 } 1136 } 1137 1138 1139 1140 if (Abort) 1141 { 1142 IDSetSwitch(&ConnectSP, "Envoi de la commande Abort\n"); 1143 1144 Goto=false; 1145 1146 for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected) 1147 { 1148 if (!ABORT(i)) Sockets[i].sendalertes++; 1149 } 1150 1151 LecturePosition=false; 1152 1153 InitAntennes(); 1154 1155 Abort=false; 1156 } 1157 1158 1159 if (Park) 1160 { 1161 IDSetSwitch(&ConnectSP, "Envoi de la commande Park\n"); 1162 1163 Goto=false; 1164 1165 for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected) 1166 { 1167 if (!PARK(i)) Sockets[i].sendalertes++; 1168 } 1169 1170 LecturePosition=false; 1171 1172 InitAntennes(); 1173 1174 Park=false; 1175 } 1176 1177 1178 // Gestion du suivi 1179 1180 if ((Goto) && (LastGotoOK)) 1181 { 1182 // Durée entre deux actualisations 1183 1184 double delai=ActualisationTM1/3600.0/24.0; // Actualisation toutes les 15 minutes en mode transit 1185 1186 if (TrackingMode==2) delai=ActualisationTM2/3600.0/24.0; //et 5 secs en mode tracking 1187 1188 1189 // On actualise la position 1190 1191 if (JJ-JJAnc > delai) 1192 { 1193 1194 LastGotoOK=false; 1195 1196 LecturePosition=true; 1197 1198 ADDEC2Motor(targetRA, targetDEC); 1199 1200 InitAntennes(); 1201 1202 JJAnc=JJ; 1203 } 1204 1205 //Plus d'antenne ! 1206 1207 if (AntennesConnectees() == 0) 1208 { 1209 // LecturePosition=false; 1210 1211 // Goto=false; 1212 1213 // InitAntennes(); 1214 1215 if ( compt % 1000 == 0) IDSetSwitch(&OnCoordSetSP, "Erreur ! Plus d antennes connectées !"); 1216 } 1217 } 1218 1219 1220 1221 // Exécution de la procédure complÚte de lecture de la position de l'antenne 1222 // puis envoi d'une commande Goto 1223 1224 if (LecturePosition) 1225 { 1226 for (int i=1; i<SocketsNumber; i++) /*if (Sockets[i].Connected)*/ 1227 { 1228 switch (Sockets[i].etape) 1229 { 1230 1231 //Envoi de la commande POS 1232 case 0 : 1233 { 1234 Sockets[i].ack_pos=false; 1235 Sockets[i].PosValides=false; 1236 1237 if (!POSITION(i)) Sockets[i].sendalertes++; 1238 1239 Sockets[i].etape++; 1240 } 1241 break; 1242 1243 //ack POS 1244 case 1 : 1245 { 1246 if (Sockets[i].ack_pos) 1247 { 1248 Sockets[i].AttenteExecution=0; 1249 Sockets[i].AnomaliesExecution=0; 1250 Sockets[i].etape++; 1251 i--; 1252 } 1253 else 1254 { 1255 // on réitÚre l'ordre précédent si rien ne se passe 1256 1257 Sockets[i].AttenteExecution++; 1258 1259 if (Sockets[i].AttenteExecution>MAXATTENTE) 1260 { 1261 Sockets[i].etape=0; 1262 Sockets[i].AttenteExecution=0; 1263 Sockets[i].AnomaliesExecution++; 1264 } 1265 1266 if (Sockets[i].AnomaliesExecution>MAXANOMALIES) 1267 { 1268 Sockets[i].etape=3; 1269 1270 // if ( compt % 1000 == 0) 1271 { 1272 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s. Pas d acknowledge reçu aprÚs l ordre POSITION. Déconnexion de l antenne.", 1273 Sockets[i].IP.c_str()); 1274 Sockets[i].Connected=false; 1275 } 1276 } 1277 } 1278 } 1279 break; 1280 1281 //Valeurs pos valides ? 1282 case 2 : 1283 { 1284 if (Sockets[i].PosValides) 1285 { 1286 Sockets[i].AttenteExecution=0; 1287 Sockets[i].etape++; 1288 } 1289 else 1290 { 1291 // on réitÚre l'ordre précédent si rien ne se passe 1292 1293 Sockets[i].AttenteExecution++; 1294 1295 if (Sockets[i].AttenteExecution>MAXATTENTE) 1296 { 1297 Sockets[i].etape=2; 1298 Sockets[i].AttenteExecution=0; 1299 Sockets[i].AnomaliesExecution++; 1300 } 1301 1302 if (Sockets[i].AnomaliesExecution>MAXANOMALIES) 1303 { 1304 Sockets[i].etape=3; 1305 1306 // if ( compt % 1000 == 0) 1307 { 1308 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s. La position retournée n est pas valide. Déconnexion de l antenne.", 1309 Sockets[i].IP.c_str()); 1310 Sockets[i].Connected=false; 1311 } 1312 } 1313 } 1314 } 1315 break; 1316 1317 //ack goto ? 1318 case 4 : 1319 { 1320 if (Sockets[i].ack_goto) 1321 { 1322 Sockets[i].AttenteExecution=0; 1323 Sockets[i].AnomaliesExecution=0; 1324 Sockets[i].etape++; 1325 } 1326 else 1327 { 1328 // on réitÚre l'ordre précédent si rien ne se passe 1329 1330 Sockets[i].AttenteExecution++; 1331 1332 if (Sockets[i].AttenteExecution>MAXATTENTE) 1333 { 1334 Sockets[i].etape=4; 1335 Sockets[i].AttenteExecution=0; 1336 Sockets[i].AnomaliesExecution++; 1337 } 1338 1339 if (Sockets[i].AnomaliesExecution>MAXANOMALIES) 1340 { 1341 Sockets[i].etape=6; 1342 1343 // if ( compt % 1000 == 0) 1344 { 1345 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s. Pas d acknowledge reçu aprÚs l ordre GOTO. Déconnexion de l antenne.", 1346 Sockets[i].IP.c_str()); 1347 Sockets[i].Connected=false; 1348 } 1349 } 1350 } 1351 } 1352 break; 1353 1354 //goto ok ? 1355 case 5 : 1356 { 1357 if (Sockets[i].GotoOk) 1358 { 1359 Sockets[i].AttenteExecution=0; 1360 Sockets[i].AnomaliesExecution=0; 1361 Sockets[i].etape++; 1362 } 1363 else 1364 { 1365 // on réitÚre l'ordre précédent si rien ne se passe 1366 1367 Sockets[i].AttenteExecution++; 1368 1369 if (Sockets[i].AttenteExecution>MAXATTENTE) 1370 { 1371 Sockets[i].etape=5; 1372 Sockets[i].AttenteExecution=0; 1373 Sockets[i].AnomaliesExecution++; 1374 } 1375 1376 if (Sockets[i].AnomaliesExecution>MAXANOMALIESGOTO) 1377 { 1378 Sockets[i].etape=6; 1379 1380 // if ( compt % 1000 == 0) 1381 { 1382 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s. L antenne n a pas renvoyé GOTO/OK. Déconnexion de l antenne.", 1383 Sockets[i].IP.c_str()); 1384 Sockets[i].Connected=false; 1385 1386 1387 } 1388 } 1389 } 1390 } 1391 break; 1392 1393 } 1394 } 1395 } 1396 1397 1398 1399 1400 1401 1402 // Détection d'anomalies concernant l'envoi de trames sur la socket. déconnexion du micro-cont ? 1403 1404 for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected) 1405 { 1406 if (Sockets[i].sendalertes > 0) 1407 { 1408 Sockets[i].etape=5; 1409 1410 // if ( compt % 1000 == 0) 1411 { 1412 IDSetSwitch(&OnCoordSetSP, "Anomalie détectée sur l antenne %s. Déconnexion de l antenne.", 1413 Sockets[i].IP.c_str()); 1414 1415 Sockets[i].Connected=false; 1416 } 1417 } 1418 } 1419 1420 1421 1422 //On attend que toutes les antennes soient prêtes pour lancer l'ordre Goto -> meilleure synchronisation 1423 1424 int num=0; 1425 1426 for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected) 1427 { 1428 if (Sockets[i].etape == 3) num++; //fin de la procédure LecturePosition. Les antennes sont prêtes 1429 //à recevoir l'ordre GOto 1430 } 1431 1432 if ((num == AntennesConnectees()) && (num>0)) 1433 { 1434 for (int i=1; i<SocketsNumber; i++ ) if (Sockets[i].Connected) 1435 { 1436 Sockets[i].ack_goto=false; 1437 Sockets[i].AttenteExecution=0; 1438 Sockets[i].AnomaliesExecution=0; 1439 1440 if (!GOTO(i, Sockets[i].Pos.x - TargetPosition.x, Sockets[i].Pos.y - TargetPosition.y )) Sockets[i].sendalertes++; 1441 1442 Sockets[i].etape++; 1443 } 1444 } 1445 1446 1447 1448 } 1449 943 944 // Nouvelle connexion sur le socket ! 945 946 if (SocketsNumber>memSocketsNumber) 947 { 948 memSocketsNumber=SocketsNumber; 949 950 IDSetSwitch(&ConnectSP, "Connexion de l antenne %s. (Antennes connectees : %i)", 951 Sockets[SocketsNumber-1].IP.c_str(), AntennesConnectees()); 952 } 953 954 955 956 // Début des échanges avec les microcontrÃŽleurs 957 958 // Analyse des réponses des microcontrÃŽleurs 959 960 for (int i=1; i<SocketsNumber; i++) /*if (Sockets[i].Connected)*/ 961 { 962 try 963 { 964 std::string reponse, memreponse; 965 // on récupÚre la réponse du microcontrÃŽleur 966 967 Sockets[i].new_sock >> reponse; 968 969 //IDSetSwitch(&OnCoordSetSP, "Réponse ISPOLL : %s\n", reponse.c_str()); // pour vérif 970 971 //Dans le cas où plusieurs trames seraient arrivées entre deux appels de POLLMS 972 //les traiter successivement 973 974 pos=reponse.find("\n"); // d'où l'intérêt de mettre un '\n' à la fin des trames 975 //pour différencier une trame de la précédente 976 977 while ((pos!=string::npos) && (reponse.length()>1)) 978 { 979 memreponse=reponse.substr(pos+1); 980 981 reponse=reponse.substr(0, pos); 982 983 984 // On traite ici les acknowledges 985 986 if ((reponse.find("ACK")!=string::npos) && (reponse.find("NACK")==string::npos)) 987 { 988 if (reponse.find("POSITION")!=string::npos) 989 { 990 Sockets[i].ack_pos=true; 991 } 992 else if (reponse.find("GOTO")!=string::npos) 993 { 994 Sockets[i].ack_goto=true; 995 } 996 else if (reponse.find("PARK")!=string::npos) 997 { 998 Sockets[i].ack_park=true; 999 } 1000 else if (reponse.find("ABORT")!=string::npos) 1001 { 1002 Sockets[i].ack_abort=true; 1003 } 1004 } 1005 else 1006 { 1007 1008 //réponse à la requête POSITION 1009 if (reponse.find("POSITION")!=string::npos) 1010 { 1011 if (reponse.find("NACK")!=string::npos) 1012 { 1013 OnCoordSetSP.s = IPS_ALERT; 1014 IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : position de l antenne inconnue !\n", 1015 Sockets[i].IP.c_str()); 1016 Sockets[i].PosValides=false; 1017 // Si la position de l'antenne est inconnue, on déconnecte l'antenne 1018 Sockets[i].Connected=false; 1019 } 1020 else if (Sockets[i].ack_pos) 1021 { 1022 OnCoordSetSP.s = IPS_OK; 1023 Sockets[i].Pos = ExtractPosition(reponse); 1024 Sockets[i].PosValides = true; 1025 IDSetSwitch(&ParkSP, "Antenne %s : POSITION OK (x=%i, y=%i)\n", 1026 Sockets[i].IP.c_str(), Sockets[i].Pos.x, Sockets[i].Pos.y); 1027 } 1028 1029 }//réponse à la requête PARK 1030 else if (reponse.find("PARK")!=string::npos) 1031 { 1032 if (reponse.find("NACK")!=string::npos) 1033 { 1034 ParkSP.s = IPS_ALERT; 1035 IDSetSwitch(&ParkSP, "ALERTE antenne %s : erreur PARK !\n", Sockets[i].IP.c_str()); 1036 } 1037 else if (reponse.find("OK")!=string::npos) 1038 { 1039 ParkSP.s = IPS_OK; 1040 IDSetSwitch(&ParkSP, "Antenne %s : PARK OK\n", Sockets[i].IP.c_str()); 1041 } 1042 1043 }//réponse à la requête ABORT 1044 else if (reponse.find("ABORT")!=string::npos) 1045 { 1046 if (reponse.find("NACK")!=string::npos) 1047 { 1048 AbortSlewSP.s = IPS_ALERT; 1049 IDSetSwitch(&AbortSlewSP, "ALERTE antenne %s : erreur ABORT !\n", Sockets[i].IP.c_str()); 1050 } 1051 1052 if (reponse.find("OK")!=string::npos) 1053 { 1054 AbortSlewSP.s = IPS_OK; 1055 IDSetSwitch(&AbortSlewSP, "Antenne %s : ABORT OK\n", Sockets[i].IP.c_str()); 1056 } 1057 1058 } //réponse à la requête GOTO 1059 else if (reponse.find("GOTO")!=string::npos) 1060 { 1061 if (reponse.find("NACK")!=string::npos) 1062 { 1063 OnCoordSetSP.s = IPS_ALERT; 1064 IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : Erreur GOTO !\n", Sockets[i].IP.c_str()); 1065 Sockets[i].Connected=false; 1066 } 1067 else if (Sockets[i].ack_goto) 1068 { 1069 if (reponse.find("OK")!=string::npos) 1070 { 1071 OnCoordSetSP.s = IPS_OK; 1072 1073 Sockets[i].GotoOk=true; 1074 1075 IDSetSwitch(&ParkSP, "Antenne %s : GOTO OK.\n", Sockets[i].IP.c_str()); 1076 1077 lastRA = targetRA; 1078 lastDEC = targetDEC; 1079 1080 //IDLog("We received JNow RA %s - DEC %s\n", RAStr, DecStr);*/ 1081 1082 EquatorialCoordsWNP.s = IPS_OK; 1083 IDSetNumber (&EquatorialCoordsWNP, NULL); 1084 1085 // Fin du Goto pour toutes les antennes ? 1086 1087 int num=0; 1088 1089 for (int j=1; j<SocketsNumber; j++) if (Sockets[j].Connected) 1090 { 1091 if (Sockets[j].GotoOk) num++; 1092 } 1093 1094 if ((num == AntennesConnectees()) && (num>0)) 1095 { 1096 LecturePosition=false; 1097 1098 InitAntennes(); 1099 1100 LastGotoOK=true; 1101 1102 IDSetSwitch(&OnCoordSetSP, "GOTO OK !"); 1103 } 1104 } 1105 } 1106 } 1107 } 1108 1109 // On passe éventuellement à la trame suivante 1110 1111 reponse=memreponse; 1112 pos=reponse.find("\n"); 1113 1114 } 1115 } 1116 catch (SocketException& e) //Aïe 1117 { 1118 Sockets[i].new_sock.shutdown(); 1119 Sockets[i].new_sock.create(); 1120 Sockets[i].Connected = Sockets[i].new_sock.connect((std::string)Sockets[i].IP); 1121 1122 if (Sockets[i].Connected) 1123 { 1124 Sockets[i].AttenteExecution=0; 1125 Sockets[i].AnomaliesExecution=0; 1126 } 1127 1128 std::string oss; 1129 oss="SocketException IsPoll : " + e.description() + "\n"; 1130 size_t size = oss.size() + 1; 1131 char* buffer = new char[size]; 1132 strncpy(buffer, oss.c_str(), size); 1133 IDLog(buffer); 1134 delete [] buffer; 1135 } 1136 } 1137 1138 1139 1140 if (Abort) 1141 { 1142 IDSetSwitch(&ConnectSP, "Envoi de la commande Abort\n"); 1143 1144 Goto=false; 1145 1146 for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected) 1147 { 1148 if (!ABORT(i)) Sockets[i].sendalertes++; 1149 } 1150 1151 LecturePosition=false; 1152 1153 InitAntennes(); 1154 1155 Abort=false; 1156 } 1157 1158 1159 if (Park) 1160 { 1161 IDSetSwitch(&ConnectSP, "Envoi de la commande Park\n"); 1162 1163 Goto=false; 1164 1165 for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected) 1166 { 1167 if (!PARK(i)) Sockets[i].sendalertes++; 1168 } 1169 1170 LecturePosition=false; 1171 1172 InitAntennes(); 1173 1174 Park=false; 1175 } 1176 1177 1178 // Gestion du suivi 1179 1180 if ((Goto) && (LastGotoOK)) 1181 { 1182 // Durée entre deux actualisations 1183 1184 double delai=ActualisationTM1/3600.0/24.0; // Actualisation toutes les 15 minutes en mode transit 1185 1186 if (TrackingMode==2) delai=ActualisationTM2/3600.0/24.0; //et 5 secs en mode tracking 1187 1188 1189 // On actualise la position 1190 1191 if (JJ-JJAnc > delai) 1192 { 1193 1194 LastGotoOK=false; 1195 1196 LecturePosition=true; 1197 1198 ADDEC2Motor(targetRA, targetDEC); 1199 1200 InitAntennes(); 1201 1202 JJAnc=JJ; 1203 } 1204 1205 //Plus d'antenne ! 1206 1207 if (AntennesConnectees() == 0) 1208 { 1209 // LecturePosition=false; 1210 1211 // Goto=false; 1212 1213 // InitAntennes(); 1214 1215 if ( compt % 1000 == 0) IDSetSwitch(&OnCoordSetSP, "Erreur ! Plus d antennes connectees !"); 1216 } 1217 } 1218 1219 1220 1221 // Exécution de la procédure complÚte de lecture de la position de l'antenne 1222 // puis envoi d'une commande Goto 1223 1224 if (LecturePosition) 1225 { 1226 for (int i=1; i<SocketsNumber; i++) /*if (Sockets[i].Connected)*/ 1227 { 1228 switch (Sockets[i].etape) 1229 { 1230 1231 //Envoi de la commande POS 1232 case 0 : 1233 { 1234 Sockets[i].ack_pos=false; 1235 Sockets[i].PosValides=false; 1236 1237 if (!POSITION(i)) Sockets[i].sendalertes++; 1238 1239 Sockets[i].etape++; 1240 } 1241 break; 1242 1243 //ack POS 1244 case 1 : 1245 { 1246 if (Sockets[i].ack_pos) 1247 { 1248 Sockets[i].AttenteExecution=0; 1249 Sockets[i].AnomaliesExecution=0; 1250 Sockets[i].etape++; 1251 i--; 1252 } 1253 else 1254 { 1255 // on réitÚre l'ordre précédent si rien ne se passe 1256 1257 Sockets[i].AttenteExecution++; 1258 1259 if (Sockets[i].AttenteExecution>MAXATTENTE) 1260 { 1261 Sockets[i].etape=0; 1262 Sockets[i].AttenteExecution=0; 1263 Sockets[i].AnomaliesExecution++; 1264 } 1265 1266 if (Sockets[i].AnomaliesExecution>MAXANOMALIES) 1267 { 1268 Sockets[i].etape=3; 1269 1270 // if ( compt % 1000 == 0) 1271 { 1272 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : pas d acknowledge recu apres l ordre POSITION. \ 1273 Deconnexion de l antenne.", Sockets[i].IP.c_str()); 1274 Sockets[i].Connected=false; 1275 } 1276 } 1277 } 1278 } 1279 break; 1280 1281 //Valeurs pos valides ? 1282 case 2 : 1283 { 1284 if (Sockets[i].PosValides) 1285 { 1286 Sockets[i].AttenteExecution=0; 1287 Sockets[i].etape++; 1288 } 1289 else 1290 { 1291 // on réitÚre l'ordre précédent si rien ne se passe 1292 1293 Sockets[i].AttenteExecution++; 1294 1295 if (Sockets[i].AttenteExecution>MAXATTENTE) 1296 { 1297 Sockets[i].etape=2; 1298 Sockets[i].AttenteExecution=0; 1299 Sockets[i].AnomaliesExecution++; 1300 } 1301 1302 if (Sockets[i].AnomaliesExecution>MAXANOMALIES) 1303 { 1304 Sockets[i].etape=3; 1305 1306 // if ( compt % 1000 == 0) 1307 { 1308 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : la position retournee n est pas valide. \ 1309 Deconnexion de l antenne.", Sockets[i].IP.c_str()); 1310 Sockets[i].Connected=false; 1311 } 1312 } 1313 } 1314 } 1315 break; 1316 1317 //ack goto ? 1318 case 4 : 1319 { 1320 if (Sockets[i].ack_goto) 1321 { 1322 Sockets[i].AttenteExecution=0; 1323 Sockets[i].AnomaliesExecution=0; 1324 Sockets[i].etape++; 1325 } 1326 else 1327 { 1328 // on réitÚre l'ordre précédent si rien ne se passe 1329 1330 Sockets[i].AttenteExecution++; 1331 1332 if (Sockets[i].AttenteExecution>MAXATTENTE) 1333 { 1334 Sockets[i].etape=4; 1335 Sockets[i].AttenteExecution=0; 1336 Sockets[i].AnomaliesExecution++; 1337 } 1338 1339 if (Sockets[i].AnomaliesExecution>MAXANOMALIES) 1340 { 1341 Sockets[i].etape=6; 1342 1343 // if ( compt % 1000 == 0) 1344 { 1345 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : pas d acknowledge recu apres l ordre GOTO. \ 1346 Deconnexion de l antenne.", Sockets[i].IP.c_str()); 1347 Sockets[i].Connected=false; 1348 } 1349 } 1350 } 1351 } 1352 break; 1353 1354 //goto ok ? 1355 case 5 : 1356 { 1357 if (Sockets[i].GotoOk) 1358 { 1359 Sockets[i].AttenteExecution=0; 1360 Sockets[i].AnomaliesExecution=0; 1361 Sockets[i].etape++; 1362 } 1363 else 1364 { 1365 // on réitÚre l'ordre précédent si rien ne se passe 1366 1367 Sockets[i].AttenteExecution++; 1368 1369 if (Sockets[i].AttenteExecution>MAXATTENTE) 1370 { 1371 Sockets[i].etape=5; 1372 Sockets[i].AttenteExecution=0; 1373 Sockets[i].AnomaliesExecution++; 1374 } 1375 1376 if (Sockets[i].AnomaliesExecution>MAXANOMALIESGOTO) 1377 { 1378 Sockets[i].etape=6; 1379 1380 // if ( compt % 1000 == 0) 1381 { 1382 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : l antenne n a pas renvoye GOTO/OK. \ 1383 Deconnexion de l antenne.", Sockets[i].IP.c_str()); 1384 Sockets[i].Connected=false; 1385 1386 1387 } 1388 } 1389 } 1390 } 1391 break; 1392 1393 } 1394 } 1395 } 1396 1397 1398 1399 1400 1401 1402 // Détection d'anomalies concernant l'envoi de trames sur la socket. déconnexion du micro-cont ? 1403 1404 for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected) 1405 { 1406 if (Sockets[i].sendalertes > 0) 1407 { 1408 Sockets[i].etape=5; 1409 1410 // if ( compt % 1000 == 0) 1411 { 1412 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : deconnexion de l antenne.", Sockets[i].IP.c_str()); 1413 1414 Sockets[i].Connected=false; 1415 } 1416 } 1417 } 1418 1419 1420 1421 //On attend que toutes les antennes soient prêtes pour lancer l'ordre Goto -> meilleure synchronisation 1422 1423 int num=0; 1424 1425 for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected) 1426 { 1427 if (Sockets[i].etape == 3) num++; //fin de la procédure LecturePosition. Les antennes sont prêtes 1428 //à recevoir l'ordre GOto 1429 } 1430 1431 if ((num == AntennesConnectees()) && (num>0)) 1432 { 1433 for (int i=1; i<SocketsNumber; i++ ) if (Sockets[i].Connected) 1434 { 1435 Sockets[i].ack_goto=false; 1436 Sockets[i].AttenteExecution=0; 1437 Sockets[i].AnomaliesExecution=0; 1438 1439 if (!GOTO(i, Sockets[i].Pos.x - TargetPosition.x, Sockets[i].Pos.y - TargetPosition.y )) Sockets[i].sendalertes++; 1440 1441 Sockets[i].etape++; 1442 } 1443 } 1444 } 1445 1450 1446 ISPOLLRunning=false; 1451 1452 1453 1454 1455 1456 1457 1458 1459 1447 } 1448 1449 1450 1451 /************************************************************************************** 1452 ** 1453 ***************************************************************************************/ 1454 bool BAO::process_coords() 1455 { 1460 1456 switch (currentSet) 1461 1457 { 1462 // Transit1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 } 1508 1458 // Transit 1459 case BAO_TRANSIT: 1460 1461 EquatorialCoordsWNP.s = IPS_BUSY; 1462 1463 IDSetNumber (&EquatorialCoordsWNP, NULL); 1464 1465 InitAntennes(); 1466 1467 JJAnc=JJ; 1468 1469 TrackingMode = 1; 1470 1471 Goto=true; 1472 1473 LastGotoOK=false; 1474 1475 LecturePosition=true; 1476 1477 ADDEC2Motor(targetRA, targetDEC); 1478 1479 break; 1480 1481 // Tracking 1482 case BAO_TRACKING: 1483 1484 EquatorialCoordsWNP.s = IPS_BUSY; 1485 1486 IDSetNumber (&EquatorialCoordsWNP, NULL); 1487 1488 InitAntennes(); 1489 1490 JJAnc=JJ; 1491 1492 TrackingMode = 2; 1493 1494 Goto=true; 1495 1496 LastGotoOK=false; 1497 1498 LecturePosition=true; 1499 1500 ADDEC2Motor(targetRA, targetDEC); 1501 1502 break; 1503 } 1504 1509 1505 return true; 1510 1511 1512 1513 1514 1515 1516 1506 } 1507 1508 /************************************************************************************** 1509 ** 1510 ***************************************************************************************/ 1511 int BAO::get_switch_index(ISwitchVectorProperty *sp) 1512 { 1517 1513 for (int i=0; i < sp->nsp ; i++) 1518 if (sp->sp[i].s == ISS_ON)1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1514 if (sp->sp[i].s == ISS_ON) 1515 return i; 1516 1517 return -1; 1518 } 1519 1520 /************************************************************************************** 1521 ** Activation de l'interface 1522 ***************************************************************************************/ 1523 void BAO::connect_telescope() 1524 { 1529 1525 switch (ConnectSP.sp[0].s) 1530 1526 { 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 } 1564 1565 1566 1567 1568 1569 1570 1527 case ISS_ON: 1528 ConnectS[0].s = ISS_ON; 1529 ConnectS[1].s = ISS_OFF; 1530 IDLog("\nHello BAORadio !\n"); 1531 1532 ConnectSP.s = IPS_OK; 1533 IDSetSwitch (&ConnectSP, "BAORadio is online. Retrieving basic data..."); 1534 1535 1536 break; 1537 1538 case ISS_OFF: 1539 ConnectS[0].s = ISS_OFF; 1540 ConnectS[1].s = ISS_ON; 1541 ConnectSP.s = IPS_IDLE; 1542 1543 SocketsNumber=1; 1544 InitThreadOK=false; 1545 1546 for (int i=0; i<MAXHOSTNAME; i++) 1547 { 1548 Sockets[i].Connected=false; 1549 Sockets[i].IP=""; 1550 Sockets[i].new_sock.shutdown(); 1551 } 1552 1553 InitAntennes(); 1554 1555 IDSetSwitch (&ConnectSP, "BAORadio is offline."); 1556 IDLog("Telescope is offline."); 1557 1558 break; 1559 } 1560 } 1561 1562 /************************************************************************************** 1563 ** 1564 ***************************************************************************************/ 1565 void BAO::get_initial_data() 1566 { 1571 1567 // IDSetNumber (&EquatorialCoordsRNP, NULL); 1572 1573 1574 1575 1576 1577 1578 1579 1580 1568 1569 1570 } 1571 1572 /************************************************************************************** 1573 ** 1574 ***************************************************************************************/ 1575 void BAO::slew_error(int slewCode) 1576 { 1581 1577 OnCoordSetSP.s = IPS_IDLE; 1582 1578 1583 1579 if (slewCode == 1) 1584 IDSetSwitch (&OnCoordSetSP, "Object below horizon.");1580 IDSetSwitch (&OnCoordSetSP, "Object below horizon."); 1585 1581 else if (slewCode == 2) 1586 IDSetSwitch (&OnCoordSetSP, "Object below the minimum elevation limit.");1582 IDSetSwitch (&OnCoordSetSP, "Object below the minimum elevation limit."); 1587 1583 else 1588 IDSetSwitch (&OnCoordSetSP, "Slew failed.");1589 1590 1591 1592 1593 1594 1595 1584 IDSetSwitch (&OnCoordSetSP, "Slew failed."); 1585 } 1586 1587 /************************************************************************************** 1588 ** 1589 ***************************************************************************************/ 1590 void BAO::enable_simulation(bool enable) 1591 { 1596 1592 simulation = enable; 1597 1593 1598 1594 if (simulation) 1599 IDLog("Warning: Simulation is activated.\n");1595 IDLog("Warning: Simulation is activated.\n"); 1600 1596 else 1601 IDLog("Simulation is disabled.\n");1602 1603 1604 1605 1606 1607 1608 1597 IDLog("Simulation is disabled.\n"); 1598 } 1599 1600 /************************************************************************************** 1601 ** 1602 ***************************************************************************************/ 1603 void BAO::connection_lost() 1604 { 1609 1605 ConnectSP.s = IPS_IDLE; 1610 1606 IDSetSwitch(&ConnectSP, "The connection to the telescope is lost."); 1611 1607 return; 1612 1613 1614 1615 1616 1617 1618 1608 } 1609 1610 /************************************************************************************** 1611 ** 1612 ***************************************************************************************/ 1613 void BAO::connection_resumed() 1614 { 1619 1615 ConnectS[0].s = ISS_ON; 1620 1616 ConnectS[1].s = ISS_OFF; 1621 1617 ConnectSP.s = IPS_OK; 1622 1618 1623 1619 IDSetSwitch(&ConnectSP, "The connection to the telescope has been resumed."); 1624 1625 1626 1627 1628 1629 1630 1631 1632 1620 } 1621 1622 1623 /************************************************************************************** 1624 ** Envoi d'une commande sur le socket puis attente de l'acknowledge 1625 ***************************************************************************************/ 1626 1627 bool BAO::COMMANDE(int numsocket, char* Commande, char* Params) 1628 { 1633 1629 char chaine[MAXCARACTERES]; 1634 1630 1635 1631 try 1636 1632 { 1637 sprintf(chaine, "%s%s\n", Commande, Params);1638 1639 Sockets[numsocket].new_sock << chaine;1633 sprintf(chaine, "%s%s\n", Commande, Params); 1634 1635 Sockets[numsocket].new_sock << chaine; 1640 1636 } 1641 1637 catch (SocketException& e) 1642 { 1643 Sockets[numsocket].new_sock.shutdown();1644 Sockets[numsocket].new_sock.create();1645 Sockets[numsocket].Connected = Sockets[numsocket].new_sock.connect((std::string)Sockets[numsocket].IP);1646 1647 if (Sockets[numsocket].Connected)1648 {1649 1650 1651 }1652 1653 // if (AntennesConnectees() == 0) { InitAntennes(); InitThreadOK=false;}1654 1655 std::string oss;1656 oss="COMMANDE exception : " + e.description() + "\n";1657 size_t size = oss.size() + 1;1658 char* buffer = new char[size];1659 strncpy(buffer, oss.c_str(), size);1660 1661 IDLog(buffer);1662 1663 delete [] buffer;1664 1665 return false;1666 } 1667 1638 { 1639 Sockets[numsocket].new_sock.shutdown(); 1640 Sockets[numsocket].new_sock.create(); 1641 Sockets[numsocket].Connected = Sockets[numsocket].new_sock.connect((std::string)Sockets[numsocket].IP); 1642 1643 if (Sockets[numsocket].Connected) 1644 { 1645 Sockets[numsocket].AttenteExecution=0; 1646 Sockets[numsocket].AnomaliesExecution=0; 1647 } 1648 1649 // if (AntennesConnectees() == 0) { InitAntennes(); InitThreadOK=false;} 1650 1651 std::string oss; 1652 oss="COMMANDE exception : " + e.description() + "\n"; 1653 size_t size = oss.size() + 1; 1654 char* buffer = new char[size]; 1655 strncpy(buffer, oss.c_str(), size); 1656 1657 IDLog(buffer); 1658 1659 delete [] buffer; 1660 1661 return false; 1662 } 1663 1668 1664 return true; 1669 1670 1671 1672 1673 1674 1675 1676 1677 1665 } 1666 1667 1668 /************************************************************************************** 1669 ** Commande POSITION 1670 ***************************************************************************************/ 1671 1672 bool BAO::POSITION(int numsocket) 1673 { 1678 1674 return COMMANDE(numsocket, (char*)"P", (char*)""); 1679 1680 1681 1682 1683 1684 1685 1686 1675 } 1676 1677 /************************************************************************************** 1678 ** Commande PARK 1679 ***************************************************************************************/ 1680 1681 bool BAO::PARK(int numsocket) 1682 { 1687 1683 return COMMANDE(numsocket, (char*)"Z", (char*)""); 1688 1689 1690 1691 1692 1693 1694 1695 1684 } 1685 1686 /************************************************************************************** 1687 ** Commande ABORT 1688 ***************************************************************************************/ 1689 1690 bool BAO::ABORT(int numsocket) 1691 { 1696 1692 return COMMANDE(numsocket, (char*)"A", (char*)""); 1697 1698 1699 1700 1701 1702 1703 1704 1705 1693 } 1694 1695 1696 /************************************************************************************** 1697 ** Commande GOTO 1698 ***************************************************************************************/ 1699 1700 bool BAO::GOTO(int numsocket, int deltaAz, int deltaAlt) 1701 { 1706 1702 char Params[MAXCARACTERES]; 1707 1703 char sensAz; 1708 1704 char sensAlt; 1709 1705 1710 1706 sensAlt='b'; 1711 1707 sensAz='b'; 1712 1708 1713 1709 if (deltaAz<0) 1714 1710 { 1715 deltaAz=-deltaAz;1716 sensAz='f';1717 } 1718 1711 deltaAz=-deltaAz; 1712 sensAz='f'; 1713 } 1714 1719 1715 if (deltaAlt<0) 1720 1716 { 1721 deltaAlt=-deltaAlt;1722 sensAlt='f';1723 } 1724 1717 deltaAlt=-deltaAlt; 1718 sensAlt='f'; 1719 } 1720 1725 1721 sprintf(Params, "%c%04i%c%04i", sensAz, deltaAz, sensAlt, deltaAlt); 1726 1722 1727 1723 return COMMANDE(numsocket, (char*)"G", Params); 1728 1729 1730 1731 1724 } 1725 1726 1727 -
BAORadio/libindi/libindi/drivers/telescope/lx200basic.cpp
r490 r501 163 163 IDLog("Driver Version: 2007-09-28\n"); 164 164 165 //enableSimulation(true); 166 } 165 enable_simulation(false); 166 167 } 167 168 168 169 /************************************************************************************** … … 342 343 #endif 343 344 344 if ( (error_code = setObjectRA(fd, newRA)) < 0 || ( error_code = setObjectDEC(fd, newDEC)) < 0)345 if (!simulation && ( (error_code = setObjectRA(fd, newRA)) < 0 || ( error_code = setObjectDEC(fd, newDEC)) < 0)) 345 346 { 346 347 handle_error(&EquatorialCoordsWNP, error_code, "Setting RA/DEC"); … … 574 575 void LX200Basic::ISPoll() 575 576 { 576 if (is_connected() == false )577 if (is_connected() == false || simulation) 577 578 return; 578 579 … … 684 685 } 685 686 686 if ( (error_code = Slew(fd)))687 if ( !simulation && (error_code = Slew(fd))) 687 688 { 688 689 slew_error(error_code); … … 716 717 if (dx >= (TrackAccuracyN[0].value/(60.0*15.0)) || (dy >= TrackAccuracyN[1].value/60.0)) 717 718 { 718 if ( (error_code = Slew(fd)))719 if ( !simulation && (error_code = Slew(fd))) 719 720 { 720 721 slew_error(error_code); … … 751 752 EquatorialCoordsWNP.s = IPS_IDLE; 752 753 753 if ( ( error_code = Sync(fd, syncString) < 0) )754 if ( !simulation && ( error_code = Sync(fd, syncString) < 0) ) 754 755 { 755 756 IDSetNumber( &EquatorialCoordsWNP , "Synchronization failed."); 756 757 return false; 758 } 759 760 if (simulation) 761 { 762 EquatorialCoordsRN[0].value = EquatorialCoordsWN[0].value; 763 EquatorialCoordsRN[1].value = EquatorialCoordsWN[1].value; 757 764 } 758 765 -
BAORadio/libindi/libindi/drivers/telescope/lx200generic.cpp
r490 r501 165 165 Property: Movement (Arrow keys on handset). West/East 166 166 *********************************************/ 167 167 168 static ISwitch MovementWES[] = {{"MOTION_WEST", "West", ISS_OFF, 0, 0}, {"MOTION_EAST", "East", ISS_OFF, 0, 0}}; 168 169 ISwitchVectorProperty MovementWESP = { mydev, "TELESCOPE_MOTION_WE", "West/East", MOTION_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, MovementWES, NARRAY(MovementWES), "", 0}; … … 314 315 strcpy(TimeTP.device , newName ); 315 316 strcpy(UTCOffsetNP.device , newName ); 317 316 318 strcpy(SDTimeNP.device , newName ); 317 319 … … 338 340 { 339 341 static int isInit=0; 342 char *envDev = getenv("INDIDEV"); 340 343 341 344 if (isInit) … … 355 358 { 356 359 fprintf(stderr , "initilizaing from LX200 classic device...\n"); 357 // 1. mydev = device_name 358 changeAllDeviceNames("LX200 Classic"); 359 // 2. device = sub_class 360 360 361 telescope = new LX200Classic(); 361 telescope->setCurrentDeviceName("LX200 Classic"); 362 if (envDev != NULL) 363 { 364 changeAllDeviceNames(envDev); 365 telescope->setCurrentDeviceName(envDev); 366 } 367 else 368 { 369 // 1. mydev = device_name 370 changeAllDeviceNames("LX200 Classic"); 371 telescope->setCurrentDeviceName("LX200 Classic"); 372 } 362 373 363 374 MaxReticleFlashRate = 3; … … 367 378 { 368 379 fprintf(stderr , "initilizaing from LX200 GPS device...\n"); 369 // 1. mydev = device_name 370 changeAllDeviceNames("LX200 GPS"); 380 371 381 // 2. device = sub_class 372 382 telescope = new LX200GPS(); 373 telescope->setCurrentDeviceName("LX200 GPS"); 383 384 if (envDev != NULL) 385 { 386 // 1. mydev = device_name 387 changeAllDeviceNames(envDev); 388 telescope->setCurrentDeviceName(envDev); 389 } 390 else 391 { 392 // 1. mydev = device_name 393 changeAllDeviceNames("LX200 GPS"); 394 telescope->setCurrentDeviceName("LX200 GPS"); 395 } 396 397 374 398 375 399 MaxReticleFlashRate = 9; … … 379 403 380 404 IDLog("Initilizaing from LX200 16 device...\n"); 381 // 1. mydev = device_name 382 changeAllDeviceNames("LX200 16"); 405 383 406 // 2. device = sub_class 384 407 telescope = new LX200_16(); 385 telescope->setCurrentDeviceName("LX200 16"); 408 409 if (envDev != NULL) 410 { 411 // 1. mydev = device_name 412 changeAllDeviceNames(envDev); 413 telescope->setCurrentDeviceName(envDev); 414 } 415 else 416 { 417 changeAllDeviceNames("LX200 16"); 418 telescope->setCurrentDeviceName("LX200 16"); 419 } 386 420 387 421 MaxReticleFlashRate = 3; … … 391 425 fprintf(stderr , "initilizaing from autostar device...\n"); 392 426 393 // 1. change device name394 changeAllDeviceNames("LX200 Autostar");395 427 // 2. device = sub_class 396 428 telescope = new LX200Autostar(); 397 telescope->setCurrentDeviceName("LX200 Autostar"); 429 430 if (envDev != NULL) 431 { 432 // 1. change device name 433 changeAllDeviceNames(envDev); 434 telescope->setCurrentDeviceName(envDev); 435 } 436 else 437 { 438 // 1. change device name 439 changeAllDeviceNames("LX200 Autostar"); 440 telescope->setCurrentDeviceName("LX200 Autostar"); 441 } 398 442 399 443 MaxReticleFlashRate = 9; … … 403 447 fprintf(stderr , "initilizaing from ap device...\n"); 404 448 405 // 1. change device name 406 changeAllDeviceNames("LX200 Astro-Physics"); 449 407 450 // 2. device = sub_class 408 451 telescope = new LX200AstroPhysics(); 409 telescope->setCurrentDeviceName("LX200 Astro-Physics"); 452 453 if (envDev != NULL) 454 { 455 // 1. change device name 456 changeAllDeviceNames(envDev); 457 telescope->setCurrentDeviceName(envDev); 458 } 459 else 460 { 461 // 1. change device name 462 changeAllDeviceNames("LX200 Astro-Physics"); 463 telescope->setCurrentDeviceName("LX200 Astro-Physics"); 464 } 465 410 466 411 467 MaxReticleFlashRate = 9; … … 415 471 { 416 472 telescope = new LX200Generic(); 417 telescope->setCurrentDeviceName("LX200 Generic"); 473 474 if (envDev != NULL) 475 { 476 // 1. change device name 477 changeAllDeviceNames(envDev); 478 telescope->setCurrentDeviceName(envDev); 479 } 480 else 481 { 482 // 1. change device name 483 changeAllDeviceNames("LX200 Generic"); 484 telescope->setCurrentDeviceName("LX200 Generic"); 485 } 486 418 487 } 419 488 -
BAORadio/libindi/libindi/examples/tutorial_two.c
r490 r501 100 100 101 101 /* Equatorial EOD Coord Request. This property is for requesting changes to target equatorial coordinates. However, the CURRENT coordinates are reported in EQUATORIAL_EOD_COORDS above.*/ 102 static INumber eqNR[] = {{"RA _REQUEST" ,"RA H:M:S" , "%10.6m" ,0. , 24., 0., 0., 0, 0, 0},103 {"DEC _REQUEST", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0}};102 static INumber eqNR[] = {{"RA" ,"RA H:M:S" , "%10.6m" ,0. , 24., 0., 0., 0, 0, 0}, 103 {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0}}; 104 104 static INumberVectorProperty eqNPR = { mydev, "EQUATORIAL_EOD_COORD_REQUEST", "Equatorial Request", MAIN_GROUP , IP_RW, 0, IPS_IDLE, eqNR, NARRAY(eqNR), "", 0}; 105 105 -
BAORadio/libindi/libindi/indiapi.h
r490 r501 48 48 <li><a href="indicom_8h.html">INDI Common Routine Library</a></li> 49 49 <li><a href="lilxml_8h.html">INDI LilXML Library</a></li> 50 <li><a href="http://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/cfitsio.html">CFITSIO Library</a></li> 50 <li><a href="group__configFunctions.html">Configuration</a></li> 51 <li><a href="classINDI_1_1BaseClient.html">Client API</a></li> 51 52 </ul> 52 53 … … 74 75 75 76 /* INDI Library version */ 76 #define INDI_LIBV 0. 677 #define INDI_LIBV 0.7 77 78 78 79 /******************************************************************************* -
BAORadio/libindi/libindi/indidevapi.h
r490 r501 302 302 \param snooped_property name of the snooped property in the device. 303 303 */ 304 extern void IDSnoopDevice (const char *snooped_device, c har *snooped_property);304 extern void IDSnoopDevice (const char *snooped_device, const char *snooped_property); 305 305 306 306 /** \brief Function a Driver calls to control whether they will receive BLOBs from snooped devices. 307 \param snooped_device _namename of the device to snoop.307 \param snooped_device name of the device to snoop. 308 308 \param bh How drivers handle BLOBs incoming from snooping drivers. 309 309 */ … … 403 403 /** \brief Find an IText member in a vector text property. 404 404 * 405 * \param t p a pointer to a text vector property.405 * \param tvp a pointer to a text vector property. 406 406 * \param name the name of the member to search for. 407 407 * \return a pointer to an IText member on match, or NULL if nothing is found. 408 408 */ 409 extern IText *IUFindText (const ITextVectorProperty *t p, const char *name);409 extern IText *IUFindText (const ITextVectorProperty *tvp, const char *name); 410 410 411 411 /** \brief Find an INumber member in a number text property. 412 412 * 413 * \param tp a pointer to a number vector property.413 * \param nvp a pointer to a number vector property. 414 414 * \param name the name of the member to search for. 415 415 * \return a pointer to an INumber member on match, or NULL if nothing is found. 416 416 */ 417 extern INumber *IUFindNumber(const INumberVectorProperty * tp, const char *name);417 extern INumber *IUFindNumber(const INumberVectorProperty *nvp, const char *name); 418 418 419 419 /** \brief Find an ISwitch member in a vector switch property. 420 420 * 421 * \param tp a pointer to a switch vector property.421 * \param svp a pointer to a switch vector property. 422 422 * \param name the name of the member to search for. 423 423 * \return a pointer to an ISwitch member on match, or NULL if nothing is found. 424 424 */ 425 extern ISwitch *IUFindSwitch(const ISwitchVectorProperty *tp, const char *name); 425 extern ISwitch *IUFindSwitch(const ISwitchVectorProperty *svp, const char *name); 426 427 /** \brief Find an ILight member in a vector Light property. 428 * 429 * \param lvp a pointer to a Light vector property. 430 * \param name the name of the member to search for. 431 * \return a pointer to an ILight member on match, or NULL if nothing is found. 432 */ 433 extern ILight *IUFindLight(const ILightVectorProperty *lvp, const char *name); 434 435 /** \brief Find an IBLOB member in a vector BLOB property. 436 * 437 * \param bvp a pointer to a BLOB vector property. 438 * \param name the name of the member to search for. 439 * \return a pointer to an IBLOB member on match, or NULL if nothing is found. 440 */ 441 extern IBLOB *IUFindBLOB(const IBLOBVectorProperty *bvp, const char *name); 426 442 427 443 /** \brief Returns the first ON switch it finds in the vector switch property. … … 429 445 * \note This is only valid for ISR_1OFMANY mode. That is, when only one switch out of many is allowed to be ON. Do not use this function if you can have multiple ON switches in the same vector property. 430 446 * 431 * \param tp a pointer to a switch vector property.447 * \param sp a pointer to a switch vector property. 432 448 * \return a pointer to the \e first ON ISwitch member if found. If all switches are off, NULL is returned. 433 449 */ 434 extern ISwitch *IUFindOnSwitch (const ISwitchVectorProperty * tp);450 extern ISwitch *IUFindOnSwitch (const ISwitchVectorProperty *sp); 435 451 436 452 /** \brief Reset all switches in a switch vector property to OFF. … … 517 533 extern void IUFillText(IText *tp, const char *name, const char * label, const char *initialText); 518 534 535 /** \brief Assign attributes for a BLOB property. The BLOB's data and auxiliary elements will be set to NULL. 536 \param bp pointer a BLOB property to fill 537 \param name the BLOB name 538 \param label the BLOB label 539 \param format the BLOB format. 540 */ 541 extern void IUFillBLOB(IBLOB *bp, const char *name, const char * label, const char *format); 519 542 520 543 /** \brief Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL. … … 573 596 extern void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char * dev, const char *name, const char *label, const char* group, IPerm p, double timeout, IPState s); 574 597 598 /** \brief Assign attributes for a BLOB vector property. The vector's auxiliary elements will be set to NULL. 599 \param bvp pointer a BLOB vector property to fill 600 \param bp pointer to an array of BLOBs 601 \param nbp the dimension of bp 602 \param dev the device name this vector property belongs to 603 \param name the vector property name 604 \param label the vector property label 605 \param group the vector property group 606 \param p the vector property permission 607 \param timeout vector property timeout in seconds 608 \param s the vector property initial state. 609 */ 610 extern void IUFillBLOBVector(IBLOBVectorProperty *bvp, IBLOB *bp, int nbp, const char * dev, const char *name, const char *label, const char* group, IPerm p, double timeout, IPState s); 611 612 575 613 /** \brief Update a snooped number vector property from the given XML root element. 576 614 \param root XML root elememnt containing the snopped property content … … 706 744 #define INDI_UNUSED(x) (void) x 707 745 746 /** \brief Extract dev and name attributes from an XML element. 747 \param root The XML element to be parsed. 748 \param dev pointer to an allocated buffer to save the extracted element device name attribute. 749 The buffer size must be at least MAXINDIDEVICE bytes. 750 \param name pointer to an allocated buffer to save the extracted elemented name attribute. 751 The buffer size must be at least MAXINDINAME bytes. 752 \param msg pointer to an allocated char buffer to store error messages. The minimum buffer size is MAXRBUF. 753 \return 0 if successful, -1 if error is encountered and msg is set. 754 */ 755 extern int crackDN (XMLEle *root, char **dev, char **name, char msg[]); 756 757 /** \brief Extract property state (Idle, OK, Busy, Alert) from the supplied string. 758 \param str A string representation of the state. 759 \param ip Pointer to IPState structure to store the extracted property state. 760 \return 0 if successful, -1 if error is encountered. 761 */ 762 extern int crackIPState (const char *str, IPState *ip); 763 764 /** \brief Extract switch state (On or Off) from the supplied string. 765 \param str A string representation of the switch state. 766 \param ip Pointer to ISState structure to store the extracted switch state. 767 \return 0 if successful, -1 if error is encountered. 768 */ 769 extern int crackISState (const char *str, ISState *ip); 770 771 /** \brief Extract property permission state (RW, RO, WO) from the supplied string. 772 \param str A string representation of the permission state. 773 \param ip Pointer to IPerm structure to store the extracted permission state. 774 \return 0 if successful, -1 if error is encountered. 775 */ 776 extern int crackIPerm (const char *str, IPerm *ip); 777 778 /** \brief Extract switch rule (OneOfMany, OnlyOne..etc) from the supplied string. 779 \param str A string representation of the switch rule. 780 \param ip Pointer to ISRule structure to store the extracted switch rule. 781 \return 0 if successful, -1 if error is encountered. 782 */ 783 extern int crackISRule (const char *str, ISRule *ip); 784 785 /** \return Returns a string representation of the supplied property state. */ 786 extern const char *pstateStr(IPState s); 787 /** \return Returns a string representation of the supplied switch status. */ 788 extern const char *sstateStr(ISState s); 789 /** \return Returns a string representation of the supplied switch rule. */ 790 extern const char *ruleStr(ISRule r); 791 /** \return Returns a string representation of the supplied permission value. */ 792 extern const char *permStr(IPerm p); 793 794 extern void xmlv1(void); 795 708 796 #ifdef __cplusplus 709 797 } -
BAORadio/libindi/libindi/indidrivermain.c
r490 r501 3 3 Copyright (C) 2003-2006 Elwood C. Downey 4 4 5 Modified by Jasem Mutlaq (2003-2006)5 Updated by Jasem Mutlaq (2003-2010) 6 6 7 7 This library is free software; you can redistribute it and/or … … 46 46 #include "indidevapi.h" 47 47 #include "indicom.h" 48 #include "indidriver.h" 48 49 49 static void usage(void); 50 static void clientMsgCB(int fd, void *arg); 51 static int dispatch (XMLEle *root, char msg[]); 52 static int crackDN (XMLEle *root, char **dev, char **name, char msg[]); 53 static int isPropDefined(const char *property_name); 54 static int crackIPState (const char *str, IPState *ip); 55 static int crackISState (const char *str, ISState *ip); 56 static void xmlv1(void); 57 const char *pstateStr(IPState s); 58 const char *sstateStr(ISState s); 59 const char *ruleStr(ISRule r); 60 const char *permStr(IPerm p); 50 #define MAXRBUF 2048 61 51 52 ROSC *roCheck; 53 int nroCheck; /* # of elements in roCheck */ 62 54 63 static int nroCheck; /* # of elements in roCheck */ 64 static int verbose; /* chatty */ 55 int verbose; /* chatty */ 65 56 char *me; /* a.out name */ 66 staticLilXML *clixml; /* XML parser context */57 LilXML *clixml; /* XML parser context */ 67 58 68 /* insure RO properties are never modified. RO Sanity Check */ 69 typedef struct 70 { 71 char propName[MAXINDINAME]; 72 IPerm perm; 73 } ROSC; 74 75 static ROSC *roCheck; 59 static void usage(void); 76 60 77 61 int … … 109 93 clixml = newLilXML(); 110 94 addCallback (0, clientMsgCB, NULL); 111 112 nroCheck = 0;113 roCheck = NULL;114 95 115 96 /* service client */ … … 121 102 } 122 103 123 /* Return 1 is property is already cached, 0 otherwise*/124 static int isPropDefined(const char *property_name)104 /* print usage message and exit (1) */ 105 static void usage(void) 125 106 { 126 int i=0; 127 128 for (i=0; i < nroCheck; i++) 129 if (!strcmp(property_name, roCheck[i].propName)) 130 return 1; 107 fprintf (stderr, "Usage: %s [options]\n", me); 108 fprintf (stderr, "Purpose: INDI Device driver framework.\n"); 109 fprintf (stderr, "Options:\n"); 110 fprintf (stderr, " -v : more verbose to stderr\n"); 131 111 132 return 0; 133 112 exit (1); 134 113 } 135 114 136 /* functions we define that drivers may call */137 138 /* tell client to create a text vector property */139 void140 IDDefText (const ITextVectorProperty *tvp, const char *fmt, ...)141 {142 int i;143 ROSC *SC;144 145 xmlv1();146 printf ("<defTextVector\n");147 printf (" device='%s'\n", tvp->device);148 printf (" name='%s'\n", tvp->name);149 printf (" label='%s'\n", tvp->label);150 printf (" group='%s'\n", tvp->group);151 printf (" state='%s'\n", pstateStr(tvp->s));152 printf (" perm='%s'\n", permStr(tvp->p));153 printf (" timeout='%g'\n", tvp->timeout);154 printf (" timestamp='%s'\n", timestamp());155 if (fmt) {156 va_list ap;157 va_start (ap, fmt);158 printf (" message='");159 vprintf (fmt, ap);160 printf ("'\n");161 va_end (ap);162 }163 printf (">\n");164 165 for (i = 0; i < tvp->ntp; i++) {166 IText *tp = &tvp->tp[i];167 printf (" <defText\n");168 printf (" name='%s'\n", tp->name);169 printf (" label='%s'>\n", tp->label);170 printf (" %s\n", tp->text ? tp->text : "");171 printf (" </defText>\n");172 }173 174 printf ("</defTextVector>\n");175 176 if (!isPropDefined(tvp->name))177 {178 /* Add this property to insure proper sanity check */179 roCheck = roCheck ? (ROSC *) realloc ( roCheck, sizeof(ROSC) * (nroCheck+1))180 : (ROSC *) malloc ( sizeof(ROSC));181 SC = &roCheck[nroCheck++];182 183 strcpy(SC->propName, tvp->name);184 SC->perm = tvp->p;185 }186 187 fflush (stdout);188 }189 190 /* tell client to create a new numeric vector property */191 void192 IDDefNumber (const INumberVectorProperty *n, const char *fmt, ...)193 {194 int i;195 ROSC *SC;196 197 xmlv1();198 printf ("<defNumberVector\n");199 printf (" device='%s'\n", n->device);200 printf (" name='%s'\n", n->name);201 printf (" label='%s'\n", n->label);202 printf (" group='%s'\n", n->group);203 printf (" state='%s'\n", pstateStr(n->s));204 printf (" perm='%s'\n", permStr(n->p));205 printf (" timeout='%g'\n", n->timeout);206 printf (" timestamp='%s'\n", timestamp());207 if (fmt) {208 va_list ap;209 va_start (ap, fmt);210 printf (" message='");211 vprintf (fmt, ap);212 printf ("'\n");213 va_end (ap);214 }215 printf (">\n");216 217 for (i = 0; i < n->nnp; i++) {218 INumber *np = &n->np[i];219 printf (" <defNumber\n");220 printf (" name='%s'\n", np->name);221 printf (" label='%s'\n", np->label);222 printf (" format='%s'\n", np->format);223 printf (" min='%.20g'\n", np->min);224 printf (" max='%.20g'\n", np->max);225 printf (" step='%.20g'>\n", np->step);226 printf (" %.20g\n", np->value);227 printf (" </defNumber>\n");228 }229 230 printf ("</defNumberVector>\n");231 232 if (!isPropDefined(n->name))233 {234 /* Add this property to insure proper sanity check */235 roCheck = roCheck ? (ROSC *) realloc ( roCheck, sizeof(ROSC) * (nroCheck+1))236 : (ROSC *) malloc ( sizeof(ROSC));237 SC = &roCheck[nroCheck++];238 239 strcpy(SC->propName, n->name);240 SC->perm = n->p;241 242 }243 244 fflush (stdout);245 }246 247 /* tell client to create a new switch vector property */248 void249 IDDefSwitch (const ISwitchVectorProperty *s, const char *fmt, ...)250 251 {252 int i;253 ROSC *SC;254 255 xmlv1();256 printf ("<defSwitchVector\n");257 printf (" device='%s'\n", s->device);258 printf (" name='%s'\n", s->name);259 printf (" label='%s'\n", s->label);260 printf (" group='%s'\n", s->group);261 printf (" state='%s'\n", pstateStr(s->s));262 printf (" perm='%s'\n", permStr(s->p));263 printf (" rule='%s'\n", ruleStr (s->r));264 printf (" timeout='%g'\n", s->timeout);265 printf (" timestamp='%s'\n", timestamp());266 if (fmt) {267 va_list ap;268 va_start (ap, fmt);269 printf (" message='");270 vprintf (fmt, ap);271 printf ("'\n");272 va_end (ap);273 }274 printf (">\n");275 276 for (i = 0; i < s->nsp; i++) {277 ISwitch *sp = &s->sp[i];278 printf (" <defSwitch\n");279 printf (" name='%s'\n", sp->name);280 printf (" label='%s'>\n", sp->label);281 printf (" %s\n", sstateStr(sp->s));282 printf (" </defSwitch>\n");283 }284 285 printf ("</defSwitchVector>\n");286 287 if (!isPropDefined(s->name))288 {289 /* Add this property to insure proper sanity check */290 roCheck = roCheck ? (ROSC *) realloc ( roCheck, sizeof(ROSC) * (nroCheck+1))291 : (ROSC *) malloc ( sizeof(ROSC));292 SC = &roCheck[nroCheck++];293 294 strcpy(SC->propName, s->name);295 SC->perm = s->p;296 }297 298 fflush (stdout);299 }300 301 /* tell client to create a new lights vector property */302 void303 IDDefLight (const ILightVectorProperty *lvp, const char *fmt, ...)304 {305 int i;306 307 xmlv1();308 printf ("<defLightVector\n");309 printf (" device='%s'\n", lvp->device);310 printf (" name='%s'\n", lvp->name);311 printf (" label='%s'\n", lvp->label);312 printf (" group='%s'\n", lvp->group);313 printf (" state='%s'\n", pstateStr(lvp->s));314 printf (" timestamp='%s'\n", timestamp());315 if (fmt) {316 va_list ap;317 va_start (ap, fmt);318 printf (" message='");319 vprintf (fmt, ap);320 printf ("'\n");321 va_end (ap);322 }323 printf (">\n");324 325 for (i = 0; i < lvp->nlp; i++) {326 ILight *lp = &lvp->lp[i];327 printf (" <defLight\n");328 printf (" name='%s'\n", lp->name);329 printf (" label='%s'>\n", lp->label);330 printf (" %s\n", pstateStr(lp->s));331 printf (" </defLight>\n");332 }333 334 printf ("</defLightVector>\n");335 fflush (stdout);336 }337 338 /* tell client to create a new BLOB vector property */339 void340 IDDefBLOB (const IBLOBVectorProperty *b, const char *fmt, ...)341 {342 int i;343 ROSC *SC;344 345 xmlv1();346 printf ("<defBLOBVector\n");347 printf (" device='%s'\n", b->device);348 printf (" name='%s'\n", b->name);349 printf (" label='%s'\n", b->label);350 printf (" group='%s'\n", b->group);351 printf (" state='%s'\n", pstateStr(b->s));352 printf (" perm='%s'\n", permStr(b->p));353 printf (" timeout='%g'\n", b->timeout);354 printf (" timestamp='%s'\n", timestamp());355 if (fmt) {356 va_list ap;357 va_start (ap, fmt);358 printf (" message='");359 vprintf (fmt, ap);360 printf ("'\n");361 va_end (ap);362 }363 printf (">\n");364 365 for (i = 0; i < b->nbp; i++) {366 IBLOB *bp = &b->bp[i];367 printf (" <defBLOB\n");368 printf (" name='%s'\n", bp->name);369 printf (" label='%s'\n", bp->label);370 printf (" />\n");371 }372 373 printf ("</defBLOBVector>\n");374 375 if (!isPropDefined(b->name))376 {377 /* Add this property to insure proper sanity check */378 roCheck = roCheck ? (ROSC *) realloc ( roCheck, sizeof(ROSC) * (nroCheck+1))379 : (ROSC *) malloc ( sizeof(ROSC));380 SC = &roCheck[nroCheck++];381 382 strcpy(SC->propName, b->name);383 SC->perm = b->p;384 }385 386 fflush (stdout);387 }388 389 /* tell client to update an existing text vector property */390 void391 IDSetText (const ITextVectorProperty *tvp, const char *fmt, ...)392 {393 int i;394 395 xmlv1();396 printf ("<setTextVector\n");397 printf (" device='%s'\n", tvp->device);398 printf (" name='%s'\n", tvp->name);399 printf (" state='%s'\n", pstateStr(tvp->s));400 printf (" timeout='%g'\n", tvp->timeout);401 printf (" timestamp='%s'\n", timestamp());402 if (fmt) {403 va_list ap;404 va_start (ap, fmt);405 printf (" message='");406 vprintf (fmt, ap);407 printf ("'\n");408 va_end (ap);409 }410 printf (">\n");411 412 for (i = 0; i < tvp->ntp; i++) {413 IText *tp = &tvp->tp[i];414 printf (" <oneText name='%s'>\n", tp->name);415 printf (" %s\n", tp->text ? tp->text : "");416 printf (" </oneText>\n");417 }418 419 printf ("</setTextVector>\n");420 fflush (stdout);421 }422 423 /* tell client to update an existing numeric vector property */424 void425 IDSetNumber (const INumberVectorProperty *nvp, const char *fmt, ...)426 {427 int i;428 429 xmlv1();430 printf ("<setNumberVector\n");431 printf (" device='%s'\n", nvp->device);432 printf (" name='%s'\n", nvp->name);433 printf (" state='%s'\n", pstateStr(nvp->s));434 printf (" timeout='%g'\n", nvp->timeout);435 printf (" timestamp='%s'\n", timestamp());436 if (fmt) {437 va_list ap;438 va_start (ap, fmt);439 printf (" message='");440 vprintf (fmt, ap);441 printf ("'\n");442 va_end (ap);443 }444 printf (">\n");445 446 for (i = 0; i < nvp->nnp; i++) {447 INumber *np = &nvp->np[i];448 printf (" <oneNumber name='%s'>\n", np->name);449 printf (" %.20g\n", np->value);450 printf (" </oneNumber>\n");451 }452 453 printf ("</setNumberVector>\n");454 fflush (stdout);455 }456 457 /* tell client to update an existing switch vector property */458 void459 IDSetSwitch (const ISwitchVectorProperty *svp, const char *fmt, ...)460 {461 int i;462 463 xmlv1();464 printf ("<setSwitchVector\n");465 printf (" device='%s'\n", svp->device);466 printf (" name='%s'\n", svp->name);467 printf (" state='%s'\n", pstateStr(svp->s));468 printf (" timeout='%g'\n", svp->timeout);469 printf (" timestamp='%s'\n", timestamp());470 if (fmt) {471 va_list ap;472 va_start (ap, fmt);473 printf (" message='");474 vprintf (fmt, ap);475 printf ("'\n");476 va_end (ap);477 }478 printf (">\n");479 480 for (i = 0; i < svp->nsp; i++) {481 ISwitch *sp = &svp->sp[i];482 printf (" <oneSwitch name='%s'>\n", sp->name);483 printf (" %s\n", sstateStr(sp->s));484 printf (" </oneSwitch>\n");485 }486 487 printf ("</setSwitchVector>\n");488 fflush (stdout);489 }490 491 /* tell client to update an existing lights vector property */492 void493 IDSetLight (const ILightVectorProperty *lvp, const char *fmt, ...)494 {495 int i;496 497 xmlv1();498 printf ("<setLightVector\n");499 printf (" device='%s'\n", lvp->device);500 printf (" name='%s'\n", lvp->name);501 printf (" state='%s'\n", pstateStr(lvp->s));502 printf (" timestamp='%s'\n", timestamp());503 if (fmt) {504 va_list ap;505 va_start (ap, fmt);506 printf (" message='");507 vprintf (fmt, ap);508 printf ("'\n");509 va_end (ap);510 }511 printf (">\n");512 513 for (i = 0; i < lvp->nlp; i++) {514 ILight *lp = &lvp->lp[i];515 printf (" <oneLight name='%s'>\n", lp->name);516 printf (" %s\n", pstateStr(lp->s));517 printf (" </oneLight>\n");518 }519 520 printf ("</setLightVector>\n");521 fflush (stdout);522 }523 524 /* tell client to update an existing BLOB vector property */525 void526 IDSetBLOB (const IBLOBVectorProperty *bvp, const char *fmt, ...)527 {528 int i;529 530 xmlv1();531 printf ("<setBLOBVector\n");532 printf (" device='%s'\n", bvp->device);533 printf (" name='%s'\n", bvp->name);534 printf (" state='%s'\n", pstateStr(bvp->s));535 printf (" timeout='%g'\n", bvp->timeout);536 printf (" timestamp='%s'\n", timestamp());537 if (fmt) {538 va_list ap;539 va_start (ap, fmt);540 printf (" message='");541 vprintf (fmt, ap);542 printf ("'\n");543 va_end (ap);544 }545 printf (">\n");546 547 for (i = 0; i < bvp->nbp; i++) {548 IBLOB *bp = &bvp->bp[i];549 unsigned char *encblob;550 int j, l;551 552 printf (" <oneBLOB\n");553 printf (" name='%s'\n", bp->name);554 printf (" size='%d'\n", bp->size);555 printf (" format='%s'>\n", bp->format);556 557 encblob = malloc (4*bp->bloblen/3+4);558 l = to64frombits(encblob, bp->blob, bp->bloblen);559 for (j = 0; j < l; j += 72)560 printf ("%.72s\n", encblob+j);561 free (encblob);562 563 printf (" </oneBLOB>\n");564 }565 566 printf ("</setBLOBVector>\n");567 fflush (stdout);568 }569 570 /* tell client to update min/max elements of an existing number vector property */571 void IUUpdateMinMax(const INumberVectorProperty *nvp)572 {573 int i;574 575 xmlv1();576 printf ("<setNumberVector\n");577 printf (" device='%s'\n", nvp->device);578 printf (" name='%s'\n", nvp->name);579 printf (" state='%s'\n", pstateStr(nvp->s));580 printf (" timeout='%g'\n", nvp->timeout);581 printf (" timestamp='%s'\n", timestamp());582 printf (">\n");583 584 for (i = 0; i < nvp->nnp; i++) {585 INumber *np = &nvp->np[i];586 printf (" <oneNumber name='%s'\n", np->name);587 printf (" min='%g'\n", np->min);588 printf (" max='%g'\n", np->max);589 printf (" step='%g'\n", np->step);590 printf(">\n");591 printf (" %g\n", np->value);592 printf (" </oneNumber>\n");593 }594 595 printf ("</setNumberVector>\n");596 fflush (stdout);597 }598 599 /* send client a message for a specific device or at large if !dev */600 void601 IDMessage (const char *dev, const char *fmt, ...)602 {603 604 xmlv1();605 printf ("<message\n");606 if (dev)607 printf (" device='%s'\n", dev);608 printf (" timestamp='%s'\n", timestamp());609 if (fmt) {610 va_list ap;611 va_start (ap, fmt);612 printf (" message='");613 vprintf (fmt, ap);614 printf ("'\n");615 va_end (ap);616 }617 printf ("/>\n");618 fflush (stdout);619 }620 621 /* tell Client to delete the property with given name on given device, or622 * entire device if !name623 */624 void625 IDDelete (const char *dev, const char *name, const char *fmt, ...)626 {627 xmlv1();628 printf ("<delProperty\n device='%s'\n", dev);629 if (name)630 printf (" name='%s'\n", name);631 printf (" timestamp='%s'\n", timestamp());632 if (fmt) {633 va_list ap;634 va_start (ap, fmt);635 printf (" message='");636 vprintf (fmt, ap);637 printf ("'\n");638 va_end (ap);639 }640 printf ("/>\n");641 fflush (stdout);642 }643 644 /* tell indiserver we want to snoop on the given device/property.645 * name ignored if NULL or empty.646 */647 void648 IDSnoopDevice (const char *snooped_device_name, char *snooped_property_name)649 {650 xmlv1();651 if (snooped_property_name && snooped_property_name[0])652 printf ("<getProperties device='%s' name='%s'/>\n",653 snooped_device_name, snooped_property_name);654 else655 printf ("<getProperties device='%s'/>\n", snooped_device_name);656 fflush (stdout);657 }658 659 /* tell indiserver whether we want BLOBs from the given snooped device.660 * silently ignored if given device is not already registered for snooping.661 */662 void663 IDSnoopBLOBs (const char *snooped_device, BLOBHandling bh)664 {665 const char *how;666 667 switch (bh) {668 case B_NEVER: how = "Never"; break;669 case B_ALSO: how = "Also"; break;670 case B_ONLY: how = "Only"; break;671 default: return;672 }673 674 xmlv1();675 printf ("<enableBLOB device='%s'>%s</enableBLOB>\n",676 snooped_device, how);677 fflush (stdout);678 }679 680 /* "INDI" wrappers to the more generic eventloop facility. */681 682 int683 IEAddCallback (int readfiledes, IE_CBF *fp, void *p)684 {685 return (addCallback (readfiledes, (CBF*)fp, p));686 }687 688 void689 IERmCallback (int callbackid)690 {691 rmCallback (callbackid);692 }693 694 int695 IEAddTimer (int millisecs, IE_TCF *fp, void *p)696 {697 return (addTimer (millisecs, (TCF*)fp, p));698 }699 700 void701 IERmTimer (int timerid)702 {703 rmTimer (timerid);704 }705 706 int707 IEAddWorkProc (IE_WPF *fp, void *p)708 {709 return (addWorkProc ((WPF*)fp, p));710 }711 712 void713 IERmWorkProc (int workprocid)714 {715 rmWorkProc (workprocid);716 }717 718 719 int720 IEDeferLoop (int maxms, int *flagp)721 {722 return (deferLoop (maxms, flagp));723 }724 725 int726 IEDeferLoop0 (int maxms, int *flagp)727 {728 return (deferLoop0 (maxms, flagp));729 }730 731 /* find a member of an IText vector, else NULL */732 IText *733 IUFindText (const ITextVectorProperty *tvp, const char *name)734 {735 int i;736 737 for (i = 0; i < tvp->ntp; i++)738 if (strcmp (tvp->tp[i].name, name) == 0)739 return (&tvp->tp[i]);740 fprintf (stderr, "No IText '%s' in %s.%s\n",name,tvp->device,tvp->name);741 return (NULL);742 }743 744 /* find a member of an INumber vector, else NULL */745 INumber *746 IUFindNumber(const INumberVectorProperty *nvp, const char *name)747 {748 int i;749 750 for (i = 0; i < nvp->nnp; i++)751 if (strcmp (nvp->np[i].name, name) == 0)752 return (&nvp->np[i]);753 fprintf(stderr,"No INumber '%s' in %s.%s\n",name,nvp->device,nvp->name);754 return (NULL);755 }756 757 /* find a member of an ISwitch vector, else NULL */758 ISwitch *759 IUFindSwitch(const ISwitchVectorProperty *svp, const char *name)760 {761 int i;762 763 for (i = 0; i < svp->nsp; i++)764 if (strcmp (svp->sp[i].name, name) == 0)765 return (&svp->sp[i]);766 fprintf(stderr,"No ISwitch '%s' in %s.%s\n",name,svp->device,svp->name);767 return (NULL);768 }769 770 /* find an ON member of an ISwitch vector, else NULL.771 * N.B. user must make sense of result with ISRule in mind.772 */773 ISwitch *774 IUFindOnSwitch(const ISwitchVectorProperty *svp)775 {776 int i;777 778 for (i = 0; i < svp->nsp; i++)779 if (svp->sp[i].s == ISS_ON)780 return (&svp->sp[i]);781 /*fprintf(stderr, "No ISwitch On in %s.%s\n", svp->device, svp->name);*/782 return (NULL);783 }784 785 /* Set all switches to off */786 void787 IUResetSwitch(ISwitchVectorProperty *svp)788 {789 int i;790 791 for (i = 0; i < svp->nsp; i++)792 svp->sp[i].s = ISS_OFF;793 }794 795 /* Update property switches in accord with states and names. */796 int797 IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)798 {799 int i=0;800 ISwitch *sp;801 char sn[MAXINDINAME];802 803 /* store On switch name */804 if (svp->r == ISR_1OFMANY)805 {806 sp = IUFindOnSwitch(svp);807 if (sp) strncpy(sn, sp->name, MAXINDINAME);808 809 IUResetSwitch(svp);810 }811 812 for (i = 0; i < n ; i++)813 {814 sp = IUFindSwitch(svp, names[i]);815 816 if (!sp)817 {818 svp->s = IPS_IDLE;819 IDSetSwitch(svp, "Error: %s is not a member of %s property.", names[i], svp->name);820 return -1;821 }822 823 sp->s = states[i];824 }825 826 /* Consistency checks for ISR_1OFMANY after update. */827 if (svp->r == ISR_1OFMANY)828 {829 int t_count=0;830 for (i=0; i < svp->nsp; i++)831 {832 if (svp->sp[i].s == ISS_ON)833 t_count++;834 }835 if (t_count != 1)836 {837 IUResetSwitch(svp);838 sp = IUFindSwitch(svp, sn);839 if (sp) sp->s = ISS_ON;840 svp->s = IPS_IDLE;841 IDSetSwitch(svp, "Error: invalid state switch for property %s. %s.", svp->name, t_count == 0 ? "No switch is on" : "Too many switches are on");842 return -1;843 }844 }845 846 return 0;847 848 }849 850 /* Update property numbers in accord with values and names */851 int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)852 {853 int i=0;854 855 INumber *np;856 857 for (i = 0; i < n; i++)858 {859 np = IUFindNumber(nvp, names[i]);860 if (!np)861 {862 nvp->s = IPS_IDLE;863 IDSetNumber(nvp, "Error: %s is not a member of %s property.", names[i], nvp->name);864 return -1;865 }866 867 if (values[i] < np->min || values[i] > np->max)868 {869 nvp->s = IPS_IDLE;870 IDSetNumber(nvp, "Error: Invalid range. Valid range is from %g to %g", np->min, np->max);871 return -1;872 }873 874 }875 876 /* First loop checks for error, second loop set all values atomically*/877 for (i=0; i < n; i++)878 {879 np = IUFindNumber(nvp, names[i]);880 np->value = values[i];881 }882 883 return 0;884 885 }886 887 /* Update property text in accord with texts and names */888 int IUUpdateText(ITextVectorProperty *tvp, char * texts[], char *names[], int n)889 {890 int i=0;891 892 IText *tp;893 894 for (i = 0; i < n; i++)895 {896 tp = IUFindText(tvp, names[i]);897 if (!tp)898 {899 tvp->s = IPS_IDLE;900 IDSetText(tvp, "Error: %s is not a member of %s property.", names[i], tvp->name);901 return -1;902 }903 }904 905 /* First loop checks for error, second loop set all values atomically*/906 for (i=0; i < n; i++)907 {908 tp = IUFindText(tvp, names[i]);909 IUSaveText(tp, texts[i]);910 }911 912 return 0;913 914 }915 916 /* save malloced copy of newtext in tp->text, reusing if not first time */917 void918 IUSaveText (IText *tp, const char *newtext)919 {920 /* seed for realloc */921 if (tp->text == NULL)922 tp->text = malloc (1);923 924 /* copy in fresh string */925 tp->text = strcpy (realloc (tp->text, strlen(newtext)+1), newtext);926 }927 928 void IUFillSwitch(ISwitch *sp, const char *name, const char * label, ISState s)929 {930 strcpy(sp->name, name);931 strcpy(sp->label, label);932 sp->s = s;933 sp->svp = NULL;934 sp->aux = NULL;935 }936 937 void IUFillLight(ILight *lp, const char *name, const char * label, IPState s)938 {939 strcpy(lp->name, name);940 strcpy(lp->label, label);941 lp->s = s;942 lp->lvp = NULL;943 lp->aux = NULL;944 }945 946 947 void IUFillNumber(INumber *np, const char *name, const char * label, const char *format, double min, double max, double step, double value)948 {949 950 strcpy(np->name, name);951 strcpy(np->label, label);952 strcpy(np->format, format);953 954 np->min = min;955 np->max = max;956 np->step = step;957 np->value = value;958 np->nvp = NULL;959 np->aux0 = NULL;960 np->aux1 = NULL;961 }962 963 void IUFillText(IText *tp, const char *name, const char * label, const char *initialText)964 {965 966 strcpy(tp->name, name);967 strcpy(tp->label, label);968 tp->text = NULL;969 tp->tvp = NULL;970 tp->aux0 = NULL;971 tp->aux1 = NULL;972 973 IUSaveText(tp, initialText);974 975 }976 977 void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char * dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)978 {979 strcpy(svp->device, dev);980 strcpy(svp->name, name);981 strcpy(svp->label, label);982 strcpy(svp->group, group);983 strcpy(svp->timestamp, "");984 985 svp->p = p;986 svp->r = r;987 svp->timeout = timeout;988 svp->s = s;989 svp->sp = sp;990 svp->nsp = nsp;991 }992 993 void IUFillLightVector(ILightVectorProperty *lvp, ILight *lp, int nlp, const char * dev, const char *name, const char *label, const char *group, IPState s)994 {995 strcpy(lvp->device, dev);996 strcpy(lvp->name, name);997 strcpy(lvp->label, label);998 strcpy(lvp->group, group);999 strcpy(lvp->timestamp, "");1000 1001 lvp->s = s;1002 lvp->lp = lp;1003 lvp->nlp = nlp;1004 }1005 1006 void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char * dev, const char *name, const char *label, const char* group, IPerm p, double timeout, IPState s)1007 {1008 1009 strcpy(nvp->device, dev);1010 strcpy(nvp->name, name);1011 strcpy(nvp->label, label);1012 strcpy(nvp->group, group);1013 strcpy(nvp->timestamp, "");1014 1015 nvp->p = p;1016 nvp->timeout = timeout;1017 nvp->s = s;1018 nvp->np = np;1019 nvp->nnp = nnp;1020 1021 }1022 1023 void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char * dev, const char *name, const char *label, const char* group, IPerm p, double timeout, IPState s)1024 {1025 strcpy(tvp->device, dev);1026 strcpy(tvp->name, name);1027 strcpy(tvp->label, label);1028 strcpy(tvp->group, group);1029 strcpy(tvp->timestamp, "");1030 1031 tvp->p = p;1032 tvp->timeout = timeout;1033 tvp->s = s;1034 tvp->tp = tp;1035 tvp->ntp = ntp;1036 1037 }1038 1039 /*****************************************************************************1040 * convenience functions for use in your implementation of ISSnoopDevice().1041 */1042 1043 /* crack the snooped driver setNumberVector or defNumberVector message into1044 * the given INumberVectorProperty.1045 * return 0 if type, device and name match and all members are present, else1046 * return -11047 */1048 int1049 IUSnoopNumber (XMLEle *root, INumberVectorProperty *nvp)1050 {1051 char *dev, *name;1052 XMLEle *ep;1053 int i;1054 1055 /* check and crack type, device, name and state */1056 if (strcmp (tagXMLEle(root)+3, "NumberVector") ||1057 crackDN (root, &dev, &name, NULL) < 0)1058 return (-1);1059 if (strcmp (dev, nvp->device) || strcmp (name, nvp->name))1060 return (-1); /* not this property */1061 (void) crackIPState (findXMLAttValu (root,"state"), &nvp->s);1062 1063 /* match each INumber with a oneNumber */1064 for (i = 0; i < nvp->nnp; i++) {1065 for (ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) {1066 if (!strcmp (tagXMLEle(ep), "oneNumber") &&1067 !strcmp (nvp->np[i].name, findXMLAttValu(ep, "name"))) {1068 if (f_scansexa (pcdataXMLEle(ep), &nvp->np[i].value) < 0)1069 return (-1); /* bad number format */1070 break;1071 }1072 }1073 if (!ep)1074 return (-1); /* element not found */1075 }1076 1077 /* ok */1078 return (0);1079 }1080 1081 /* crack the snooped driver setTextVector or defTextVector message into1082 * the given ITextVectorProperty.1083 * return 0 if type, device and name match and all members are present, else1084 * return -11085 */1086 int1087 IUSnoopText (XMLEle *root, ITextVectorProperty *tvp)1088 {1089 char *dev, *name;1090 XMLEle *ep;1091 int i;1092 1093 /* check and crack type, device, name and state */1094 if (strcmp (tagXMLEle(root)+3, "TextVector") ||1095 crackDN (root, &dev, &name, NULL) < 0)1096 return (-1);1097 if (strcmp (dev, tvp->device) || strcmp (name, tvp->name))1098 return (-1); /* not this property */1099 (void) crackIPState (findXMLAttValu (root,"state"), &tvp->s);1100 1101 /* match each IText with a oneText */1102 for (i = 0; i < tvp->ntp; i++) {1103 for (ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) {1104 if (!strcmp (tagXMLEle(ep), "oneText") &&1105 !strcmp (tvp->tp[i].name, findXMLAttValu(ep, "name"))) {1106 IUSaveText (&tvp->tp[i], pcdataXMLEle(ep));1107 break;1108 }1109 }1110 if (!ep)1111 return (-1); /* element not found */1112 }1113 1114 /* ok */1115 return (0);1116 }1117 1118 /* crack the snooped driver setLightVector or defLightVector message into1119 * the given ILightVectorProperty. it is not necessary that all ILight names1120 * be found.1121 * return 0 if type, device and name match, else return -1.1122 */1123 int1124 IUSnoopLight (XMLEle *root, ILightVectorProperty *lvp)1125 {1126 char *dev, *name;1127 XMLEle *ep;1128 int i;1129 1130 /* check and crack type, device, name and state */1131 if (strcmp (tagXMLEle(root)+3, "LightVector") ||1132 crackDN (root, &dev, &name, NULL) < 0)1133 return (-1);1134 if (strcmp (dev, lvp->device) || strcmp (name, lvp->name))1135 return (-1); /* not this property */1136 1137 (void) crackIPState (findXMLAttValu (root,"state"), &lvp->s);1138 1139 /* match each oneLight with one ILight */1140 for (ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) {1141 if (!strcmp (tagXMLEle(ep), "oneLight")) {1142 const char *name = findXMLAttValu (ep, "name");1143 for (i = 0; i < lvp->nlp; i++) {1144 if (!strcmp (lvp->lp[i].name, name)) {1145 if (crackIPState(pcdataXMLEle(ep), &lvp->lp[i].s) < 0) {1146 return (-1); /* unrecognized state */1147 }1148 break;1149 }1150 }1151 }1152 }1153 1154 /* ok */1155 return (0);1156 }1157 1158 /* crack the snooped driver setSwitchVector or defSwitchVector message into the1159 * given ISwitchVectorProperty. it is not necessary that all ISwitch names be1160 * found.1161 * return 0 if type, device and name match, else return -1.1162 */1163 int1164 IUSnoopSwitch (XMLEle *root, ISwitchVectorProperty *svp)1165 {1166 char *dev, *name;1167 XMLEle *ep;1168 int i;1169 1170 /* check and crack type, device, name and state */1171 if (strcmp (tagXMLEle(root)+3, "SwitchVector") ||1172 crackDN (root, &dev, &name, NULL) < 0)1173 return (-1);1174 if (strcmp (dev, svp->device) || strcmp (name, svp->name))1175 return (-1); /* not this property */1176 (void) crackIPState (findXMLAttValu (root,"state"), &svp->s);1177 1178 /* match each oneSwitch with one ISwitch */1179 for (ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) {1180 if (!strcmp (tagXMLEle(ep), "oneSwitch")) {1181 const char *name = findXMLAttValu (ep, "name");1182 for (i = 0; i < svp->nsp; i++) {1183 if (!strcmp (svp->sp[i].name, name)) {1184 if (crackISState(pcdataXMLEle(ep), &svp->sp[i].s) < 0) {1185 return (-1); /* unrecognized state */1186 }1187 break;1188 }1189 }1190 }1191 }1192 1193 /* ok */1194 return (0);1195 }1196 1197 /* crack the snooped driver setBLOBVector message into the given1198 * IBLOBVectorProperty. it is not necessary that all IBLOB names be found.1199 * return 0 if type, device and name match, else return -1.1200 * N.B. we assume any existing blob in bvp has been malloced, which we free1201 * and replace with a newly malloced blob if found.1202 */1203 int1204 IUSnoopBLOB (XMLEle *root, IBLOBVectorProperty *bvp)1205 {1206 char *dev, *name;1207 XMLEle *ep;1208 int i;1209 1210 /* check and crack type, device, name and state */1211 if (strcmp (tagXMLEle(root), "setBLOBVector") ||1212 crackDN (root, &dev, &name, NULL) < 0)1213 return (-1);1214 if (strcmp (dev, bvp->device) || strcmp (name, bvp->name))1215 return (-1); /* not this property */1216 (void) crackIPState (findXMLAttValu (root,"state"), &bvp->s);1217 1218 /* match each oneBLOB with one IBLOB */1219 for (ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) {1220 if (!strcmp (tagXMLEle(ep), "oneBLOB")) {1221 const char *name = findXMLAttValu (ep, "name");1222 for (i = 0; i < bvp->nbp; i++) {1223 IBLOB *bp = &bvp->bp[i];1224 if (!strcmp (bp->name, name)) {1225 strcpy (bp->format, findXMLAttValu (ep,"format"));1226 bp->size = atof (findXMLAttValu (ep,"size"));1227 bp->bloblen = pcdatalenXMLEle(ep)+1;1228 if (bp->blob)1229 free (bp->blob);1230 bp->blob = strcpy(malloc(bp->bloblen),pcdataXMLEle(ep));1231 break;1232 }1233 }1234 }1235 }1236 1237 /* ok */1238 return (0);1239 }1240 1241 /* print usage message and exit (1) */1242 static void1243 usage(void)1244 {1245 fprintf (stderr, "Usage: %s [options]\n", me);1246 fprintf (stderr, "Purpose: INDI Device driver framework.\n");1247 fprintf (stderr, "Options:\n");1248 fprintf (stderr, " -v : more verbose to stderr\n");1249 1250 exit (1);1251 }1252 1253 /* callback when INDI client message arrives on stdin.1254 * collect and dispatch when see outter element closure.1255 * exit if OS trouble or see incompatable INDI version.1256 * arg is not used.1257 */1258 static void1259 clientMsgCB (int fd, void *arg)1260 {1261 char buf[1024], msg[1024], *bp;1262 int nr;1263 arg=arg;1264 1265 /* one read */1266 nr = read (fd, buf, sizeof(buf));1267 if (nr < 0) {1268 fprintf (stderr, "%s: %s\n", me, strerror(errno));1269 exit(1);1270 }1271 if (nr == 0) {1272 fprintf (stderr, "%s: EOF\n", me);1273 exit(1);1274 }1275 1276 /* crack and dispatch when complete */1277 for (bp = buf; nr-- > 0; bp++) {1278 XMLEle *root = readXMLEle (clixml, *bp, msg);1279 if (root) {1280 if (dispatch (root, msg) < 0)1281 fprintf (stderr, "%s dispatch error: %s\n", me, msg);1282 delXMLEle (root);1283 } else if (msg[0])1284 fprintf (stderr, "%s XML error: %s\n", me, msg);1285 }1286 1287 }1288 1289 /* crack the given INDI XML element and call driver's IS* entry points as they1290 * are recognized.1291 * return 0 if ok else -1 with reason in msg[].1292 * N.B. exit if getProperties does not proclaim a compatible version.1293 */1294 static int1295 dispatch (XMLEle *root, char msg[])1296 {1297 char *rtag = tagXMLEle(root);1298 XMLEle *ep;1299 int n,i=0;1300 1301 if (verbose)1302 prXMLEle (stderr, root, 0);1303 1304 /* check tag in surmised decreasing order of likelyhood */1305 1306 if (!strcmp (rtag, "newNumberVector")) {1307 static double *doubles;1308 static char **names;1309 static int maxn;1310 char *dev, *name;1311 1312 /* pull out device and name */1313 if (crackDN (root, &dev, &name, msg) < 0)1314 return (-1);1315 1316 /* seed for reallocs */1317 if (!doubles) {1318 doubles = (double *) malloc (1);1319 names = (char **) malloc (1);1320 }1321 1322 /* pull out each name/value pair */1323 for (n = 0, ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) {1324 if (strcmp (tagXMLEle(ep), "oneNumber") == 0) {1325 XMLAtt *na = findXMLAtt (ep, "name");1326 if (na) {1327 if (n >= maxn) {1328 /* grow for this and another */1329 int newsz = (maxn=n+1)*sizeof(double);1330 doubles = (double *) realloc(doubles,newsz);1331 newsz = maxn*sizeof(char *);1332 names = (char **) realloc (names, newsz);1333 }1334 if (f_scansexa (pcdataXMLEle(ep), &doubles[n]) < 0)1335 IDMessage (dev,"%s: Bad format %s", name,1336 pcdataXMLEle(ep));1337 else1338 names[n++] = valuXMLAtt(na);1339 }1340 }1341 }1342 1343 /* insure property is not RO */1344 for (i=0; i < nroCheck; i++)1345 {1346 if (!strcmp(roCheck[i].propName, name))1347 {1348 if (roCheck[i].perm == IP_RO)1349 return -1;1350 }1351 }1352 1353 /* invoke driver if something to do, but not an error if not */1354 if (n > 0)1355 ISNewNumber (dev, name, doubles, names, n);1356 else1357 IDMessage(dev,"%s: newNumberVector with no valid members",name);1358 return (0);1359 }1360 1361 if (!strcmp (rtag, "newSwitchVector")) {1362 static ISState *states;1363 static char **names;1364 static int maxn;1365 char *dev, *name;1366 XMLEle *ep;1367 1368 /* pull out device and name */1369 if (crackDN (root, &dev, &name, msg) < 0)1370 return (-1);1371 1372 /* seed for reallocs */1373 if (!states) {1374 states = (ISState *) malloc (1);1375 names = (char **) malloc (1);1376 }1377 1378 /* pull out each name/state pair */1379 for (n = 0, ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) {1380 if (strcmp (tagXMLEle(ep), "oneSwitch") == 0) {1381 XMLAtt *na = findXMLAtt (ep, "name");1382 if (na) {1383 if (n >= maxn) {1384 int newsz = (maxn=n+1)*sizeof(ISState);1385 states = (ISState *) realloc(states, newsz);1386 newsz = maxn*sizeof(char *);1387 names = (char **) realloc (names, newsz);1388 }1389 if (strcmp (pcdataXMLEle(ep),"On") == 0) {1390 states[n] = ISS_ON;1391 names[n] = valuXMLAtt(na);1392 n++;1393 } else if (strcmp (pcdataXMLEle(ep),"Off") == 0) {1394 states[n] = ISS_OFF;1395 names[n] = valuXMLAtt(na);1396 n++;1397 } else1398 IDMessage (dev, "%s: must be On or Off: %s", name,1399 pcdataXMLEle(ep));1400 }1401 }1402 }1403 1404 /* insure property is not RO */1405 for (i=0; i < nroCheck; i++)1406 {1407 if (!strcmp(roCheck[i].propName, name))1408 {1409 if (roCheck[i].perm == IP_RO)1410 return -1;1411 }1412 }1413 1414 /* invoke driver if something to do, but not an error if not */1415 if (n > 0)1416 ISNewSwitch (dev, name, states, names, n);1417 else1418 IDMessage(dev,"%s: newSwitchVector with no valid members",name);1419 return (0);1420 }1421 1422 if (!strcmp (rtag, "newTextVector")) {1423 static char **texts;1424 static char **names;1425 static int maxn;1426 char *dev, *name;1427 1428 /* pull out device and name */1429 if (crackDN (root, &dev, &name, msg) < 0)1430 return (-1);1431 1432 /* seed for reallocs */1433 if (!texts) {1434 texts = (char **) malloc (1);1435 names = (char **) malloc (1);1436 }1437 1438 /* pull out each name/text pair */1439 for (n = 0, ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) {1440 if (strcmp (tagXMLEle(ep), "oneText") == 0) {1441 XMLAtt *na = findXMLAtt (ep, "name");1442 if (na) {1443 if (n >= maxn) {1444 int newsz = (maxn=n+1)*sizeof(char *);1445 texts = (char **) realloc (texts, newsz);1446 names = (char **) realloc (names, newsz);1447 }1448 texts[n] = pcdataXMLEle(ep);1449 names[n] = valuXMLAtt(na);1450 n++;1451 }1452 }1453 }1454 1455 /* insure property is not RO */1456 for (i=0; i < nroCheck; i++)1457 {1458 if (!strcmp(roCheck[i].propName, name))1459 {1460 if (roCheck[i].perm == IP_RO)1461 return -1;1462 }1463 }1464 1465 /* invoke driver if something to do, but not an error if not */1466 if (n > 0)1467 ISNewText (dev, name, texts, names, n);1468 else1469 IDMessage (dev, "%s: set with no valid members", name);1470 return (0);1471 }1472 1473 if (!strcmp (rtag, "newBLOBVector")) {1474 static char **blobs;1475 static char **names;1476 static char **formats;1477 static int *blobsizes;1478 static int *sizes;1479 static int maxn;1480 char *dev, *name;1481 int i;1482 1483 /* pull out device and name */1484 if (crackDN (root, &dev, &name, msg) < 0)1485 return (-1);1486 1487 /* seed for reallocs */1488 if (!blobs) {1489 blobs = (char **) malloc (1);1490 names = (char **) malloc (1);1491 formats = (char **) malloc (1);1492 blobsizes = (int *) malloc (1);1493 sizes = (int *) malloc (1);1494 }1495 1496 /* pull out each name/BLOB pair, decode */1497 for (n = 0, ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) {1498 if (strcmp (tagXMLEle(ep), "oneBLOB") == 0) {1499 XMLAtt *na = findXMLAtt (ep, "name");1500 XMLAtt *fa = findXMLAtt (ep, "format");1501 XMLAtt *sa = findXMLAtt (ep, "size");1502 if (na && fa && sa) {1503 if (n >= maxn) {1504 int newsz = (maxn=n+1)*sizeof(char *);1505 blobs = (char **) realloc (blobs, newsz);1506 names = (char **) realloc (names, newsz);1507 formats = (char **) realloc(formats,newsz);1508 newsz = maxn*sizeof(int);1509 sizes = (int *) realloc(sizes,newsz);1510 blobsizes = (int *) realloc(blobsizes,newsz);1511 }1512 blobs[n] = malloc (3*pcdatalenXMLEle(ep)/4);1513 blobsizes[n] = from64tobits(blobs[n], pcdataXMLEle(ep));1514 names[n] = valuXMLAtt(na);1515 formats[n] = valuXMLAtt(fa);1516 sizes[n] = atoi(valuXMLAtt(sa));1517 n++;1518 }1519 }1520 }1521 1522 /* invoke driver if something to do, but not an error if not */1523 if (n > 0) {1524 ISNewBLOB (dev, name, sizes, blobsizes, blobs, formats,names,n);1525 for (i = 0; i < n; i++)1526 free (blobs[i]);1527 } else1528 IDMessage (dev, "%s: newBLOBVector with no valid members",name);1529 return (0);1530 }1531 1532 if (!strcmp (rtag, "getProperties")) {1533 XMLAtt *ap;1534 double v;1535 1536 /* check version */1537 ap = findXMLAtt (root, "version");1538 if (!ap) {1539 fprintf (stderr, "%s: getProperties missing version\n", me);1540 exit(1);1541 }1542 v = atof (valuXMLAtt(ap));1543 if (v > INDIV) {1544 fprintf (stderr, "%s: client version %g > %g\n", me, v, INDIV);1545 exit(1);1546 }1547 1548 /* ok */1549 ap = findXMLAtt (root, "device");1550 ISGetProperties (ap ? valuXMLAtt(ap) : NULL);1551 return (0);1552 }1553 1554 /* other commands might be from a snooped device.1555 * we don't know here which devices are being snooped so we send1556 * all remaining valid messages1557 */1558 if ( !strcmp (rtag, "setNumberVector") ||1559 !strcmp (rtag, "setTextVector") ||1560 !strcmp (rtag, "setLightVector") ||1561 !strcmp (rtag, "setSwitchVector") ||1562 !strcmp (rtag, "setBLOBVector") ||1563 !strcmp (rtag, "defNumberVector") ||1564 !strcmp (rtag, "defTextVector") ||1565 !strcmp (rtag, "defLightVector") ||1566 !strcmp (rtag, "defSwitchVector") ||1567 !strcmp (rtag, "defBLOBVector") ||1568 !strcmp (rtag, "message") ||1569 !strcmp (rtag, "delProperty")) {1570 ISSnoopDevice (root);1571 return (0);1572 }1573 1574 sprintf (msg, "Unknown command: %s", rtag);1575 return(1);1576 }1577 1578 /* pull out device and name attributes from root.1579 * return 0 if ok else -1 with reason in msg[].1580 */1581 static int1582 crackDN (XMLEle *root, char **dev, char **name, char msg[])1583 {1584 XMLAtt *ap;1585 1586 ap = findXMLAtt (root, "device");1587 if (!ap) {1588 sprintf (msg, "%s requires 'device' attribute", tagXMLEle(root));1589 return (-1);1590 }1591 *dev = valuXMLAtt(ap);1592 1593 ap = findXMLAtt (root, "name");1594 if (!ap) {1595 sprintf (msg, "%s requires 'name' attribute", tagXMLEle(root));1596 return (-1);1597 }1598 *name = valuXMLAtt(ap);1599 1600 return (0);1601 }1602 1603 /* return static string corresponding to the given property or light state */1604 const char *1605 pstateStr (IPState s)1606 {1607 switch (s) {1608 case IPS_IDLE: return ("Idle");1609 case IPS_OK: return ("Ok");1610 case IPS_BUSY: return ("Busy");1611 case IPS_ALERT: return ("Alert");1612 default:1613 fprintf (stderr, "Impossible IPState %d\n", s);1614 exit(1);1615 }1616 }1617 1618 /* crack string into IPState.1619 * return 0 if ok, else -11620 */1621 static int1622 crackIPState (const char *str, IPState *ip)1623 {1624 if (!strcmp (str, "Idle")) *ip = IPS_IDLE;1625 else if (!strcmp (str, "Ok")) *ip = IPS_OK;1626 else if (!strcmp (str, "Busy")) *ip = IPS_BUSY;1627 else if (!strcmp (str, "Alert")) *ip = IPS_ALERT;1628 else return (-1);1629 return (0);1630 }1631 1632 /* crack string into ISState.1633 * return 0 if ok, else -11634 */1635 static int1636 crackISState (const char *str, ISState *ip)1637 {1638 if (!strcmp (str, "On")) *ip = ISS_ON;1639 else if (!strcmp (str, "Off")) *ip = ISS_OFF;1640 else return (-1);1641 return (0);1642 }1643 1644 /* return static string corresponding to the given switch state */1645 const char *1646 sstateStr (ISState s)1647 {1648 switch (s) {1649 case ISS_ON: return ("On");1650 case ISS_OFF: return ("Off");1651 default:1652 fprintf (stderr, "Impossible ISState %d\n", s);1653 exit(1);1654 }1655 }1656 1657 /* return static string corresponding to the given Rule */1658 const char *1659 ruleStr (ISRule r)1660 {1661 switch (r) {1662 case ISR_1OFMANY: return ("OneOfMany");1663 case ISR_ATMOST1: return ("AtMostOne");1664 case ISR_NOFMANY: return ("AnyOfMany");1665 default:1666 fprintf (stderr, "Impossible ISRule %d\n", r);1667 exit(1);1668 }1669 }1670 1671 /* return static string corresponding to the given IPerm */1672 const char *1673 permStr (IPerm p)1674 {1675 switch (p) {1676 case IP_RO: return ("ro");1677 case IP_WO: return ("wo");1678 case IP_RW: return ("rw");1679 default:1680 fprintf (stderr, "Impossible IPerm %d\n", p);1681 exit(1);1682 }1683 }1684 1685 /* print the boilerplate comment introducing xml */1686 static void1687 xmlv1()1688 {1689 printf ("<?xml version='1.0'?>\n");1690 } -
BAORadio/libindi/libindi/indiserver.c
r490 r501 92 92 } Snoopee; 93 93 94 struct 95 { 96 const char *name; /* Path to FIFO for dynamic startups & shutdowns of drivers */ 97 int fd; 98 FILE *fs; 99 } fifo; 100 94 101 /* info for each connected client */ 95 102 typedef struct { … … 109 116 /* info for each connected driver */ 110 117 typedef struct { 111 c onst char *name; /* persistent mallocedname */118 char name[MAXINDIDEVICE]; /* persistent name */ 112 119 char dev[MAXINDIDEVICE]; /* device served by this driver */ 120 int active; /* 1 when this record is in use */ 113 121 Snoopee *sprops; /* malloced array of props we snoop */ 114 122 int nsprops; /* n entries in sprops[] */ … … 136 144 static void noZombies (void); 137 145 static void noSIGPIPE (void); 146 static void indiFIFO(void); 138 147 static void indiRun (void); 139 148 static void indiListen (void); 149 static void newFIFO(void); 140 150 static void newClient (void); 141 151 static int newClSocket (void); … … 146 156 static void startRemoteDvr (DvrInfo *dp); 147 157 static int openINDIServer (char host[], int indi_port); 148 static void restartDvr (DvrInfo *dp);158 static void shutdownDvr (DvrInfo *dp, int restart); 149 159 static void q2RDrivers (const char *dev, Msg *mp, XMLEle *root); 150 160 static void q2SDrivers (int isblob, const char *dev, const char *name, Msg *mp, … … 209 219 ac--; 210 220 break; 221 case 'f': 222 if (ac < 2) { 223 fprintf (stderr, "-f requires fifo node\n"); 224 usage(); 225 } 226 fifo.name = *++av; 227 ac--; 228 break; 211 229 case 'v': 212 230 verbose++; … … 218 236 219 237 /* at this point there are ac args in av[] to name our drivers */ 220 if (ac == 0)221 238 if (ac == 0 && !fifo.name) 239 usage(); 222 240 223 241 /* take care of some unixisms */ … … 230 248 231 249 /* create driver info array all at once since size never changes */ 232 250 ndvrinfo = ac; 233 251 dvrinfo = (DvrInfo *) calloc (ndvrinfo, sizeof(DvrInfo)); 234 252 235 253 /* start each driver */ 236 237 dvrinfo[ac].name = *av++;254 while (ac-- > 0) { 255 strcpy(dvrinfo[ac].name, *av++); 238 256 startDvr (&dvrinfo[ac]); 239 257 } 240 258 241 259 /* announce we are online */ 242 260 indiListen(); 261 262 /* Load up FIFO, if available */ 263 indiFIFO(); 243 264 244 265 /* handle new clients and all io */ … … 271 292 fprintf (stderr, "Code %s. Protocol %g.\n", "$Revision: 726523 $", INDIV); 272 293 fprintf (stderr, "Options:\n"); 273 fprintf (stderr, " -l d : log driver messages to <d>/YYYY-MM-DD.islog\n"); 274 fprintf (stderr, " -m m : kill client if gets more than this many MB behind, default %d\n", DEFMAXQSIZ); 275 fprintf (stderr, " -p p : alternate IP port, default %d\n", INDIPORT); 276 fprintf (stderr, " -v : show key events, no traffic\n"); 277 fprintf (stderr, " -vv : -v + key message content\n"); 278 fprintf (stderr, " -vvv : -vv + complete xml\n"); 279 fprintf (stderr, "driver : executable or device@host[:port]\n"); 294 fprintf (stderr, " -l d : log driver messages to <d>/YYYY-MM-DD.islog\n"); 295 fprintf (stderr, " -m m : kill client if gets more than this many MB behind, default %d\n", DEFMAXQSIZ); 296 fprintf (stderr, " -p p : alternate IP port, default %d\n", INDIPORT); 297 fprintf (stderr, " -f path : Path to fifo for dynamic startup and shutdown of drivers.\n"); 298 fprintf (stderr, " -v : show key events, no traffic\n"); 299 fprintf (stderr, " -vv : -v + key message content\n"); 300 fprintf (stderr, " -vvv : -vv + complete xml\n"); 301 fprintf (stderr, "driver : executable or device@host[:port]\n"); 280 302 281 303 exit (2); … … 307 329 } 308 330 331 static DvrInfo * allocDvr () 332 { 333 DvrInfo *dp = NULL; 334 int dvi; 335 336 /* try to reuse a drivber slot, else add one */ 337 for (dvi = 0; dvi < ndvrinfo; dvi++) 338 if (!(dp = &dvrinfo[dvi])->active) 339 break; 340 if (dvi == ndvrinfo) 341 { 342 /* grow dvrinfo */ 343 dvrinfo = (DvrInfo *) realloc (dvrinfo, (ndvrinfo+1)*sizeof(DvrInfo)); 344 if (!dvrinfo) { 345 fprintf (stderr, "no memory for new drivers\n"); 346 Bye(); 347 } 348 dp = &dvrinfo[ndvrinfo++]; 349 } 350 351 /* rig up new dvrinfo entry */ 352 memset (dp, 0, sizeof(*dp)); 353 dp->active = 1; 354 355 return dp; 356 357 } 358 309 359 /* start the given INDI driver process or connection. 310 360 * exit if trouble. … … 382 432 dp->efd = ep[0]; 383 433 dp->lp = newLilXML(); 384 434 dp->msgq = newFQ(1); 385 435 dp->sprops = (Snoopee*) malloc (1); /* seed for realloc */ 386 436 dp->nsprops = 0; 387 437 dp->nsent = 0; 438 dp->active = 1; 388 439 389 440 /* first message primes driver to report its properties -- dev known … … 436 487 dp->nsprops = 0; 437 488 dp->nsent = 0; 489 dp->active = 1; 438 490 439 491 /* N.B. storing name now is key to limiting outbound traffic to this … … 544 596 } 545 597 598 /* Attempt to open up FIFO */ 599 static void indiFIFO(void) 600 { 601 /* Open up FIFO, if available */ 602 if (fifo.name) 603 { 604 fifo.fd = open(fifo.name, O_RDONLY); 605 if (fifo.fd < 0) 606 { 607 fprintf(stderr, "%s: open(%s): %s.\n", indi_tstamp(NULL), fifo.name, strerror(errno)); 608 Bye(); 609 } 610 611 fifo.fs = fdopen(fifo.fd, "r"); 612 } 613 } 614 546 615 /* service traffic from clients and drivers */ 547 616 static void … … 549 618 { 550 619 fd_set rs, ws; 551 int maxfd;620 int maxfd=0; 552 621 int i, s; 553 622 … … 556 625 FD_ZERO(&rs); 557 626 627 if (fifo.name && fifo.fd > 0) 628 { 629 FD_SET(fifo.fd, &rs); 630 maxfd = fifo.fd; 631 } 632 558 633 /* always listen for new clients */ 559 634 FD_SET(lsocket, &rs); 560 maxfd = lsocket; 635 if (lsocket > maxfd) 636 maxfd = lsocket; 561 637 562 638 /* add all client readers and client writers with work to send */ … … 573 649 574 650 /* add all driver readers and driver writers with work to send */ 575 for (i = 0; i < ndvrinfo; i++) { 651 for (i = 0; i < ndvrinfo; i++) 652 { 576 653 DvrInfo *dp = &dvrinfo[i]; 577 FD_SET(dp->rfd, &rs); 578 if (dp->rfd > maxfd) 579 maxfd = dp->rfd; 580 if (dp->pid != REMOTEDVR) { 581 FD_SET(dp->efd, &rs); 582 if (dp->efd > maxfd) 583 maxfd = dp->efd; 584 } 585 if (nFQ(dp->msgq) > 0) { 586 FD_SET(dp->wfd, &ws); 587 if (dp->wfd > maxfd) 588 maxfd = dp->wfd; 589 } 654 if (dp->active) 655 { 656 FD_SET(dp->rfd, &rs); 657 if (dp->rfd > maxfd) 658 maxfd = dp->rfd; 659 if (dp->pid != REMOTEDVR) 660 { 661 FD_SET(dp->efd, &rs); 662 if (dp->efd > maxfd) 663 maxfd = dp->efd; 664 } 665 if (nFQ(dp->msgq) > 0) 666 { 667 FD_SET(dp->wfd, &ws); 668 if (dp->wfd > maxfd) 669 maxfd = dp->wfd; 670 } 671 } 590 672 } 591 673 … … 597 679 Bye(); 598 680 } 681 682 683 /* new command from FIFO? */ 684 if (s > 0 && FD_ISSET(fifo.fd, &rs)) { 685 newFIFO(); 686 s--; 687 } 599 688 600 689 /* new client? */ … … 642 731 } 643 732 733 /* Read commands from FIFO and process them. Start/stop drivers accordingly */ 734 static void newFIFO(void) 735 { 736 char line[MAXRBUF], tDriver[MAXRBUF], tConfig[MAXRBUF], tDev[MAXRBUF]; 737 static char *envDev=NULL, *envConfig=NULL; 738 const char *delm = " "; 739 char *token, *cp; 740 DvrInfo *dp = NULL; 741 int startCmd=0; 742 743 if (envDev == NULL) 744 envDev = (char *) malloc(MAXRBUF* sizeof(char)); 745 if (envConfig == NULL) 746 envConfig = (char *) malloc(MAXRBUF * sizeof(char)); 747 748 while ( fgets (line, MAXRBUF, fifo.fs) != NULL) 749 { 750 //fprintf(stderr, "FIFO: %s\n", line); 751 tDev[0] = '\0', tDriver[0] = '\0', tConfig[0] = '\0', envDev[0] = '\0', envConfig[0] = '\0'; 752 cp = strdup(line); 753 754 token = strsep(&cp, delm); 755 756 if (!strcmp(token, "start") || !strcmp(token, "stop")) 757 { 758 if (!strcmp(token, "start")) 759 startCmd = 1; 760 761 token = strsep(&cp, delm); 762 763 if (!token) 764 continue; 765 766 strncpy(tDriver, token, MAXRBUF); 767 768 if (verbose) 769 fprintf(stderr, "FIFO: Request for %s driver: %s\n", (startCmd == 1) ? "starting" : "stopping", tDriver); 770 771 /* Find more name + config */ 772 token = strsep(&cp, delm); 773 774 if (token) 775 { 776 /* If config file detected, copy it */ 777 if (strstr(token, ".xml")) 778 strncpy(tConfig, token, MAXRBUF); 779 /* Get rid of quotes */ 780 else if (strstr(token, "\"") || strstr(token, "'")) 781 { 782 strncat(tDev, ++token, MAXRBUF); 783 while (token = strsep(&cp, delm) ) 784 { 785 strcat(tDev, " "); 786 strncat(tDev, token, MAXRBUF); 787 if (strstr(token, "\"") || strstr(token, "'")) 788 { 789 tDev[strlen(tDev)-1] = '\0'; 790 break; 791 } 792 } 793 } 794 else 795 strncpy(tDev, token, MAXRBUF); 796 797 /* Find config, if there is any */ 798 token = strsep(&cp, delm); 799 if (token) 800 { 801 /* Get rid of quotes */ 802 if (strstr(token, "\"") || strstr(token, "'")) 803 { 804 strncat(tConfig, ++token, MAXRBUF); 805 while (token = strsep(&cp, delm) ) 806 { 807 strcat(tConfig, " "); 808 strncat(tConfig, token, MAXRBUF); 809 810 if (strstr(token, "\"") || strstr(token, "'")) 811 { 812 tConfig[strlen(tConfig)-1] = '\0'; 813 break; 814 } 815 } 816 } 817 else 818 strncpy(tConfig, token, MAXRBUF); 819 } 820 } 821 822 /* Did we find device name? */ 823 if (tDev[0]) 824 { 825 snprintf(envDev, MAXRBUF, "INDIDEV=%s", tDev); 826 //fprintf(stderr, "With name: %s\n", envDev); 827 putenv(envDev); 828 829 //fprintf(stderr, "envionment check INDIDEV: %s\n", getenv("INDIDEV")); 830 } 831 832 /* Did we find config file */ 833 if (tConfig[0]) 834 { 835 snprintf(envConfig, MAXRBUF, "INDICONFIG=%s", tConfig); 836 //fprintf(stderr, "With config: %s\n", envConfig); 837 putenv(envConfig); 838 } 839 840 if (startCmd) 841 { 842 if (verbose) 843 fprintf(stderr, "FIFO: Starting driver %s\n", tDriver); 844 dp = allocDvr(); 845 strncpy(dp->name, tDriver, MAXINDIDEVICE); 846 strncpy(dp->dev, tDev, MAXINDIDEVICE); 847 startDvr (dp); 848 } 849 else 850 { 851 for (dp = dvrinfo; dp < &dvrinfo[ndvrinfo]; dp++) 852 { 853 if (!strcmp(dp->name, tDriver)) 854 { 855 /* If device name is given, check against it before shutting down */ 856 if (tDev[0] && strcmp(dp->dev, tDev)) 857 continue; 858 859 if (verbose) 860 fprintf(stderr, "FIFO: Shutting down driver: %s\n", tDriver); 861 862 shutdownDvr(dp, 0); 863 864 /* Inform clients that this driver is dead */ 865 XMLEle *root = addXMLEle (NULL, "delProperty"); 866 addXMLAtt(root, "device", dp->dev); 867 Msg * mp = newMsg(); 868 869 q2Clients(NULL, 0, dp->dev, NULL, mp, root); 870 if (mp->count > 0) 871 setMsgXMLEle (mp, root); 872 else 873 freeMsg (mp); 874 delXMLEle (root); 875 876 break; 877 878 } 879 } 880 } 881 } 882 } 883 } 884 644 885 /* prepare for new client arriving on lsocket. 645 886 * exit if trouble. … … 753 994 /* echo new* commands back to other clients */ 754 995 if (!strncmp (roottag, "new", 3)) { 755 996 if (q2Clients (cp, isblob, dev, name, mp, root) < 0) 756 997 shutany++; 757 998 } … … 798 1039 fprintf (stderr, "%s: Driver %s: stdin EOF\n", 799 1040 indi_tstamp(NULL), dp->name); 800 restartDvr (dp);1041 shutdownDvr (dp, 1); 801 1042 return (-1); 802 1043 } … … 872 1113 fprintf (stderr, "%s: Driver %s: XML read: %.*s\n", ts, 873 1114 dp->name, nr, buf); 874 restartDvr (dp);1115 shutdownDvr (dp, 1); 875 1116 return (-1); 876 1117 } … … 899 1140 fprintf (stderr, "%s: Driver %s: stderr EOF\n", 900 1141 indi_tstamp(NULL), dp->name); 901 restartDvr (dp);1142 shutdownDvr (dp, 1); 902 1143 return (-1); 903 1144 } … … 949 1190 /* close down the given driver and restart */ 950 1191 static void 951 restartDvr (DvrInfo *dp)1192 shutdownDvr (DvrInfo *dp, int restart) 952 1193 { 953 1194 Msg *mp; … … 960 1201 } else { 961 1202 /* local pipe connection */ 962 1203 kill (dp->pid, SIGKILL); /* we've insured there are no zombies */ 963 1204 close (dp->wfd); 964 1205 close (dp->rfd); … … 969 1210 free (dp->sprops); 970 1211 delLilXML (dp->lp); 1212 1213 /* ok now to recycle */ 1214 dp->active = 0; 971 1215 972 1216 /* decrement and possibly free any unsent messages for this client */ … … 976 1220 delFQ (dp->msgq); 977 1221 978 fprintf (stderr, "%s: Driver %s: restart #%d\n", indi_tstamp(NULL), 979 dp->name, ++dp->restarts); 980 startDvr (dp); 1222 if (restart) 1223 { 1224 fprintf (stderr, "%s: Driver %s: restart #%d\n", indi_tstamp(NULL), 1225 dp->name, ++dp->restarts); 1226 startDvr (dp); 1227 } 1228 981 1229 } 982 1230 … … 1285 1533 fprintf (stderr, "%s: Driver %s: write: %s\n", indi_tstamp(NULL), 1286 1534 dp->name, strerror(errno)); 1287 restartDvr (dp);1535 shutdownDvr (dp, 1); 1288 1536 return (-1); 1289 1537 } … … 1325 1573 Property *pp = &cp->props[i]; 1326 1574 if (!strcmp (pp->dev, dev) && 1327 1575 (!pp->name[0] || !strcmp(pp->name, name))) 1328 1576 return (0); 1329 1577 } … … 1459 1707 logDMsg (XMLEle *root, const char *dev) 1460 1708 { 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1709 char stamp[64]; 1710 char logfn[1024]; 1711 const char *ts, *ms; 1712 FILE *fp; 1713 1714 /* get message, if any */ 1715 ms = findXMLAttValu (root, "message"); 1716 if (!ms[0]) 1717 return; 1718 1719 /* get timestamp now if not provided */ 1720 ts = findXMLAttValu (root, "timestamp"); 1721 if (!ts[0]) 1722 { 1723 indi_tstamp (stamp); 1724 ts = stamp; 1725 } 1726 1727 /* append to log file, name is date portion of time stamp */ 1728 sprintf (logfn, "%s/%.10s.islog", ldir, ts); 1729 fp = fopen (logfn, "a"); 1730 if (!fp) 1731 return; /* oh well */ 1732 fprintf (fp, "%s: %s: %s\n", ts, dev, ms); 1733 fclose (fp); 1486 1734 } 1487 1735 -
BAORadio/libindi/libindi/libindi.pc.cmake
r490 r501 10 10 Libs: -L@LIB_DESTINATION@ -lindi 11 11 Cflags: -I@INCLUDE_INSTALL_DIR@ -@INCLUDE_INSTALL_DIR@/libindi 12 -
BAORadio/libindi/libindi/libs/indicom.c
r490 r501 24 24 */ 25 25 26 /* needed for sincos() in math.h */27 #ifndef _GNU_SOURCE28 #define _GNU_SOURCE29 #endif30 #ifdef _WIN3231 #define CX _CX32 #define CY _CY33 #endif34 26 #include <stdlib.h> 35 27 #include <math.h> … … 40 32 #include <errno.h> 41 33 #include <stdarg.h> 42 43 #include <config.h> 34 #include <sys/param.h> 35 36 //#include <config.h> 44 37 45 38 #ifdef HAVE_NOVA_H 46 39 #include <libnova.h> 47 40 #endif 48 49 41 50 42 #include "indicom.h" … … 52 44 #undef CX 53 45 #undef CY 54 #endif55 const char * Direction[] = { "North", "West", "East", "South", "All"};56 const char * SolarSystem[] = { "Mercury", "Venus", "Moon", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"};57 58 /* make it compile on solaris */59 #ifndef M_PI60 #define M_PI 3.1415926535897932384626433832795028841971693993751058209749445961 46 #endif 62 47 … … 67 52 #define PARITY_ODD 2 68 53 #endif 54 55 #define MAXRBUF 2048 56 57 #include "indidevapi.h" 69 58 70 59 void getSexComponents(double value, int *d, int *m, int *s); … … 387 376 } 388 377 378 #ifdef BSD 379 // BSD - OSX version 380 int tty_connect(const char *device, int bit_rate, int word_size, int parity, int stop_bits, int *fd) 381 { 382 int t_fd = -1; 383 int bps; 384 char msg[80]; 385 int handshake; 386 struct termios tty_setting; 387 388 // Open the serial port read/write, with no controlling terminal, and don't wait for a connection. 389 // The O_NONBLOCK flag also causes subsequent I/O on the device to be non-blocking. 390 // See open(2) ("man 2 open") for details. 391 392 t_fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK); 393 if (t_fd == -1) 394 { 395 printf("Error opening serial port %s - %s(%d).\n", 396 device, strerror(errno), errno); 397 goto error; 398 } 399 400 // Note that open() follows POSIX semantics: multiple open() calls to the same file will succeed 401 // unless the TIOCEXCL ioctl is issued. This will prevent additional opens except by root-owned 402 // processes. 403 // See tty(4) ("man 4 tty") and ioctl(2) ("man 2 ioctl") for details. 404 405 if (ioctl(t_fd, TIOCEXCL) == -1) 406 { 407 printf("Error setting TIOCEXCL on %s - %s(%d).\n", 408 device, strerror(errno), errno); 409 goto error; 410 } 411 412 // Now that the device is open, clear the O_NONBLOCK flag so subsequent I/O will block. 413 // See fcntl(2) ("man 2 fcntl") for details. 414 415 if (fcntl(t_fd, F_SETFL, 0) == -1) 416 { 417 printf("Error clearing O_NONBLOCK %s - %s(%d).\n", 418 device, strerror(errno), errno); 419 goto error; 420 } 421 422 // Get the current options and save them so we can restore the default settings later. 423 if (tcgetattr(t_fd, &tty_setting) == -1) 424 { 425 printf("Error getting tty attributes %s - %s(%d).\n", 426 device, strerror(errno), errno); 427 goto error; 428 } 429 430 // Set raw input (non-canonical) mode, with reads blocking until either a single character 431 // has been received or a one second timeout expires. 432 // See tcsetattr(4) ("man 4 tcsetattr") and termios(4) ("man 4 termios") for details. 433 434 cfmakeraw(&tty_setting); 435 tty_setting.c_cc[VMIN] = 1; 436 tty_setting.c_cc[VTIME] = 10; 437 438 // The baud rate, word length, and handshake options can be set as follows: 439 switch (bit_rate) { 440 case 0: 441 bps = B0; 442 break; 443 case 50: 444 bps = B50; 445 break; 446 case 75: 447 bps = B75; 448 break; 449 case 110: 450 bps = B110; 451 break; 452 case 134: 453 bps = B134; 454 break; 455 case 150: 456 bps = B150; 457 break; 458 case 200: 459 bps = B200; 460 break; 461 case 300: 462 bps = B300; 463 break; 464 case 600: 465 bps = B600; 466 break; 467 case 1200: 468 bps = B1200; 469 break; 470 case 1800: 471 bps = B1800; 472 break; 473 case 2400: 474 bps = B2400; 475 break; 476 case 4800: 477 bps = B4800; 478 break; 479 case 9600: 480 bps = B9600; 481 break; 482 case 19200: 483 bps = B19200; 484 break; 485 case 38400: 486 bps = B38400; 487 break; 488 case 57600: 489 bps = B57600; 490 break; 491 case 115200: 492 bps = B115200; 493 break; 494 case 230400: 495 bps = B230400; 496 break; 497 default: 498 if (snprintf(msg, sizeof(msg), "tty_connect: %d is not a valid bit rate.", bit_rate) 0) 499 perror(NULL); 500 else 501 perror(msg); 502 return TTY_PARAM_ERROR; 503 } 504 505 cfsetspeed(&tty_setting, bps); // Set baud rate 506 /* word size */ 507 switch (word_size) { 508 case 5: 509 tty_setting.c_cflag |= CS5; 510 break; 511 case 6: 512 tty_setting.c_cflag |= CS6; 513 break; 514 case 7: 515 tty_setting.c_cflag |= CS7; 516 break; 517 case 8: 518 tty_setting.c_cflag |= CS8; 519 break; 520 default: 521 522 fprintf( stderr, "Default\n") ; 523 if (snprintf(msg, sizeof(msg), "tty_connect: %d is not a valid data bit count.", word_size) 0) 524 perror(NULL); 525 else 526 perror(msg); 527 528 return TTY_PARAM_ERROR; 529 } 530 531 /* parity */ 532 switch (parity) { 533 case PARITY_NONE: 534 break; 535 case PARITY_EVEN: 536 tty_setting.c_cflag |= PARENB; 537 break; 538 case PARITY_ODD: 539 tty_setting.c_cflag |= PARENB | PARODD; 540 break; 541 default: 542 543 fprintf( stderr, "Default1\n") ; 544 if (snprintf(msg, sizeof(msg), "tty_connect: %d is not a valid parity selection value.", parity) 0) 545 perror(NULL); 546 else 547 perror(msg); 548 549 return TTY_PARAM_ERROR; 550 } 551 552 /* stop_bits */ 553 switch (stop_bits) { 554 case 1: 555 break; 556 case 2: 557 tty_setting.c_cflag |= CSTOPB; 558 break; 559 default: 560 fprintf( stderr, "Default2\n") ; 561 if (snprintf(msg, sizeof(msg), "tty_connect: %d is not a valid stop bit count.", stop_bits) 0) 562 perror(NULL); 563 else 564 perror(msg); 565 566 return TTY_PARAM_ERROR; 567 } 568 569 #if defined(MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) 570 // Starting with Tiger, the IOSSIOSPEED ioctl can be used to set arbitrary baud rates 571 // other than those specified by POSIX. The driver for the underlying serial hardware 572 // ultimately determines which baud rates can be used. This ioctl sets both the input 573 // and output speed. 574 575 speed_t speed = 14400; // Set 14400 baud 576 if (ioctl(fileDescriptor, IOSSIOSPEED, &speed) == -1) 577 { 578 printf("Error calling ioctl(..., IOSSIOSPEED, ...) %s - %s(%d).\n", 579 bsdPath, strerror(errno), errno); 580 } 581 #endif 582 583 // Cause the new options to take effect immediately. 584 if (tcsetattr(t_fd, TCSANOW, &tty_setting) == -1) 585 { 586 printf("Error setting tty attributes %s - %s(%d).\n", 587 device, strerror(errno), errno); 588 goto error; 589 } 590 591 // To set the modem handshake lines, use the following ioctls. 592 // See tty(4) ("man 4 tty") and ioctl(2) ("man 2 ioctl") for details. 593 594 if (ioctl(t_fd, TIOCSDTR) == -1) // Assert Data Terminal Ready (DTR) 595 { 596 printf("Error asserting DTR %s - %s(%d).\n", 597 device, strerror(errno), errno); 598 } 599 600 if (ioctl(t_fd, TIOCCDTR) == -1) // Clear Data Terminal Ready (DTR) 601 { 602 printf("Error clearing DTR %s - %s(%d).\n", 603 device, strerror(errno), errno); 604 } 605 606 handshake = TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR; 607 if (ioctl(t_fd, TIOCMSET, &handshake) == -1) 608 // Set the modem lines depending on the bits set in handshake 609 { 610 printf("Error setting handshake lines %s - %s(%d).\n", 611 device, strerror(errno), errno); 612 } 613 614 // To read the state of the modem lines, use the following ioctl. 615 // See tty(4) ("man 4 tty") and ioctl(2) ("man 2 ioctl") for details. 616 617 if (ioctl(t_fd, TIOCMGET, &handshake) == -1) 618 // Store the state of the modem lines in handshake 619 { 620 printf("Error getting handshake lines %s - %s(%d).\n", 621 device, strerror(errno), errno); 622 } 623 624 printf("Handshake lines currently set to %d\n", handshake); 625 626 #if defined(MAC_OS_X_VERSION_10_3) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3) 627 unsigned long mics = 1UL; 628 629 // Set the receive latency in microseconds. Serial drivers use this value to determine how often to 630 // dequeue characters received by the hardware. Most applications don't need to set this value: if an 631 // app reads lines of characters, the app can't do anything until the line termination character has been 632 // received anyway. The most common applications which are sensitive to read latency are MIDI and IrDA 633 // applications. 634 635 if (ioctl(t_fd, IOSSDATALAT, &mics) == -1) 636 { 637 // set latency to 1 microsecond 638 printf("Error setting read latency %s - %s(%d).\n", 639 device, strerror(errno), errno); 640 goto error; 641 } 642 #endif 643 644 *fd = t_fd; 645 /* return success */ 646 return TTY_OK; 647 648 // Failure path 649 error: 650 if (t_fd != -1) 651 { 652 close(t_fd); 653 } 654 655 return TTY_PORT_FAILURE; 656 } 657 #else 389 658 int tty_connect(const char *device, int bit_rate, int word_size, int parity, int stop_bits, int *fd) 390 659 { … … 577 846 #endif 578 847 } 848 // Unix - Linux version 849 850 #endif 851 579 852 580 853 int tty_disconnect(int fd) … … 644 917 } 645 918 } 919 920 /* return static string corresponding to the given property or light state */ 921 const char * 922 pstateStr (IPState s) 923 { 924 switch (s) { 925 case IPS_IDLE: return ("Idle"); 926 case IPS_OK: return ("Ok"); 927 case IPS_BUSY: return ("Busy"); 928 case IPS_ALERT: return ("Alert"); 929 default: 930 fprintf (stderr, "Impossible IPState %d\n", s); 931 exit(1); 932 } 933 } 934 935 /* crack string into IPState. 936 * return 0 if ok, else -1 937 */ 938 int 939 crackIPState (const char *str, IPState *ip) 940 { 941 if (!strcmp (str, "Idle")) *ip = IPS_IDLE; 942 else if (!strcmp (str, "Ok")) *ip = IPS_OK; 943 else if (!strcmp (str, "Busy")) *ip = IPS_BUSY; 944 else if (!strcmp (str, "Alert")) *ip = IPS_ALERT; 945 else return (-1); 946 return (0); 947 } 948 949 /* crack string into ISState. 950 * return 0 if ok, else -1 951 */ 952 int 953 crackISState (const char *str, ISState *ip) 954 { 955 if (!strcmp (str, "On")) *ip = ISS_ON; 956 else if (!strcmp (str, "Off")) *ip = ISS_OFF; 957 else return (-1); 958 return (0); 959 } 960 961 int 962 crackIPerm (const char *str, IPerm *ip) 963 { 964 if (!strcmp (str, "rw")) *ip = IP_RW; 965 else if (!strcmp (str, "ro")) *ip = IP_RO; 966 else if (!strcmp (str, "wo")) *ip = IP_WO; 967 else return (-1); 968 return (0); 969 } 970 971 int crackISRule (const char *str, ISRule *ip) 972 { 973 if (!strcmp (str, "OneOfMany")) *ip = ISR_1OFMANY; 974 else if (!strcmp (str, "AtMostOne")) *ip = ISR_ATMOST1; 975 else if (!strcmp (str, "AnyOfMany")) *ip = ISR_NOFMANY; 976 else return (-1); 977 return (0); 978 } 979 980 /* return static string corresponding to the given switch state */ 981 const char * 982 sstateStr (ISState s) 983 { 984 switch (s) { 985 case ISS_ON: return ("On"); 986 case ISS_OFF: return ("Off"); 987 default: 988 fprintf (stderr, "Impossible ISState %d\n", s); 989 } 990 } 991 992 /* return static string corresponding to the given Rule */ 993 const char * 994 ruleStr (ISRule r) 995 { 996 switch (r) { 997 case ISR_1OFMANY: return ("OneOfMany"); 998 case ISR_ATMOST1: return ("AtMostOne"); 999 case ISR_NOFMANY: return ("AnyOfMany"); 1000 default: 1001 fprintf (stderr, "Impossible ISRule %d\n", r); 1002 } 1003 } 1004 1005 /* return static string corresponding to the given IPerm */ 1006 const char * 1007 permStr (IPerm p) 1008 { 1009 switch (p) { 1010 case IP_RO: return ("ro"); 1011 case IP_WO: return ("wo"); 1012 case IP_RW: return ("rw"); 1013 default: 1014 fprintf (stderr, "Impossible IPerm %d\n", p); 1015 } 1016 } 1017 1018 /* print the boilerplate comment introducing xml */ 1019 void 1020 xmlv1() 1021 { 1022 printf ("<?xml version='1.0'?>\n"); 1023 } 1024 1025 /* pull out device and name attributes from root. 1026 * return 0 if ok else -1 with reason in msg[]. 1027 */ 1028 int 1029 crackDN (XMLEle *root, char **dev, char **name, char msg[]) 1030 { 1031 XMLAtt *ap; 1032 1033 ap = findXMLAtt (root, "device"); 1034 if (!ap) { 1035 sprintf (msg, "%s requires 'device' attribute", tagXMLEle(root)); 1036 return (-1); 1037 } 1038 *dev = valuXMLAtt(ap); 1039 1040 ap = findXMLAtt (root, "name"); 1041 if (!ap) { 1042 sprintf (msg, "%s requires 'name' attribute", tagXMLEle(root)); 1043 return (-1); 1044 } 1045 *name = valuXMLAtt(ap); 1046 1047 return (0); 1048 } 1049 1050 /* find a member of an IText vector, else NULL */ 1051 IText * 1052 IUFindText (const ITextVectorProperty *tvp, const char *name) 1053 { 1054 int i; 1055 1056 for (i = 0; i < tvp->ntp; i++) 1057 if (strcmp (tvp->tp[i].name, name) == 0) 1058 return (&tvp->tp[i]); 1059 fprintf (stderr, "No IText '%s' in %s.%s\n",name,tvp->device,tvp->name); 1060 return (NULL); 1061 } 1062 1063 /* find a member of an INumber vector, else NULL */ 1064 INumber * 1065 IUFindNumber(const INumberVectorProperty *nvp, const char *name) 1066 { 1067 int i; 1068 1069 for (i = 0; i < nvp->nnp; i++) 1070 if (strcmp (nvp->np[i].name, name) == 0) 1071 return (&nvp->np[i]); 1072 fprintf(stderr,"No INumber '%s' in %s.%s\n",name,nvp->device,nvp->name); 1073 return (NULL); 1074 } 1075 1076 /* find a member of an ISwitch vector, else NULL */ 1077 ISwitch * 1078 IUFindSwitch(const ISwitchVectorProperty *svp, const char *name) 1079 { 1080 int i; 1081 1082 for (i = 0; i < svp->nsp; i++) 1083 if (strcmp (svp->sp[i].name, name) == 0) 1084 return (&svp->sp[i]); 1085 fprintf(stderr,"No ISwitch '%s' in %s.%s\n",name,svp->device,svp->name); 1086 return (NULL); 1087 } 1088 1089 /* find a member of an ILight vector, else NULL */ 1090 ILight * 1091 IUFindLight(const ILightVectorProperty *lvp, const char *name) 1092 { 1093 int i; 1094 1095 for (i = 0; i < lvp->nlp; i++) 1096 if (strcmp (lvp->lp[i].name, name) == 0) 1097 return (&lvp->lp[i]); 1098 fprintf(stderr,"No ILight '%s' in %s.%s\n",name,lvp->device,lvp->name); 1099 return (NULL); 1100 } 1101 1102 /* find a member of an IBLOB vector, else NULL */ 1103 IBLOB * 1104 IUFindBLOB(const IBLOBVectorProperty *bvp, const char *name) 1105 { 1106 int i; 1107 1108 for (i = 0; i < bvp->nbp; i++) 1109 if (strcmp (bvp->bp[i].name, name) == 0) 1110 return (&bvp->bp[i]); 1111 fprintf(stderr,"No IBLOB '%s' in %s.%s\n",name,bvp->device,bvp->name); 1112 return (NULL); 1113 } 1114 1115 /* find an ON member of an ISwitch vector, else NULL. 1116 * N.B. user must make sense of result with ISRule in mind. 1117 */ 1118 ISwitch * 1119 IUFindOnSwitch(const ISwitchVectorProperty *svp) 1120 { 1121 int i; 1122 1123 for (i = 0; i < svp->nsp; i++) 1124 if (svp->sp[i].s == ISS_ON) 1125 return (&svp->sp[i]); 1126 /*fprintf(stderr, "No ISwitch On in %s.%s\n", svp->device, svp->name);*/ 1127 return (NULL); 1128 } 1129 1130 /* Set all switches to off */ 1131 void 1132 IUResetSwitch(ISwitchVectorProperty *svp) 1133 { 1134 int i; 1135 1136 for (i = 0; i < svp->nsp; i++) 1137 svp->sp[i].s = ISS_OFF; 1138 } 1139 1140 /* save malloced copy of newtext in tp->text, reusing if not first time */ 1141 void 1142 IUSaveText (IText *tp, const char *newtext) 1143 { 1144 /* seed for realloc */ 1145 if (tp->text == NULL) 1146 tp->text = malloc (1); 1147 1148 /* copy in fresh string */ 1149 tp->text = strcpy (realloc (tp->text, strlen(newtext)+1), newtext); 1150 } -
BAORadio/libindi/libindi/libs/indicom.h
r490 r501 48 48 #define ERRMSG_SIZE 1024 49 49 #define INDI_DEBUG 50 51 50 52 51 extern const char * Direction[]; -
BAORadio/libindi/libindi/libs/lilxml.h
r490 r501 248 248 * N.B. s must be at least as large as that reported by sprlXMLEle()+1. 249 249 * N.B. set level = 0 on first call. 250 * \return return length of resulting string (sans trailing \0)250 * \return return length of resulting string (sans trailing @\0@) 251 251 */ 252 252 extern int sprXMLEle (char *s, XMLEle *ep, int level); 253 253 254 /** \brief return number of bytes in a string guaranteed able to hold result of sprXLMEle(ep) (sans trailing \0).254 /** \brief return number of bytes in a string guaranteed able to hold result of sprXLMEle(ep) (sans trailing @\0@). 255 255 * N.B. set level = 0 on first call. 256 256 */
Note: See TracChangeset
for help on using the changeset viewer.