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