1 /*
2 OWFS -- One-Wire filesystem
3 OWHTTPD -- One-Wire Web Server
4 Written 2003 Paul H Alfille
5 email: paul.alfille@gmail.com
6 Released under the GPL
7 See the header file: ow.h for full attribution
8 1wire/iButton system from Dallas Semiconductor
9 */
10
11 #include <config.h>
12 #include "owfs_config.h"
13 #include "ow.h"
14 #include "ow_devices.h"
15 #include "ow_pid.h"
16
17 static void IgnoreSignals(void);
18 static void SetupTemperatureLimits( void );
19 static void SetupInboundConnections(void);
20 static GOOD_OR_BAD SetupSingleInboundConnection( struct port_in * pin ) ;
21
22 /* Start the owlib process -- already in background */
LibStart(void * v)23 GOOD_OR_BAD LibStart(void* v)
24 {
25 /* Start configuration monitoring */
26 Config_Monitor_Watch(v) ;
27
28 /* Build device and filetype arrays (including externals) */
29 DeviceSort();
30
31 Globals.zero = zero_none ;
32 #if OW_ZERO
33 if ( OW_Load_dnssd_library() == 0 ) {
34 Globals.zero = zero_bonjour ;
35 }
36 #endif /* OW_ZERO */
37
38 /* Initialize random number generator, make sure fake devices get the same
39 * id each time */
40 srand(1);
41
42 SetupTemperatureLimits() ;
43
44 MONITOR_WLOCK ;
45 SetupInboundConnections();
46 MONITOR_WUNLOCK ;
47
48 // Signal handlers
49 IgnoreSignals();
50
51 if ( Inbound_Control.head_port == NULL ) {
52 LEVEL_DEFAULT("No valid 1-wire buses found");
53 return gbBAD ;
54 }
55 return gbGOOD ;
56 }
57
58 // only changes FAKE and MOCK temp limits
59 // do it here after options are parsed to allow correction forr temperature scale
SetupTemperatureLimits(void)60 static void SetupTemperatureLimits( void )
61 {
62 struct parsedname pn;
63
64 FS_ParsedName_Placeholder(&pn); // minimal parsename -- no destroy needed
65
66 if ( Globals.templow < GLOBAL_UNTOUCHED_TEMP_LIMIT + 1 ) {
67 Globals.templow = 0. ; // freezing point
68 } else {
69 Globals.templow = fromTemperature(Globals.templow,&pn) ; // internal scale
70 }
71
72 if ( Globals.temphigh < GLOBAL_UNTOUCHED_TEMP_LIMIT + 1 ) {
73 Globals.temphigh = 100. ; // boiling point
74 } else {
75 Globals.temphigh = fromTemperature(Globals.temphigh,&pn) ; // internal scale
76 }
77 LEVEL_DEBUG("Global temp limit %gC to %gC (for fake and mock adapters)",Globals.templow,Globals.temphigh);
78 }
79
SetupInboundConnections(void)80 static void SetupInboundConnections(void)
81 {
82 struct port_in *pin = Inbound_Control.head_port;
83
84 // cycle through connections analyzing them
85 while (pin != NULL) {
86 struct port_in * next = pin->next ; // read before potential delete
87 if ( BAD( SetupSingleInboundConnection(pin) ) ) {
88 RemovePort( pin ) ;
89 }
90 pin = next ;
91 }
92 }
93
SetupSingleInboundConnection(struct port_in * pin)94 static GOOD_OR_BAD SetupSingleInboundConnection( struct port_in * pin )
95 {
96 struct connection_in * in = pin->first ;
97 switch (pin->busmode) {
98
99 case bus_zero:
100 if ( BAD( Zero_detect(pin) )) {
101 LEVEL_CONNECT("Cannot open server at %s", DEVICENAME(in));
102 return gbBAD ;
103 }
104 break;
105
106 case bus_server:
107 if (BAD( Server_detect(pin)) ) {
108 LEVEL_CONNECT("Cannot open server at %s -- first attempt.", DEVICENAME(in));
109 sleep(5); // delay to allow owserver to open it's listen socket
110 if ( GOOD( Server_detect(pin)) ) {
111 break ;
112 }
113 LEVEL_CONNECT("Cannot open server at %s -- second (and final) attempt.", DEVICENAME(in));
114 return gbBAD ;
115 }
116 break;
117
118 case bus_serial:
119 /* Set up DS2480/LINK interface */
120 if ( BAD( DS2480_detect(pin) )) {
121 LEVEL_CONNECT("Cannot detect DS2480 or LINK interface on %s.", DEVICENAME(in));
122 } else {
123 return gbGOOD ;
124 }
125 // Fall Through
126 in->adapter_name = "DS9097"; // need to set adapter name for this approach to passive adapter
127 __attribute__ ((fallthrough));
128 case bus_passive:
129 if ( BAD( DS9097_detect(pin) )) {
130 LEVEL_DEFAULT("Cannot detect DS9097 (passive) interface on %s.", DEVICENAME(in));
131 return gbBAD ;
132 }
133 break;
134
135 case bus_xport:
136 if ( BAD( DS2480_detect(pin) )) {
137 LEVEL_DEFAULT("Cannot detect DS2480B via telnet interface on %s.", DEVICENAME(in));
138 return gbBAD ;
139 }
140 break;
141
142 case bus_i2c:
143 #if OW_I2C
144 if ( BAD( DS2482_detect(pin) )) {
145 LEVEL_CONNECT("Cannot detect an i2c DS2482-x00 on %s", DEVICENAME(in));
146 return gbBAD ;
147 }
148 #endif /* OW_I2C */
149 break;
150
151 case bus_ha7net:
152 if ( BAD( HA7_detect(pin) )) {
153 LEVEL_CONNECT("Cannot detect an HA7net server on %s", DEVICENAME(in));
154 return gbBAD ;
155 }
156 break;
157
158 case bus_enet:
159 if ( BAD( OWServer_Enet_detect(pin) )) {
160 LEVEL_CONNECT("Cannot detect an OWServer_Enet on %s", DEVICENAME(in));
161 return gbBAD ;
162 }
163 break;
164
165 case bus_ha5:
166 if ( BAD( HA5_detect(pin) )) {
167 LEVEL_CONNECT("Cannot detect an HA5 on %s", DEVICENAME(in));
168 return gbBAD ;
169 }
170 break;
171
172 case bus_ha7e:
173 if ( BAD( HA7E_detect(pin) )) {
174 LEVEL_CONNECT("Cannot detect an HA7E/HA7S on %s", DEVICENAME(in));
175 return gbBAD ;
176 }
177 break;
178
179 case bus_ds1wm:
180 if ( BAD( DS1WM_detect(pin) )) {
181 LEVEL_CONNECT("Cannot detect an DS1WM synthesized bus master at %s", DEVICENAME(in));
182 return gbBAD ;
183 }
184 break;
185
186 case bus_k1wm:
187 if ( BAD( K1WM_detect(pin) )) {
188 LEVEL_CONNECT("Cannot detect an K1WM synthesized bus master at %s", DEVICENAME(in));
189 return gbBAD ;
190 }
191 break;
192
193 case bus_parallel:
194 #if OW_PARPORT
195 if ( BAD( DS1410_detect(pin) )) {
196 LEVEL_DEFAULT("Cannot detect the DS1410E parallel bus master");
197 return gbBAD ;
198 }
199 #endif /* OW_PARPORT */
200 break;
201
202 case bus_usb:
203 #if OW_USB
204 /* in->master.usb.ds1420_address should be set to identify the
205 * adapter just in case it's disconnected. It's done in the
206 * DS9490_next_both() if not set. */
207 if ( BAD( DS9490_detect(pin) )) {
208 LEVEL_DEFAULT("Cannot open USB bus master");
209 return gbBAD ;
210 }
211 #endif /* OW_USB */
212 break;
213
214 case bus_link:
215 if ( BAD( LINK_detect(pin) )) {
216 LEVEL_CONNECT("Cannot open LINK bus master at %s", DEVICENAME(in));
217 return gbBAD ;
218 }
219 break;
220
221 case bus_masterhub:
222 if ( BAD( MasterHub_detect(pin) )) {
223 LEVEL_CONNECT("Cannot open Hobby Boards MasterHub bus master at %s", DEVICENAME(in));
224 return gbBAD ;
225 }
226 break;
227
228 case bus_pbm:
229 if ( BAD( PBM_detect(pin) )) {
230 LEVEL_CONNECT("Cannot open PBM bus master at %s", DEVICENAME(in));
231 return gbBAD ;
232 }
233 break;
234
235 case bus_etherweather:
236 if ( BAD( EtherWeather_detect(pin) )) {
237 LEVEL_CONNECT("Cannot detect an EtherWeather server on %s", DEVICENAME(in));
238 return gbBAD ;
239 }
240 break;
241
242 case bus_browse:
243 RETURN_BAD_IF_BAD( Browse_detect(pin) ) ;
244 break;
245
246 case bus_fake:
247 Fake_detect(pin); // never fails
248 break;
249
250 case bus_tester:
251 Tester_detect(pin); // never fails
252 break;
253
254 case bus_mock:
255 Mock_detect(pin); // never fails
256 break;
257
258 case bus_w1_monitor:
259 RETURN_BAD_IF_BAD( W1_monitor_detect(pin) ) ;
260 break;
261
262 case bus_usb_monitor:
263 #if OW_USB
264 RETURN_BAD_IF_BAD( USB_monitor_detect(pin) ) ;
265 #endif /* OW_USB */
266 break;
267
268 case bus_w1:
269 /* w1 is different: it is a dynamic list of adapters */
270 /* the scanning starts with "W1_Browse" in LibStart and continues in it's own thread */
271 /* No connection_in entries should have been created for w1 yet */
272 break ;
273
274 case bus_external:
275 RETURN_BAD_IF_BAD( External_detect(pin) ) ;
276 break;
277
278 case bus_bad:
279 default:
280 return gbBAD ;
281 break;
282 }
283 return gbGOOD ;
284 }
285
IgnoreSignals(void)286 static void IgnoreSignals(void)
287 {
288 struct sigaction sa;
289
290 memset(&sa, 0, sizeof(struct sigaction));
291 sigemptyset(&(sa.sa_mask));
292
293 sa.sa_flags = 0;
294 sa.sa_handler = SIG_IGN;
295 if (sigaction(SIGPIPE, &sa, NULL) == -1) {
296 LEVEL_DEFAULT("Cannot ignore SIGPIPE");
297 exit(0);
298 }
299 }
300
301