118 |
132 |
119 |
133 |
120 void cmd_server(void) |
134 void cmd_server(void) |
121 { |
135 { |
122 char *inp, *hostname, buf[SS_BUFSIZE], obuf[SS_BUFSIZE]; |
136 char *inp, *hostname, buf[SS_BUFSIZE], obuf[SS_BUFSIZE]; |
123 int i, rc, rlen, timer; |
137 int i, rc, rlen; |
124 socklen_t fromlen; |
138 socklen_t fromlen; |
125 struct pollfd pfd[1]; |
|
126 float newtemp; |
139 float newtemp; |
127 |
|
128 /* |
|
129 * Close listen socket |
|
130 */ |
|
131 close(ls); |
|
132 /* |
|
133 * Install private signal handler. |
|
134 */ |
|
135 for (i = 0; i < NSIG; i++) { |
|
136 if ((i == SIGHUP) || (i == SIGPIPE) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV)) |
|
137 signal(i, (void (*))cmd_die); |
|
138 else |
|
139 signal(i, SIG_IGN); |
|
140 } |
|
141 |
140 |
142 hp = gethostbyaddr ((char *) &peeraddr_in.sin_addr, sizeof(struct in_addr), peeraddr_in.sin_family); |
141 hp = gethostbyaddr ((char *) &peeraddr_in.sin_addr, sizeof(struct in_addr), peeraddr_in.sin_family); |
143 if (hp == NULL) { |
142 if (hp == NULL) { |
144 hostname = inet_ntoa(peeraddr_in.sin_addr); |
143 hostname = inet_ntoa(peeraddr_in.sin_addr); |
145 } else { |
144 } else { |
146 hostname = hp->h_name; |
145 hostname = hp->h_name; |
147 } |
146 } |
148 |
147 |
149 clients++; |
148 if (debug) { |
150 syslog(LOG_NOTICE, "Start new client connection (%d) from %s port %u", clients, hostname, ntohs(peeraddr_in.sin_port)); |
149 syslog(LOG_NOTICE, "Start new client connection from %s port %u", hostname, ntohs(peeraddr_in.sin_port)); |
151 if (debug) |
150 fprintf(stdout, "Start new client connection from %s port %u\n", hostname, ntohs(peeraddr_in.sin_port)); |
152 fprintf(stdout, "Start new client connection (%d) from %s port %u\n", clients, hostname, ntohs(peeraddr_in.sin_port)); |
151 } |
153 timer = SS_TIMEOUT * 4; |
152 |
154 |
153 memset((char *)&buf, 0, SS_BUFSIZE); |
155 /* |
154 fromlen = sizeof(peeraddr_in); |
156 * Receive loop |
155 rlen = recvfrom(s, buf, sizeof(buf) -1, 0, (struct sockaddr *)&peeraddr_in, &fromlen); |
157 */ |
156 if (rlen == -1) { |
158 for (;;) { |
157 syslog(LOG_NOTICE, "recvfrom(): %s", strerror(errno)); |
159 /* |
158 } else { |
160 * Poll socket until a define timeout of 0,25 second. |
159 for (i = 0; i < strlen(buf); i++) { |
161 */ |
160 if (buf[i] == '\n') |
162 pfd[0].fd = s; |
161 buf[i] = '\0'; |
163 pfd[0].events = POLLIN; |
162 if (buf[i] == '\r') |
164 pfd[0].revents = 0; |
163 buf[i] = '\0'; |
165 rc = poll(pfd, 1, 250); |
164 } |
166 |
165 if (strlen(buf)) { |
167 if (rc == -1) { |
166 if (debug) { |
|
167 syslog(LOG_NOTICE, "recv: \"%s\"", buf); |
|
168 fprintf(stdout, "recv: \"%s\"\n", buf); |
|
169 } |
|
170 |
168 /* |
171 /* |
169 * Poll can be interrupted by a finished child so that's not a real error. |
172 * Process commands from the client |
170 */ |
173 */ |
171 if (errno != EINTR) { |
174 if (strncmp(buf, "ack", 3) == 0) { |
172 syslog(LOG_NOTICE, "poll() rc=%d sock=%d events=%04x", rc, s, pfd[0].revents); |
175 srv_send((char *)"ack"); |
173 } |
176 } else if (strncmp(buf, "lcd", 3) == 0) { |
174 } else if (rc) { |
177 sprintf(obuf, "[\" \", \" \", \" \", \" \"]"); |
175 if (pfd[0].revents & POLLIN) { |
178 for (i = 0; i < 20; i++) { |
176 memset((char *)&buf, 0, SS_BUFSIZE); |
179 obuf[i+2] = lcdbuf[lcdHandle][i][0]; |
177 fromlen = sizeof(peeraddr_in); |
180 obuf[i+26] = lcdbuf[lcdHandle][i][1]; |
178 rlen = recvfrom(s, buf, sizeof(buf) -1, 0, (struct sockaddr *)&peeraddr_in, &fromlen); |
181 obuf[i+50] = lcdbuf[lcdHandle][i][2]; |
179 if (rlen == -1) { |
182 obuf[i+74] = lcdbuf[lcdHandle][i][3]; |
180 syslog(LOG_NOTICE, "recvfrom(): %s", strerror(errno)); |
|
181 } else { |
|
182 for (i = 0; i < strlen(buf); i++) { |
|
183 if (buf[i] == '\n') |
|
184 buf[i] = '\0'; |
|
185 if (buf[i] == '\r') |
|
186 buf[i] = '\0'; |
|
187 } |
|
188 timer = SS_TIMEOUT * 4; |
|
189 if (strlen(buf)) { |
|
190 syslog(LOG_NOTICE, "recv: \"%s\"", buf); |
|
191 if (debug) |
|
192 fprintf(stdout, "recv: \"%s\"\n", buf); |
|
193 |
|
194 /* |
|
195 * Process commands from the client |
|
196 */ |
|
197 if (strncmp(buf, "ack", 3) == 0) { |
|
198 srv_send((char *)"ack"); |
|
199 } else if (strncmp(buf, "lcd", 3) == 0) { |
|
200 sprintf(obuf, "[\" \", \" \", \" \", \" \"]"); |
|
201 for (i = 0; i < 20; i++) { |
|
202 obuf[i+2] = lcdbuf[lcdHandle][i][0]; |
|
203 obuf[i+26] = lcdbuf[lcdHandle][i][1]; |
|
204 obuf[i+50] = lcdbuf[lcdHandle][i][2]; |
|
205 obuf[i+74] = lcdbuf[lcdHandle][i][3]; |
|
206 } |
|
207 srv_send(obuf); |
|
208 } else if (strncmp(buf, "getMode", 7) == 0) { |
|
209 srv_send("%c", beer->cs_mode); |
|
210 } else if (strncmp(buf, "getFridge", 9) == 0) { |
|
211 srv_send("%.1f", beer->cs_fridgeSet); |
|
212 } else if (strncmp(buf, "getBeer", 7) == 0) { |
|
213 srv_send("%.1f", beer->cs_beerSet); |
|
214 } else if (strncmp(buf, "getControlConstants", 19) == 0) { |
|
215 srv_send("{ \"tempFormat\":\"%c\", \"tempSetMin\":%.1f, \"tempSetMax\":%.1f, \"idleRangeH\":%.3f, \"idleRangeL\":%.3f }", |
|
216 beer->cc_tempFormat, beer->cc_tempSetMin, beer->cc_tempSetMax, beer->cc_idleRangeH, beer->cc_idleRangeL ); |
|
217 } else if (strncmp(buf, "getControlSettings", 18) == 0) { |
|
218 srv_send("{ \"mode\":\"%c\", \"beerSet\":%.1f, \"fridgeSet\":%.1f, \"heatEstimator\":%.1f, \"coolEstimator\":%.1f }", |
|
219 beer->cs_mode, beer->cs_beerSet, beer->cs_fridgeSet, beer->cs_heatEstimator, beer->cs_coolEstimator); |
|
220 } else if (strncmp(buf, "getControlVariables", 19) == 0) { |
|
221 srv_send("{ \"beerDiff\":%.2f }", beer->cv_beerDiff); |
|
222 } else if (strncmp(buf, "setBeer=", 8) == 0) { |
|
223 inp = xstrcpy(buf+8); |
|
224 rc = sscanf(inp, "%f", &newtemp); |
|
225 if (debug) |
|
226 fprintf(stdout, "new temp from %s, %.1f, rc=%d\n", inp, newtemp, rc); |
|
227 if (rc == 1) { |
|
228 srv_send("ack"); |
|
229 beer->cs_mode = 'b'; |
|
230 beer->cs_beerSet = newtemp; |
|
231 } else { |
|
232 srv_send("err"); |
|
233 } |
|
234 } else if (strncmp(buf, "setFridge=", 10) == 0) { |
|
235 inp = xstrcpy(buf+10); |
|
236 rc = sscanf(inp, "%f", &newtemp); |
|
237 if (debug) |
|
238 fprintf(stdout, "new temp from %s, %.1f, rc=%d\n", inp, newtemp, rc); |
|
239 if (rc == 1) { |
|
240 srv_send("ack"); |
|
241 beer->cs_mode = 'f'; |
|
242 beer->cs_fridgeSet = newtemp; |
|
243 } else { |
|
244 srv_send("err"); |
|
245 } |
|
246 } else { |
|
247 if (debug) |
|
248 fprintf(stdout, "unknown command \"%s\"\n", buf); |
|
249 srv_send((char *)"ERR"); |
|
250 } |
|
251 break; |
|
252 } |
|
253 } |
183 } |
|
184 srv_send(obuf); |
|
185 } else if (strncmp(buf, "getMode", 7) == 0) { |
|
186 srv_send("%c", cs_mode); |
|
187 } else if (strncmp(buf, "getFridge", 9) == 0) { |
|
188 srv_send("%.1f", cs_fridgeSet); |
|
189 } else if (strncmp(buf, "getBeer", 7) == 0) { |
|
190 srv_send("%.1f", cs_beerSet); |
|
191 } else if (strncmp(buf, "getControlConstants", 19) == 0) { |
|
192 srv_send("{ \"tempFormat\":\"%c\", \"tempSetMin\":%.1f, \"tempSetMax\":%.1f, \"idleRangeH\":%.3f, \"idleRangeL\":%.3f }", |
|
193 cc_tempFormat, cc_tempSetMin, cc_tempSetMax, cc_idleRangeH, cc_idleRangeL ); |
|
194 } else if (strncmp(buf, "getControlSettings", 18) == 0) { |
|
195 srv_send("{ \"mode\":\"%c\", \"beerSet\":%.1f, \"fridgeSet\":%.1f, \"heatEstimator\":%.1f, \"coolEstimator\":%.1f }", |
|
196 cs_mode, cs_beerSet, cs_fridgeSet, cs_heatEstimator, cs_coolEstimator); |
|
197 } else if (strncmp(buf, "getControlVariables", 19) == 0) { |
|
198 srv_send("{ \"beerDiff\":%.2f }", cv_beerDiff); |
|
199 } else if (strncmp(buf, "setBeer=", 8) == 0) { |
|
200 inp = xstrcpy(buf+8); |
|
201 rc = sscanf(inp, "%f", &newtemp); |
|
202 if (debug) |
|
203 fprintf(stdout, "new temp from %s, %.1f, rc=%d\n", inp, newtemp, rc); |
|
204 if (rc == 1) { |
|
205 srv_send("ack"); |
|
206 cs_mode = 'b'; |
|
207 cs_beerSet = newtemp; |
|
208 } else { |
|
209 srv_send("err"); |
|
210 } |
|
211 free(inp); |
|
212 } else if (strncmp(buf, "setFridge=", 10) == 0) { |
|
213 inp = xstrcpy(buf+10); |
|
214 rc = sscanf(inp, "%f", &newtemp); |
|
215 if (debug) |
|
216 fprintf(stdout, "new temp from %s, %.1f, rc=%d\n", inp, newtemp, rc); |
|
217 if (rc == 1) { |
|
218 srv_send("ack"); |
|
219 cs_mode = 'f'; |
|
220 cs_fridgeSet = newtemp; |
|
221 } else { |
|
222 srv_send("err"); |
|
223 } |
|
224 free(inp); |
254 } else { |
225 } else { |
255 syslog(LOG_NOTICE, "poll other event"); |
226 if (debug) |
256 } |
227 fprintf(stdout, "unknown command \"%s\"\n", buf); |
257 |
228 srv_send((char *)"ERR"); |
258 } else { |
|
259 /* |
|
260 * Poll timeout, do some housekeeping |
|
261 */ |
|
262 if (timer) { |
|
263 timer--; |
|
264 } else { |
|
265 /* Inactivity timeout */ |
|
266 break; |
|
267 } |
|
268 if (my_shutdown) { |
|
269 break; |
|
270 } |
229 } |
271 } |
230 } |
272 } |
231 } |
273 |
232 |
274 if (clients) |
233 if (debug) { |
275 clients--; |
234 syslog(LOG_NOTICE, "End connection from %s port %u", hostname, ntohs(peeraddr_in.sin_port)); |
276 syslog(LOG_NOTICE, "End connection from %s port %u", hostname, ntohs(peeraddr_in.sin_port)); |
|
277 if (debug) |
|
278 fprintf(stdout, "End connection from %s port %u\n", hostname, ntohs(peeraddr_in.sin_port)); |
235 fprintf(stdout, "End connection from %s port %u\n", hostname, ntohs(peeraddr_in.sin_port)); |
|
236 } |
|
237 |
279 close(s); |
238 close(s); |
280 } |
239 } |
281 |
240 |
282 |
241 |
283 |
242 |